EAC: Clearify naming of functions and data

Use names that are specific to EAC, not the German ID card (nPA),
because Protocol and Commands are defined by BSI TR-03110 and ICAO.
Functions that are nPA specific are moved to card-npa.h.
This commit is contained in:
Frank Morgner 2018-01-25 23:30:51 +01:00
parent 6843ab4190
commit f862060614
9 changed files with 447 additions and 442 deletions

View File

@ -1,7 +1,7 @@
/*
* card-npa.c: Recognize known German identity cards
*
* Copyright (C) 2011-2015 Frank Morgner <frankmorgner@gmail.com>
* Copyright (C) 2011-2018 Frank Morgner <frankmorgner@gmail.com>
*
* This file is part of OpenSC.
*
@ -291,9 +291,9 @@ static int npa_unlock_esign(sc_card_t *card)
}
/* FIXME set flags with opensc.conf */
npa_default_flags |= NPA_FLAG_DISABLE_CHECK_ALL;
npa_default_flags |= NPA_FLAG_DISABLE_CHECK_TA;
npa_default_flags |= NPA_FLAG_DISABLE_CHECK_CA;
eac_default_flags |= EAC_FLAG_DISABLE_CHECK_ALL;
eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA;
eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA;
/* FIXME show an alert to the user if can == NULL */
r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02);
@ -451,7 +451,7 @@ static int npa_pin_cmd_get_info(struct sc_card *card,
/* usually 10 tries */
*tries_left = 10;
data->pin1.max_tries = 10;
r = npa_pace_get_tries_left(card,
r = eac_pace_get_tries_left(card,
pin_reference, tries_left);
data->pin1.tries_left = *tries_left;
break;
@ -460,7 +460,7 @@ static int npa_pin_cmd_get_info(struct sc_card *card,
/* usually 3 tries */
*tries_left = 3;
data->pin1.max_tries = 3;
r = npa_pace_get_tries_left(card,
r = eac_pace_get_tries_left(card,
pin_reference, tries_left);
data->pin1.tries_left = *tries_left;
break;
@ -511,10 +511,10 @@ static int npa_pace_verify(struct sc_card *card,
&& r != SC_SUCCESS
&& pace_output.mse_set_at_sw1 == 0x63
&& (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0
&& (pace_output.mse_set_at_sw2 & 0x0f) <= UC_PIN_SUSPENDED) {
&& (pace_output.mse_set_at_sw2 & 0x0f) <= EAC_UC_PIN_SUSPENDED) {
/* TODO ask for user consent when automatically resuming the PIN */
sc_log(card->ctx, "%s is suspended. Will try to resume it with %s.\n",
npa_secret_name(pin_reference), npa_secret_name(PACE_PIN_ID_CAN));
eac_secret_name(pin_reference), eac_secret_name(PACE_PIN_ID_CAN));
pace_input.pin_id = PACE_PIN_ID_CAN;
pace_input.pin = NULL;
@ -532,9 +532,9 @@ static int npa_pace_verify(struct sc_card *card,
r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02);
if (r == SC_SUCCESS) {
sc_log(card->ctx, "%s resumed.\n", npa_secret_name(pin_reference));
sc_log(card->ctx, "%s resumed.\n", eac_secret_name(pin_reference));
if (tries_left) {
*tries_left = MAX_PIN_TRIES;
*tries_left = EAC_MAX_PIN_TRIES;
}
} else {
if (tries_left) {
@ -552,10 +552,10 @@ static int npa_pace_verify(struct sc_card *card,
if (pin_reference == PACE_PIN_ID_PIN && tries_left) {
if (*tries_left == 0) {
sc_log(card->ctx, "%s is suspended and must be resumed.\n",
npa_secret_name(pin_reference));
eac_secret_name(pin_reference));
} else if (*tries_left == 1) {
sc_log(card->ctx, "%s is blocked and must be unblocked.\n",
npa_secret_name(pin_reference));
eac_secret_name(pin_reference));
}
}
@ -586,6 +586,75 @@ static int npa_standard_pin_cmd(struct sc_card *card,
return r;
}
int
npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id,
int ask_for_secret, const char *new, size_t new_len)
{
sc_apdu_t apdu;
char *p = NULL;
int r;
if (ask_for_secret && (!new || !new_len)) {
if (!(SC_READER_CAP_PIN_PAD & card->reader->capabilities)) {
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
p = malloc(EAC_MAX_PIN_LEN+1);
if (!p) {
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,
EAC_MIN_PIN_LEN, EAC_MAX_PIN_LEN+1,
"Please enter your new PIN: ", 0)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n");
free(p);
return SC_ERROR_INTERNAL;
}
new_len = strlen(p);
if (new_len > EAC_MAX_PIN_LEN)
return SC_ERROR_INVALID_PIN_LENGTH;
new = p;
#else
return SC_ERROR_NOT_SUPPORTED;
#endif
}
}
sc_format_apdu(card, &apdu, 0, 0x2C, 0, pin_id);
apdu.data = (u8 *) new;
apdu.datalen = new_len;
apdu.lc = apdu.datalen;
if (new_len || ask_for_secret) {
apdu.p1 = 0x02;
apdu.cse = SC_APDU_CASE_3_SHORT;
} else {
apdu.p1 = 0x03;
apdu.cse = SC_APDU_CASE_1;
}
if (ask_for_secret && !new_len) {
struct sc_pin_cmd_data data;
data.apdu = &apdu;
data.cmd = SC_PIN_CMD_CHANGE;
data.flags = SC_PIN_CMD_IMPLICIT_CHANGE;
data.pin2.encoding = SC_PIN_ENCODING_ASCII;
data.pin2.length_offset = 0;
data.pin2.offset = 5;
data.pin2.max_length = EAC_MAX_PIN_LEN;
data.pin2.min_length = EAC_MIN_PIN_LEN;
data.pin2.pad_length = 0;
r = card->reader->ops->perform_verify(card->reader, &data);
} else
r = sc_transmit_apdu(card, &apdu);
if (p) {
sc_mem_clear(p, new_len);
free(p);
}
return r;
}
static int npa_pin_cmd(struct sc_card *card,
struct sc_pin_cmd_data *data, int *tries_left)
{

View File

@ -25,6 +25,8 @@
extern "C" {
#endif
#include "sm/sm-eac.h"
const unsigned char esign_chat[] = {
0x7F, 0x4C, 0x0E,
0x06, 0x09, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x03, 0x01, 0x02, 0x03,
@ -33,6 +35,43 @@ const unsigned char esign_chat[] = {
const unsigned char df_esign_aid[] = { 0xa0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4e};
/**
* @brief Sends a reset retry counter APDU
*
* According to TR-03110 the reset retry counter APDU is used to set a new PIN
* or to reset the retry counter of the PIN. The standard requires this
* operation to be authorized either by an established PACE channel or by the
* effective authorization of the terminal's certificate.
*
* @param[in] card
* @param[in] pin_id Type of secret (usually PIN or CAN). You may use <tt>enum s_type</tt> from \c <openssl/pace.h>.
* @param[in] ask_for_secret whether to ask the user for the secret (\c 1) or not (\c 0)
* @param[in] new (optional) new secret
* @param[in] new_len (optional) length of \a new
*
* @return \c SC_SUCCESS or error code if an error occurred
*/
int npa_reset_retry_counter(sc_card_t *card,
enum s_type pin_id, int ask_for_secret,
const char *new, size_t new_len);
/**
* @brief Send APDU to unblock the PIN
*
* @param[in] card
*/
#define npa_unblock_pin(card) \
npa_reset_retry_counter(card, PACE_PIN, 0, NULL, 0)
/**
* @brief Send APDU to set a new PIN
*
* @param[in] card
* @param[in] newp (optional) new PIN
* @param[in] newplen (optional) length of \a new
*/
#define npa_change_pin(card, newp, newplen) \
npa_reset_retry_counter(card, PACE_PIN, 1, newp, newplen)
#ifdef __cplusplus
}
#endif

View File

@ -350,14 +350,14 @@ _sc_card_add_ec_alg
_sc_card_add_rsa_alg
_sc_match_atr
_sc_log
npa_secret_name
eac_secret_name
get_pace_capabilities
perform_pace
perform_terminal_authentication
perform_chip_authentication
npa_default_flags
eac_default_flags
eac_pace_get_tries_left
npa_reset_retry_counter
npa_pace_get_tries_left
escape_pace_input_to_buf
escape_buf_to_pace_input
escape_pace_output_to_buf

View File

@ -1,7 +1,7 @@
/*
* reader-escape.c: implementation related to escape commands with pseudo APDUs
*
* Copyright (C) 2013-2015 Frank Morgner
* Copyright (C) 2013-2018 Frank Morgner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -43,20 +43,31 @@
#include <endian.h>
#endif
static const u8 escape_cla = 0xff;
static const u8 escape_ins = 0x9a;
int get_pace_capabilities(u8 *bitmap)
{
if (!bitmap)
return SC_ERROR_INVALID_ARGUMENTS;
static const u8 escape_p1_PIN = 0x04;
static const u8 escape_p2_GetReaderPACECapabilities = 0x01;
static const u8 escape_p2_EstablishPACEChannel = 0x02;
/*static const u8 escape_p2_DestroyPACEChannel = 0x03;*/
static const u8 escape_p2_PC_to_RDR_Secure = 0x10;
/* BitMap */
*bitmap = EAC_BITMAP_PACE|EAC_BITMAP_EID|EAC_BITMAP_ESIGN;
static const u8 escape_p1_IFD = 0x01;
static const u8 escape_p2_vendor = 0x01;
/*static const u8 escape_p2_product = 0x03;*/
static const u8 escape_p2_version_firmware = 0x06;
/*static const u8 escape_p2_version_driver = 0x07;*/
return SC_SUCCESS;
}
const u8 escape_cla = 0xff;
const u8 escape_ins = 0x9a;
const u8 escape_p1_PIN = 0x04;
const u8 escape_p2_GetReaderPACECapabilities = 0x01;
const u8 escape_p2_EstablishPACEChannel = 0x02;
/*const u8 escape_p2_DestroyPACEChannel = 0x03;*/
const u8 escape_p2_PC_to_RDR_Secure = 0x10;
const u8 escape_p1_IFD = 0x01;
const u8 escape_p2_vendor = 0x01;
/*const u8 escape_p2_product = 0x03;*/
const u8 escape_p2_version_firmware = 0x06;
/*const u8 escape_p2_version_driver = 0x07;*/
struct sc_asn1_entry g_boolean[] = {
{ "boolean",
@ -79,7 +90,7 @@ struct sc_asn1_entry g_numeric_string_as_octet_string[] = {
{ NULL , 0 , 0 , 0 , NULL , NULL }
};
static const struct sc_asn1_entry g_EstablishPACEChannelInput_data[] = {
const struct sc_asn1_entry g_EstablishPACEChannelInput_data[] = {
{ "passwordID",
/* use an OCTET STRING to avoid a conversion to int */
SC_ASN1_STRUCT, SC_ASN1_CTX|0x01|SC_ASN1_CONS, 0, NULL, NULL },
@ -94,7 +105,7 @@ static const struct sc_asn1_entry g_EstablishPACEChannelInput_data[] = {
SC_ASN1_STRUCT, SC_ASN1_CTX|0x05|SC_ASN1_CONS, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL },
{ NULL , 0 , 0 , 0 , NULL , NULL }
};
static const struct sc_asn1_entry g_EstablishPACEChannelOutput_data[] = {
const struct sc_asn1_entry g_EstablishPACEChannelOutput_data[] = {
{ "errorCode",
SC_ASN1_STRUCT, SC_ASN1_CTX|0x01|SC_ASN1_CONS, 0, NULL, NULL },
{ "statusMSESetAT",
@ -109,7 +120,7 @@ static const struct sc_asn1_entry g_EstablishPACEChannelOutput_data[] = {
SC_ASN1_STRUCT, SC_ASN1_CTX|0x06|SC_ASN1_CONS, SC_ASN1_OPTIONAL|SC_ASN1_ALLOC, NULL, NULL },
{ NULL , 0 , 0 , 0 , NULL , NULL }
};
static const struct sc_asn1_entry g_EstablishPACEChannel[] = {
const struct sc_asn1_entry g_EstablishPACEChannel[] = {
{ "EstablishPACEChannel",
SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE|SC_ASN1_CONS, 0, NULL, NULL },
{ NULL , 0 , 0 , 0 , NULL , NULL }

View File

@ -1,7 +1,7 @@
/*
* reader-tr03119.h: interface related to escape commands with pseudo APDUs
*
* Copyright (C) 2013-2015 Frank Morgner
* Copyright (C) 2013-2018 Frank Morgner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -28,6 +28,60 @@
extern "C" {
#endif
/** @brief NPA capabilities (TR-03119): PACE */
#define EAC_BITMAP_PACE 0x40
/** @brief NPA capabilities (TR-03119): EPA: eID */
#define EAC_BITMAP_EID 0x20
/** @brief NPA capabilities (TR-03119): EPA: eSign */
#define EAC_BITMAP_ESIGN 0x10
/**
* @brief Get the PACE capabilities
*
* @param[in,out] bitmap where to store capabilities bitmap
* @note Since this code offers no support for terminal certificate, the bitmap is always \c PACE_BITMAP_PACE|PACE_BITMAP_EID
*
* @return \c SC_SUCCESS or error code if an error occurred
*/
int get_pace_capabilities(u8 *bitmap);
/** @brief NPA result (TR-03119): Kein Fehler */
#define EAC_SUCCESS 0x00000000
/** @brief NPA result (TR-03119): Längen im Input sind inkonsistent */
#define EAC_ERROR_LENGTH_INCONSISTENT 0xD0000001
/** @brief NPA result (TR-03119): Unerwartete Daten im Input */
#define EAC_ERROR_UNEXPECTED_DATA 0xD0000002
/** @brief NPA result (TR-03119): Unerwartete Kombination von Daten im Input */
#define EAC_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003
/** @brief NPA result (TR-03119): Die Karte unterstützt das PACE Verfahren nicht. (Unerwartete Struktur in Antwortdaten der Karte) */
#define EAC_ERROR_CARD_NOT_SUPPORTED 0xE0000001
/** @brief NPA result (TR-03119): Der Kartenleser unterstützt den angeforderten bzw. den ermittelten Algorithmus nicht. */
#define EAC_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002
/** @brief NPA result (TR-03119): Der Kartenleser kennt die PIN ID nicht. */
#define EAC_ERROR_PINID_NOT_SUPPORTED 0xE0000003
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Select EF_CardAccess (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_SELECT_EF_CARDACCESS 0xF0000000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Read Binary (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_READ_BINARY 0xF0010000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf MSE: Set AT (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_MSE_SET_AT 0xF0020000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 1 (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 2 (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 3 (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 4 (needs to be OR-ed with SW1|SW2) */
#define EAC_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000
/** @brief NPA result (TR-03119): Kommunikationsabbruch mit Karte. */
#define EAC_ERROR_COMMUNICATION 0xF0100001
/** @brief NPA result (TR-03119): Keine Karte im Feld. */
#define EAC_ERROR_NO_CARD 0xF0100002
/** @brief NPA result (TR-03119): Benutzerabbruch. */
#define EAC_ERROR_ABORTED 0xF0200001
/** @brief NPA result (TR-03119): Benutzer Timeout */
#define EAC_ERROR_TIMEOUT 0xF0200002
void sc_detect_escape_cmds(sc_reader_t *reader);
int escape_pace_input_to_buf(sc_context_t *ctx,

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@
*/
/**
* @file
* @defgroup npa Interface to German identity card (neuer Personalausweis, nPA)
* @defgroup eac Interface to Extended Access Control
* @{
*/
#ifndef _SC_EAC_H
@ -38,10 +38,6 @@ extern "C" {
#include <eac/eac.h>
#include <eac/pace.h>
/** @brief ASN.1 type for authenticated auxiliary data for terminal authentication */
typedef STACK_OF(CVC_DISCRETIONARY_DATA_TEMPLATE) ASN1_AUXILIARY_DATA;
DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA)
#else
/** @brief Type of the secret */
enum s_type {
@ -80,50 +76,6 @@ enum eac_tr_version {
};
#endif
/** @brief NPA capabilities (TR-03119): PACE */
#define NPA_BITMAP_PACE 0x40
/** @brief NPA capabilities (TR-03119): EPA: eID */
#define NPA_BITMAP_EID 0x20
/** @brief NPA capabilities (TR-03119): EPA: eSign */
#define NPA_BITMAP_ESIGN 0x10
/** @brief NPA result (TR-03119): Kein Fehler */
#define NPA_SUCCESS 0x00000000
/** @brief NPA result (TR-03119): Längen im Input sind inkonsistent */
#define NPA_ERROR_LENGTH_INCONSISTENT 0xD0000001
/** @brief NPA result (TR-03119): Unerwartete Daten im Input */
#define NPA_ERROR_UNEXPECTED_DATA 0xD0000002
/** @brief NPA result (TR-03119): Unerwartete Kombination von Daten im Input */
#define NPA_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003
/** @brief NPA result (TR-03119): Die Karte unterstützt das PACE Verfahren nicht. (Unerwartete Struktur in Antwortdaten der Karte) */
#define NPA_ERROR_CARD_NOT_SUPPORTED 0xE0000001
/** @brief NPA result (TR-03119): Der Kartenleser unterstützt den angeforderten bzw. den ermittelten Algorithmus nicht. */
#define NPA_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002
/** @brief NPA result (TR-03119): Der Kartenleser kennt die PIN ID nicht. */
#define NPA_ERROR_PINID_NOT_SUPPORTED 0xE0000003
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Select EF_CardAccess (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_SELECT_EF_CARDACCESS 0xF0000000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf Read Binary (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_READ_BINARY 0xF0010000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf MSE: Set AT (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_MSE_SET_AT 0xF0020000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 1 (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 2 (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 3 (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000
/** @brief NPA result (TR-03119): Negative Antwort der Karte auf General Authenticate Step 4 (needs to be OR-ed with SW1|SW2) */
#define NPA_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000
/** @brief NPA result (TR-03119): Kommunikationsabbruch mit Karte. */
#define NPA_ERROR_COMMUNICATION 0xF0100001
/** @brief NPA result (TR-03119): Keine Karte im Feld. */
#define NPA_ERROR_NO_CARD 0xF0100002
/** @brief NPA result (TR-03119): Benutzerabbruch. */
#define NPA_ERROR_ABORTED 0xF0200001
/** @brief NPA result (TR-03119): Benutzer Timeout */
#define NPA_ERROR_TIMEOUT 0xF0200002
/** @brief File identifier of EF.CardAccess */
#define FID_EF_CARDACCESS 0x011C
/** @brief Short file identifier of EF.CardAccess */
@ -134,17 +86,17 @@ enum eac_tr_version {
#define SFID_EF_CARDSECURITY 0x1D
/** @brief Maximum length of PIN */
#define MAX_PIN_LEN 6
#define EAC_MAX_PIN_LEN 6
/** @brief Minimum length of PIN */
#define MIN_PIN_LEN 6
#define EAC_MIN_PIN_LEN 6
/** @brief Length of CAN */
#define CAN_LEN 6
#define EAC_CAN_LEN 6
/** @brief Minimum length of MRZ */
#define MAX_MRZ_LEN 128
#define EAC_MAX_MRZ_LEN 128
/** @brief Number of retries for PIN */
#define MAX_PIN_TRIES 3
#define EAC_MAX_PIN_TRIES 3
/** @brief Usage counter of PIN in suspended state */
#define UC_PIN_SUSPENDED 1
#define EAC_UC_PIN_SUSPENDED 1
/**
@ -154,18 +106,7 @@ enum eac_tr_version {
*
* @return Printable string containing the name
*/
const char *npa_secret_name(enum s_type pin_id);
/**
* @brief Get the PACE capabilities
*
* @param[in,out] bitmap where to store capabilities bitmap
* @note Since this code offers no support for terminal certificate, the bitmap is always \c PACE_BITMAP_PACE|PACE_BITMAP_EID
*
* @return \c SC_SUCCESS or error code if an error occurred
*/
int get_pace_capabilities(u8 *bitmap);
const char *eac_secret_name(enum s_type pin_id);
/**
* @brief Establish secure messaging using PACE
@ -217,6 +158,10 @@ int perform_terminal_authentication(sc_card_t *card,
const unsigned char *privkey, size_t privkey_len,
const unsigned char *auxiliary_data, size_t auxiliary_data_len);
/** @brief ASN.1 type for authenticated auxiliary data for terminal authentication */
typedef STACK_OF(CVC_DISCRETIONARY_DATA_TEMPLATE) ASN1_AUXILIARY_DATA;
DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA)
/**
* @brief Establish secure messaging using Chip Authentication version 2
*
@ -233,25 +178,8 @@ int perform_chip_authentication(sc_card_t *card,
int perform_chip_authentication_ex(sc_card_t *card, void *eacsmctx,
unsigned char *picc_pubkey, size_t picc_pubkey_len);
/**
* @brief Sends a reset retry counter APDU
*
* According to TR-03110 the reset retry counter APDU is used to set a new PIN
* or to reset the retry counter of the PIN. The standard requires this
* operation to be authorized either by an established PACE channel or by the
* effective authorization of the terminal's certificate.
*
* @param[in] card
* @param[in] pin_id Type of secret (usually PIN or CAN). You may use <tt>enum s_type</tt> from \c <openssl/pace.h>.
* @param[in] ask_for_secret whether to ask the user for the secret (\c 1) or not (\c 0)
* @param[in] new (optional) new secret
* @param[in] new_len (optional) length of \a new
*
* @return \c SC_SUCCESS or error code if an error occurred
*/
int npa_reset_retry_counter(sc_card_t *card,
enum s_type pin_id, int ask_for_secret,
const char *new, size_t new_len);
/** @brief Disable all sanity checks done by OpenSC */
#define EAC_FLAG_DISABLE_CHECK_ALL 1
/**
* @brief Sends an MSE:Set AT to determine the number of remaining tries
@ -262,34 +190,16 @@ int npa_reset_retry_counter(sc_card_t *card,
*
* @return \c SC_SUCCESS or error code if an error occurred
*/
int npa_pace_get_tries_left(sc_card_t *card,
int eac_pace_get_tries_left(sc_card_t *card,
enum s_type pin_id, int *tries_left);
/**
* @brief Send APDU to unblock the PIN
*
* @param[in] card
*/
#define npa_unblock_pin(card) \
npa_reset_retry_counter(card, PACE_PIN, 0, NULL, 0)
/**
* @brief Send APDU to set a new PIN
*
* @param[in] card
* @param[in] newp (optional) new PIN
* @param[in] newplen (optional) length of \a new
*/
#define npa_change_pin(card, newp, newplen) \
npa_reset_retry_counter(card, PACE_PIN, 1, newp, newplen)
/** @brief Disable all sanity checks done by libnpa */
#define NPA_FLAG_DISABLE_CHECK_ALL 1
/** @brief Disable checking validity period of CV certificates */
#define NPA_FLAG_DISABLE_CHECK_TA 2
#define EAC_FLAG_DISABLE_CHECK_TA 2
/** @brief Disable checking passive authentication during CA */
#define NPA_FLAG_DISABLE_CHECK_CA 4
#define EAC_FLAG_DISABLE_CHECK_CA 4
/** @brief Use \c npa_default_flags to disable checks for EAC/SM */
extern char npa_default_flags;
/** @brief Use \c eac_default_flags to disable checks for EAC/SM */
extern char eac_default_flags;
#ifdef __cplusplus
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2012 Frank Morgner <frankmorgner@gmail.com>
* Copyright (C) 2010-2018 Frank Morgner <frankmorgner@gmail.com>
*
* This file is part of OpenSC.
*
@ -30,6 +30,7 @@
#include <libopensc/log.h>
#include <libopensc/opensc.h>
#include <libopensc/sm.h>
#include <libopensc/card-npa.h>
#include <sm/sm-eac.h>
#include <stdint.h>
#include <stdio.h>
@ -419,11 +420,11 @@ main (int argc, char **argv)
if (cmdline.tr_03110v201_flag)
tr_version = EAC_TR_VERSION_2_01;
if (cmdline.disable_all_checks_flag)
npa_default_flags |= NPA_FLAG_DISABLE_CHECK_ALL;
eac_default_flags |= EAC_FLAG_DISABLE_CHECK_ALL;
if (cmdline.disable_ta_checks_flag)
npa_default_flags |= NPA_FLAG_DISABLE_CHECK_TA;
eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA;
if (cmdline.disable_ca_checks_flag)
npa_default_flags |= NPA_FLAG_DISABLE_CHECK_CA;
eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA;
r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader);
@ -457,12 +458,12 @@ main (int argc, char **argv)
if (pin) {
if (sscanf(pin, "%llu", &secret) != 1) {
fprintf(stderr, "%s is not an unsigned long long.\n",
npa_secret_name(pace_input.pin_id));
eac_secret_name(pace_input.pin_id));
exit(2);
}
if (strlen(pin) > pace_input.pin_length) {
fprintf(stderr, "%s too big, only %u digits allowed.\n",
npa_secret_name(pace_input.pin_id),
eac_secret_name(pace_input.pin_id),
(unsigned int) pace_input.pin_length);
exit(2);
}
@ -474,12 +475,12 @@ main (int argc, char **argv)
if (can) {
if (sscanf(can, "%llu", &secret) != 1) {
fprintf(stderr, "%s is not an unsigned long long.\n",
npa_secret_name(pace_input.pin_id));
eac_secret_name(pace_input.pin_id));
exit(2);
}
if (strlen(can) > pace_input.pin_length) {
fprintf(stderr, "%s too big, only %u digits allowed.\n",
npa_secret_name(pace_input.pin_id),
eac_secret_name(pace_input.pin_id),
(unsigned int) pace_input.pin_length);
exit(2);
}
@ -491,12 +492,12 @@ main (int argc, char **argv)
if (puk) {
if (sscanf(puk, "%llu", &secret) != 1) {
fprintf(stderr, "%s is not an unsigned long long.\n",
npa_secret_name(pace_input.pin_id));
eac_secret_name(pace_input.pin_id));
exit(2);
}
if (strlen(puk) > pace_input.pin_length) {
fprintf(stderr, "%s too big, only %u digits allowed.\n",
npa_secret_name(pace_input.pin_id),
eac_secret_name(pace_input.pin_id),
(unsigned int) pace_input.pin_length);
exit(2);
}
@ -515,7 +516,7 @@ main (int argc, char **argv)
gettimeofday(&tv, NULL);
printf("%u,%06u: Trying %s=%s\n",
(unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec,
npa_secret_name(pace_input.pin_id), pace_input.pin);
eac_secret_name(pace_input.pin_id), pace_input.pin);
r = perform_pace(card, pace_input, &pace_output, tr_version);
@ -526,12 +527,12 @@ main (int argc, char **argv)
if (0 > r) {
printf("%u,%06u: Tried breaking %s without success.\n",
(unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec,
npa_secret_name(pace_input.pin_id));
eac_secret_name(pace_input.pin_id));
goto err;
} else {
printf("%u,%06u: Tried breaking %s with success (=%s).\n",
(unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec,
npa_secret_name(pace_input.pin_id),
eac_secret_name(pace_input.pin_id),
pace_input.pin);
}
}
@ -750,7 +751,7 @@ main (int argc, char **argv)
if (r < 0)
goto err;
printf("Established PACE channel with %s.\n",
npa_secret_name(pace_input.pin_id));
eac_secret_name(pace_input.pin_id));
nopace:
if (cmdline.cv_certificate_given || cmdline.private_key_given) {

View File

@ -30,6 +30,7 @@
#include "libopensc/sm.h"
#include "sm/sm-iso.h"
#include "sm/sm-eac.h"
#include "libopensc/card-npa.h"
#include <string.h>
static const char *newpin = NULL;