- bugfix: moved ASN.1 declaration of PACE-APDUs to pace.c
- added commandline-option to test PACE currently with hard coded secret etc. git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@41 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
#include <opensc/log.h>
|
#include <opensc/log.h>
|
||||||
|
|
||||||
#include "ccid.h"
|
#include "ccid.h"
|
||||||
|
#include "pace.h"
|
||||||
|
|
||||||
//static const char *app_name = "ccid";
|
//static const char *app_name = "ccid";
|
||||||
static sc_context_t *ctx = NULL;
|
static sc_context_t *ctx = NULL;
|
||||||
@@ -1277,3 +1278,8 @@ int ccid_state_changed(RDR_to_PC_NotifySlotChange_t **slotchange, int timeout)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ccid_testpace()
|
||||||
|
{
|
||||||
|
pace_test(ctx, card_in_slot[0]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ void ccid_shutdown();
|
|||||||
int ccid_parse_bulkin(const __u8* inbuf, __u8** outbuf);
|
int ccid_parse_bulkin(const __u8* inbuf, __u8** outbuf);
|
||||||
int ccid_parse_control(struct usb_ctrlrequest *setup, __u8 **outbuf);
|
int ccid_parse_control(struct usb_ctrlrequest *setup, __u8 **outbuf);
|
||||||
int ccid_state_changed(RDR_to_PC_NotifySlotChange_t **slotchange, int timeout);
|
int ccid_state_changed(RDR_to_PC_NotifySlotChange_t **slotchange, int timeout);
|
||||||
|
void ccid_testpace();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
132
ccid/pace.c
132
ccid/pace.c
@@ -19,6 +19,109 @@
|
|||||||
#include <opensc/log.h>
|
#include <opensc/log.h>
|
||||||
#include "pace.h"
|
#include "pace.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ASN1_APP_EXP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MSE:Set AT
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct pace_mse_set_at_cd_st {
|
||||||
|
ASN1_OBJECT *cryptographic_mechanism_reference;
|
||||||
|
ASN1_INTEGER *key_reference1;
|
||||||
|
ASN1_INTEGER *key_reference2;
|
||||||
|
ASN1_INTEGER *auxiliary_data;
|
||||||
|
ASN1_INTEGER *eph_pub_key;
|
||||||
|
ASN1_INTEGER *cha_template;
|
||||||
|
} PACE_MSE_SET_AT_C;
|
||||||
|
ASN1_SEQUENCE(PACE_MSE_SET_AT_C) = {
|
||||||
|
/* 0x80
|
||||||
|
* Cryptographic mechanism reference */
|
||||||
|
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0),
|
||||||
|
/* 0x83
|
||||||
|
* Reference of a public key / secret key */
|
||||||
|
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, key_reference1, ASN1_INTEGER, 3),
|
||||||
|
/* 0x84
|
||||||
|
* Reference of a private key / Reference for computing a session key */
|
||||||
|
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, key_reference2, ASN1_INTEGER, 4),
|
||||||
|
/* 0x67
|
||||||
|
* Auxiliary authenticated data */
|
||||||
|
ASN1_APP_EXP_OPT(PACE_MSE_SET_AT_C, auxiliary_data, ASN1_INTEGER, 7),
|
||||||
|
/* 0x91
|
||||||
|
* Ephemeral Public Key */
|
||||||
|
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, eph_pub_key, ASN1_INTEGER, 0x11),
|
||||||
|
/* 0x7F4C
|
||||||
|
* Certificate Holder Authorization Template */
|
||||||
|
ASN1_APP_EXP_OPT(PACE_MSE_SET_AT_C, cha_template, ASN1_INTEGER, 0x4c),
|
||||||
|
} ASN1_SEQUENCE_END(PACE_MSE_SET_AT_C)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS(PACE_MSE_SET_AT_C)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General Authenticate
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Protocol Command Data */
|
||||||
|
typedef struct pace_gen_auth_cd_st {
|
||||||
|
ASN1_OCTET_STRING *mapping_data;
|
||||||
|
ASN1_OCTET_STRING *eph_pub_key;
|
||||||
|
ASN1_OCTET_STRING *auth_token;
|
||||||
|
} PACE_GEN_AUTH_C;
|
||||||
|
ASN1_SEQUENCE(PACE_GEN_AUTH_C) = {
|
||||||
|
/* 0x81
|
||||||
|
* Mapping Data */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_C, mapping_data, ASN1_INTEGER, 1),
|
||||||
|
/* 0x83
|
||||||
|
* Ephemeral Public Key */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_C, eph_pub_key, ASN1_INTEGER, 3),
|
||||||
|
/* 0x85
|
||||||
|
* Authentication Token */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_C, auth_token, ASN1_INTEGER, 5),
|
||||||
|
} ASN1_SEQUENCE_END(PACE_GEN_AUTH_C)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_C)
|
||||||
|
|
||||||
|
/* Protocol Response Data */
|
||||||
|
typedef struct pace_gen_auth_rapdu_body_st {
|
||||||
|
ASN1_INTEGER *enc_nonce;
|
||||||
|
ASN1_INTEGER *mapping_data;
|
||||||
|
ASN1_INTEGER *eph_pub_key;
|
||||||
|
ASN1_INTEGER *auth_token;
|
||||||
|
ASN1_INTEGER *cert_auth1;
|
||||||
|
ASN1_INTEGER *cert_auth2;
|
||||||
|
} PACE_GEN_AUTH_R_BODY;
|
||||||
|
ASN1_SEQUENCE(PACE_GEN_AUTH_R_BODY) = {
|
||||||
|
/* 0x80
|
||||||
|
* Encrypted Nonce */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, enc_nonce, ASN1_INTEGER, 0),
|
||||||
|
/* 0x82
|
||||||
|
* Mapping Data */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, mapping_data, ASN1_INTEGER, 2),
|
||||||
|
/* 0x84
|
||||||
|
* Ephemeral Public Key */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, eph_pub_key, ASN1_INTEGER, 4),
|
||||||
|
/* 0x86
|
||||||
|
* Authentication Token */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, auth_token, ASN1_INTEGER, 6),
|
||||||
|
/* 0x87
|
||||||
|
* Certification Authority Reference */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, cert_auth1, ASN1_INTEGER, 7),
|
||||||
|
/* 0x88
|
||||||
|
* Certification Authority Reference */
|
||||||
|
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, cert_auth2, ASN1_INTEGER, 8),
|
||||||
|
} ASN1_SEQUENCE_END(PACE_GEN_AUTH_R_BODY)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_R_BODY)
|
||||||
|
|
||||||
|
typedef PACE_GEN_AUTH_R_BODY PACE_GEN_AUTH_R;
|
||||||
|
/* 0x7C
|
||||||
|
* Dynamic Authentication Data */
|
||||||
|
ASN1_ITEM_TEMPLATE(PACE_GEN_AUTH_R) =
|
||||||
|
ASN1_EX_TEMPLATE_TYPE(
|
||||||
|
ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION,
|
||||||
|
0x1c, PACE_GEN_AUTH_R, PACE_GEN_AUTH_R_BODY)
|
||||||
|
ASN1_ITEM_TEMPLATE_END(PACE_GEN_AUTH_R)
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_R)
|
||||||
|
|
||||||
|
|
||||||
#ifdef NO_PACE
|
#ifdef NO_PACE
|
||||||
inline int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card,
|
inline int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card,
|
||||||
const __u8 *in, __u8 **out, size_t *outlen) {
|
const __u8 *in, __u8 **out, size_t *outlen) {
|
||||||
@@ -28,15 +131,18 @@ inline int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
|
|||||||
const __u8 *in, __u8 **out, size_t *outlen) {
|
const __u8 *in, __u8 **out, size_t *outlen) {
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
void pace_test(sc_context_t *ctx, sc_card_t *card) {
|
||||||
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <opensc/opensc.h>
|
#include <opensc/opensc.h>
|
||||||
#include <opensc/ui.h>
|
#include <opensc/ui.h>
|
||||||
#include <openssl/pace.h>
|
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <openssl/pace.h>
|
||||||
|
|
||||||
uint16_t ssc = 0;
|
uint16_t ssc = 0;
|
||||||
|
|
||||||
@@ -72,8 +178,10 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
|
|||||||
snprintf(buf, sizeof buf, "3f00%04x", FID_EF_CARDACCESS);
|
snprintf(buf, sizeof buf, "3f00%04x", FID_EF_CARDACCESS);
|
||||||
sc_format_path(buf, &path);
|
sc_format_path(buf, &path);
|
||||||
|
|
||||||
|
//printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
SC_TEST_RET(ctx, sc_select_file(card, &path, &file),
|
SC_TEST_RET(ctx, sc_select_file(card, &path, &file),
|
||||||
"Could not select EF.CardAccess.");
|
"Could not select EF.CardAccess.");
|
||||||
|
//printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
ssc++;
|
ssc++;
|
||||||
|
|
||||||
*length_ef_cardaccess = file->size;
|
*length_ef_cardaccess = file->size;
|
||||||
@@ -580,4 +688,26 @@ err:
|
|||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, r);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pace_test(sc_context_t *ctx, sc_card_t *card)
|
||||||
|
{
|
||||||
|
__u8 in[16];
|
||||||
|
__u8 *out = NULL;
|
||||||
|
size_t outlen;
|
||||||
|
|
||||||
|
in[0] = PACE_CAN; // pin_id
|
||||||
|
in[1] = 0; // length_chat
|
||||||
|
in[2] = 6; // length_pin
|
||||||
|
in[3] = '8';
|
||||||
|
in[4] = '4';
|
||||||
|
in[5] = '0';
|
||||||
|
in[6] = '1';
|
||||||
|
in[7] = '7';
|
||||||
|
in[8] = '9';
|
||||||
|
in[9] = 0; // length_cert_desc
|
||||||
|
in[10]= 0; // length_cert_desc
|
||||||
|
|
||||||
|
EstablishPACEChannel(ctx, card, in, &out, &outlen);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
112
ccid/pace.h
112
ccid/pace.h
@@ -31,120 +31,18 @@ extern "C" {
|
|||||||
#define PACE_BITMAP_EID 0x20
|
#define PACE_BITMAP_EID 0x20
|
||||||
#define PACE_BITMAP_ESIGN 0x10
|
#define PACE_BITMAP_ESIGN 0x10
|
||||||
|
|
||||||
#define PACE_MRZ 0x01
|
//#define PACE_MRZ 0x01
|
||||||
#define PACE_CAN 0x02
|
//#define PACE_CAN 0x02
|
||||||
#define PACE_PIN 0x03
|
//#define PACE_PIN 0x03
|
||||||
#define PACE_PUK 0x04
|
//#define PACE_PUK 0x04
|
||||||
|
|
||||||
#define FID_EF_CARDACCESS 0x011C
|
#define FID_EF_CARDACCESS 0x011C
|
||||||
|
|
||||||
#define ASN1_APP_EXP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MSE:Set AT
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct pace_mse_set_at_cd_st {
|
|
||||||
ASN1_OBJECT *cryptographic_mechanism_reference;
|
|
||||||
ASN1_INTEGER *key_reference1;
|
|
||||||
ASN1_INTEGER *key_reference2;
|
|
||||||
ASN1_INTEGER *auxiliary_data;
|
|
||||||
ASN1_INTEGER *eph_pub_key;
|
|
||||||
ASN1_INTEGER *cha_template;
|
|
||||||
} PACE_MSE_SET_AT_C;
|
|
||||||
ASN1_SEQUENCE(PACE_MSE_SET_AT_C) = {
|
|
||||||
/* 0x80
|
|
||||||
* Cryptographic mechanism reference */
|
|
||||||
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0),
|
|
||||||
/* 0x83
|
|
||||||
* Reference of a public key / secret key */
|
|
||||||
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, key_reference1, ASN1_INTEGER, 3),
|
|
||||||
/* 0x84
|
|
||||||
* Reference of a private key / Reference for computing a session key */
|
|
||||||
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, key_reference2, ASN1_INTEGER, 4),
|
|
||||||
/* 0x67
|
|
||||||
* Auxiliary authenticated data */
|
|
||||||
ASN1_APP_EXP_OPT(PACE_MSE_SET_AT_C, auxiliary_data, ASN1_INTEGER, 7),
|
|
||||||
/* 0x91
|
|
||||||
* Ephemeral Public Key */
|
|
||||||
ASN1_IMP_OPT(PACE_MSE_SET_AT_C, eph_pub_key, ASN1_INTEGER, 0x11),
|
|
||||||
/* 0x7F4C
|
|
||||||
* Certificate Holder Authorization Template */
|
|
||||||
ASN1_APP_EXP_OPT(PACE_MSE_SET_AT_C, cha_template, ASN1_INTEGER, 0x4c),
|
|
||||||
} ASN1_SEQUENCE_END(PACE_MSE_SET_AT_C)
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PACE_MSE_SET_AT_C)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* General Authenticate
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Protocol Command Data */
|
|
||||||
typedef struct pace_gen_auth_cd_st {
|
|
||||||
ASN1_OCTET_STRING *mapping_data;
|
|
||||||
ASN1_OCTET_STRING *eph_pub_key;
|
|
||||||
ASN1_OCTET_STRING *auth_token;
|
|
||||||
} PACE_GEN_AUTH_C;
|
|
||||||
ASN1_SEQUENCE(PACE_GEN_AUTH_C) = {
|
|
||||||
/* 0x81
|
|
||||||
* Mapping Data */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_C, mapping_data, ASN1_INTEGER, 1),
|
|
||||||
/* 0x83
|
|
||||||
* Ephemeral Public Key */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_C, eph_pub_key, ASN1_INTEGER, 3),
|
|
||||||
/* 0x85
|
|
||||||
* Authentication Token */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_C, auth_token, ASN1_INTEGER, 5),
|
|
||||||
} ASN1_SEQUENCE_END(PACE_GEN_AUTH_C)
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_C)
|
|
||||||
|
|
||||||
/* Protocol Response Data */
|
|
||||||
typedef struct pace_gen_auth_rapdu_body_st {
|
|
||||||
ASN1_INTEGER *enc_nonce;
|
|
||||||
ASN1_INTEGER *mapping_data;
|
|
||||||
ASN1_INTEGER *eph_pub_key;
|
|
||||||
ASN1_INTEGER *auth_token;
|
|
||||||
ASN1_INTEGER *cert_auth1;
|
|
||||||
ASN1_INTEGER *cert_auth2;
|
|
||||||
} PACE_GEN_AUTH_R_BODY;
|
|
||||||
ASN1_SEQUENCE(PACE_GEN_AUTH_R_BODY) = {
|
|
||||||
/* 0x80
|
|
||||||
* Encrypted Nonce */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, enc_nonce, ASN1_INTEGER, 0),
|
|
||||||
/* 0x82
|
|
||||||
* Mapping Data */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, mapping_data, ASN1_INTEGER, 2),
|
|
||||||
/* 0x84
|
|
||||||
* Ephemeral Public Key */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, eph_pub_key, ASN1_INTEGER, 4),
|
|
||||||
/* 0x86
|
|
||||||
* Authentication Token */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, auth_token, ASN1_INTEGER, 6),
|
|
||||||
/* 0x87
|
|
||||||
* Certification Authority Reference */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, cert_auth1, ASN1_INTEGER, 7),
|
|
||||||
/* 0x88
|
|
||||||
* Certification Authority Reference */
|
|
||||||
ASN1_IMP_OPT(PACE_GEN_AUTH_R_BODY, cert_auth2, ASN1_INTEGER, 8),
|
|
||||||
} ASN1_SEQUENCE_END(PACE_GEN_AUTH_R_BODY)
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_R_BODY)
|
|
||||||
|
|
||||||
typedef PACE_GEN_AUTH_R_BODY PACE_GEN_AUTH_R;
|
|
||||||
/* 0x7C
|
|
||||||
* Dynamic Authentication Data */
|
|
||||||
ASN1_ITEM_TEMPLATE(PACE_GEN_AUTH_R) =
|
|
||||||
ASN1_EX_TEMPLATE_TYPE(
|
|
||||||
ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION,
|
|
||||||
0x1c, PACE_GEN_AUTH_R, PACE_GEN_AUTH_R_BODY)
|
|
||||||
ASN1_ITEM_TEMPLATE_END(PACE_GEN_AUTH_R)
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_R)
|
|
||||||
|
|
||||||
|
|
||||||
int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card, const __u8
|
int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card, const __u8
|
||||||
*in, __u8 **out, size_t *outlen);
|
*in, __u8 **out, size_t *outlen);
|
||||||
int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card, const __u8 *in,
|
int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card, const __u8 *in,
|
||||||
__u8 **out, size_t *outlen);
|
__u8 **out, size_t *outlen);
|
||||||
|
void pace_test(sc_context_t *ctx, sc_card_t *card);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ static int verbose = 0;
|
|||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
static int dohid = 0;
|
static int dohid = 0;
|
||||||
static int doint = 0;
|
static int doint = 0;
|
||||||
|
static int dotest = 0;
|
||||||
int usb_reader_num = 0;
|
int usb_reader_num = 0;
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
@@ -65,6 +66,7 @@ static const struct option options[] = {
|
|||||||
{ "interrupt", no_argument, &doint, 'n' },
|
{ "interrupt", no_argument, &doint, 'n' },
|
||||||
{ "reader", required_argument, NULL, 'r' },
|
{ "reader", required_argument, NULL, 'r' },
|
||||||
{ "serial", required_argument, NULL, 's' },
|
{ "serial", required_argument, NULL, 's' },
|
||||||
|
{ "test-pace", no_argument, &dotest, 't' },
|
||||||
{ "product", required_argument, NULL, 'p' },
|
{ "product", required_argument, NULL, 'p' },
|
||||||
{ "vendor", required_argument, NULL, 'e' },
|
{ "vendor", required_argument, NULL, 'e' },
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
@@ -77,6 +79,7 @@ static const char *option_help[] = {
|
|||||||
"Add interrupt pipe for CCID",
|
"Add interrupt pipe for CCID",
|
||||||
"Number of the reader to use (default: auto-detect)",
|
"Number of the reader to use (default: auto-detect)",
|
||||||
"Serial number (max 56 bytes) of gadget (default: random)",
|
"Serial number (max 56 bytes) of gadget (default: random)",
|
||||||
|
"test PACE implementation",
|
||||||
"USB product ID (default: 0x3010)",
|
"USB product ID (default: 0x3010)",
|
||||||
"USB vendor ID (0default: x0D46)",
|
"USB vendor ID (0default: x0D46)",
|
||||||
"Use (several times) to be more verbose",
|
"Use (several times) to be more verbose",
|
||||||
@@ -1028,6 +1031,11 @@ static void *ccid (void *param)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dotest) {
|
||||||
|
sleep(2);
|
||||||
|
ccid_testpace();
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* original LinuxThreads cancelation didn't work right
|
/* original LinuxThreads cancelation didn't work right
|
||||||
|
|||||||
Reference in New Issue
Block a user