ccid-emulator: Build libopensc from source code
There is no longer an external (or stable) interface for libopensc. Linking this program with an existing version of libopensc that is pre-installed in the system library paths is not practical. However, a specific snapshot of the OpenSC source code is embedded here as a Git submodule (and included in the source distributions). Build libopensc from this and statically link it into this program. (Options such as '--enable-openpace' that are passed to ./configure will be forwarded to control the build configuration of libopensc.) Remove code that existed for compatibility when dynamically linking with older versions of libopensc.
This commit is contained in:
@@ -10,13 +10,13 @@ do_subst = $(SED) \
|
||||
BUILT_SOURCES = cmdline.h cmdline.c
|
||||
|
||||
EXTRA_DIST = ccid-emulator.ggo ccid-emulator.ggo.in
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/src/OpenSC/src -path '*/.git' -prune -o -type f -a \( -name '*.h' -o -name 'apdu.c' -o -name 'card.c' \) -print)
|
||||
MAINTAINERCLEANFILES = $(BUILT_SOURCES) ccid-emulator.ggo $(dist_man1_MANS)
|
||||
|
||||
dist_man1_MANS = ccid-emulator.1
|
||||
|
||||
ccid_emulator_SOURCES = cmdline.c ccid.c usbstring.c usb.c scutil.c
|
||||
ccid_emulator_LDADD = $(OPENSC_LIBS) $(OPENSSL_LIBS) $(PTHREAD_LIBS)
|
||||
ccid_emulator_LDADD = OpenSC/src/libopensc/libopensc.la
|
||||
ccid_emulator_LDFLAGS = $(OPENSSL_LIBS) $(PTHREAD_LIBS) -static
|
||||
ccid_emulator_CFLAGS = $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_srcdir)/src/OpenSC/src
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ bin_PROGRAMS = ccid-emulator
|
||||
|
||||
noinst_HEADERS = \
|
||||
ccid.h \
|
||||
ccid-types.h \
|
||||
cmdline.h \
|
||||
scutil.h \
|
||||
usbstring.h
|
||||
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Frank Morgner
|
||||
*
|
||||
* This file is part of ccid.
|
||||
*
|
||||
* ccid is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* ccid is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* ccid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
*/
|
||||
#ifndef _CCID_TYPES_H
|
||||
#define _CCID_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define USB_REQ_CCID 0xA1
|
||||
|
||||
#define CCID_CONTROL_ABORT 0x01
|
||||
#define CCID_CONTROL_GET_CLOCK_FREQUENCIES 0x02
|
||||
#define CCID_CONTROL_GET_DATA_RATES 0x03
|
||||
|
||||
#define CCID_OPERATION_VERIFY 0x00;
|
||||
#define CCID_OPERATION_MODIFY 0x01;
|
||||
#define CCID_ENTRY_VALIDATE 0x02
|
||||
|
||||
#define CCID_BERROR_CMD_ABORTED 0xff /** Host aborted the current activity */
|
||||
#define CCID_BERROR_ICC_MUTE 0xfe /** CCID timed out while talking to the ICC */
|
||||
#define CCID_BERROR_XFR_PARITY_ERROR 0xfd /** Parity error while talking to the ICC */
|
||||
#define CCID_BERROR_XFR_OVERRUN 0xfc /** Overrun error while talking to the ICC */
|
||||
#define CCID_BERROR_HW_ERROR 0xfb /** An all inclusive hardware error occurred */
|
||||
#define CCID_BERROR_BAD_ATR_TS 0xf
|
||||
#define CCID_BERROR_BAD_ATR_TCK 0xf
|
||||
#define CCID_BERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xf6
|
||||
#define CCID_BERROR_ICC_CLASS_NOT_SUPPORTED 0xf5
|
||||
#define CCID_BERROR_PROCEDURE_BYTE_CONFLICT 0xf4
|
||||
#define CCID_BERROR_DEACTIVATED_PROTOCOL 0xf3
|
||||
#define CCID_BERROR_BUSY_WITH_AUTO_SEQUENCE 0xf2 /** Automatic Sequence Ongoing */
|
||||
#define CCID_BERROR_PIN_TIMEOUT 0xf0
|
||||
#define CCID_BERROR_PIN_CANCELLED 0xef
|
||||
#define CCID_BERROR_CMD_SLOT_BUSY 0xe0 /** A second command was sent to a slot which was already processing a command. */
|
||||
#define CCID_BERROR_CMD_NOT_SUPPORTED 0x00
|
||||
#define CCID_BERROR_OK 0x00
|
||||
|
||||
#define CCID_BSTATUS_OK_ACTIVE 0x00 /** No error. An ICC is present and active */
|
||||
#define CCID_BSTATUS_OK_INACTIVE 0x01 /** No error. ICC is present and inactive */
|
||||
#define CCID_BSTATUS_OK_NOICC 0x02 /** No error. No ICC is present */
|
||||
#define CCID_BSTATUS_ERROR_ACTIVE 0x40 /** Failed. An ICC is present and active */
|
||||
#define CCID_BSTATUS_ERROR_INACTIVE 0x41 /** Failed. ICC is present and inactive */
|
||||
#define CCID_BSTATUS_ERROR_NOICC 0x42 /** Failed. No ICC is present */
|
||||
|
||||
#define CCID_WLEVEL_DIRECT __constant_cpu_to_le16(0) /** APDU begins and ends with this command */
|
||||
#define CCID_WLEVEL_CHAIN_NEXT_XFRBLOCK __constant_cpu_to_le16(1) /** APDU begins with this command, and continue in the next PC_to_RDR_XfrBlock */
|
||||
#define CCID_WLEVEL_CHAIN_END __constant_cpu_to_le16(2) /** abData field continues a command APDU and ends the APDU command */
|
||||
#define CCID_WLEVEL_CHAIN_CONTINUE __constant_cpu_to_le16(3) /** abData field continues a command APDU and another block is to follow */
|
||||
#define CCID_WLEVEL_RESPONSE_IN_DATABLOCK __constant_cpu_to_le16(0x10) /** empty abData field, continuation of response APDU is expected in the next RDR_to_PC_DataBlock */
|
||||
|
||||
#define CCID_PIN_ENCODING_BIN 0x00
|
||||
#define CCID_PIN_ENCODING_BCD 0x01
|
||||
#define CCID_PIN_ENCODING_ASCII 0x02
|
||||
#define CCID_PIN_UNITS_BYTES 0x80
|
||||
#define CCID_PIN_JUSTIFY_RIGHT 0x04
|
||||
#define CCID_PIN_CONFIRM_NEW 0x01
|
||||
#define CCID_PIN_INSERT_OLD 0x02
|
||||
#define CCID_PIN_NO_MSG 0x00
|
||||
#define CCID_PIN_MSG1 0x01
|
||||
#define CCID_PIN_MSG2 0x02
|
||||
#define CCID_PIN_MSG_REF 0x03
|
||||
#define CCID_PIN_MSG_DEFAULT 0xff
|
||||
|
||||
#define CCID_SLOTS_UNCHANGED 0x00
|
||||
#define CCID_SLOT1_CARD_PRESENT 0x01
|
||||
#define CCID_SLOT1_CHANGED 0x02
|
||||
#define CCID_SLOT2_CARD_PRESENT 0x04
|
||||
#define CCID_SLOT2_CHANGED 0x08
|
||||
#define CCID_SLOT3_CARD_PRESENT 0x10
|
||||
#define CCID_SLOT3_CHANGED 0x20
|
||||
#define CCID_SLOT4_CARD_PRESENT 0x40
|
||||
#define CCID_SLOT4_CHANGED 0x80
|
||||
|
||||
#define CCID_EXT_APDU_MAX (4 + 3 + 0xffff + 3)
|
||||
#define CCID_SHORT_APDU_MAX (4 + 1 + 0xff + 1)
|
||||
|
||||
struct ccid_class_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdCCID;
|
||||
uint8_t bMaxSlotIndex;
|
||||
uint8_t bVoltageSupport;
|
||||
uint32_t dwProtocols;
|
||||
uint32_t dwDefaultClock;
|
||||
uint32_t dwMaximumClock;
|
||||
uint8_t bNumClockSupport;
|
||||
uint32_t dwDataRate;
|
||||
uint32_t dwMaxDataRate;
|
||||
uint8_t bNumDataRatesSupported;
|
||||
uint32_t dwMaxIFSD;
|
||||
uint32_t dwSynchProtocols;
|
||||
uint32_t dwMechanical;
|
||||
uint32_t dwFeatures;
|
||||
uint32_t dwMaxCCIDMessageLength;
|
||||
uint8_t bClassGetResponse;
|
||||
uint8_t bclassEnvelope;
|
||||
uint16_t wLcdLayout;
|
||||
uint8_t bPINSupport;
|
||||
uint8_t bMaxCCIDBusySlots;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
typedef struct {
|
||||
uint8_t bmFindexDindex;
|
||||
uint8_t bmTCCKST0;
|
||||
uint8_t bGuardTimeT0;
|
||||
uint8_t bWaitingIntegerT0;
|
||||
uint8_t bClockStop;
|
||||
} __attribute__ ((packed)) abProtocolDataStructure_T0_t;
|
||||
typedef struct {
|
||||
uint8_t bmFindexDindex;
|
||||
uint8_t bmTCCKST1;
|
||||
uint8_t bGuardTimeT1;
|
||||
uint8_t bWaitingIntegersT1;
|
||||
uint8_t bClockStop;
|
||||
uint8_t bIFSC;
|
||||
uint8_t bNadValue;
|
||||
} __attribute__ ((packed)) abProtocolDataStructure_T1_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bTimeOut;
|
||||
uint8_t bmFormatString;
|
||||
uint8_t bmPINBlockString;
|
||||
uint8_t bmPINLengthFormat;
|
||||
uint16_t wPINMaxExtraDigit;
|
||||
uint8_t bEntryValidationCondition;
|
||||
uint8_t bNumberMessage;
|
||||
uint16_t wLangId;
|
||||
uint8_t bMsgIndex;
|
||||
uint8_t bTeoPrologue1;
|
||||
uint16_t bTeoPrologue2;
|
||||
} __attribute__ ((packed)) abPINDataStucture_Verification_t;
|
||||
typedef struct {
|
||||
uint8_t bTimeOut;
|
||||
uint8_t bmFormatString;
|
||||
uint8_t bmPINBlockString;
|
||||
uint8_t bmPINLengthFormat;
|
||||
uint8_t bInsertionOffsetOld;
|
||||
uint8_t bInsertionOffsetNew;
|
||||
uint16_t wPINMaxExtraDigit;
|
||||
uint8_t bConfirmPIN;
|
||||
uint8_t bEntryValidationCondition;
|
||||
uint8_t bNumberMessage;
|
||||
uint16_t wLangId;
|
||||
uint8_t bMsgIndex1;
|
||||
} __attribute__ ((packed)) abPINDataStucture_Modification_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bBWI;
|
||||
uint16_t wLevelParameter;
|
||||
} __attribute__ ((packed)) PC_to_RDR_XfrBlock_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __attribute__ ((packed)) PC_to_RDR_IccPowerOff_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __attribute__ ((packed)) PC_to_RDR_GetSlotStatus_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __attribute__ ((packed)) PC_to_RDR_GetParameters_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t abRFU1;
|
||||
uint16_t abRFU2;
|
||||
} __attribute__ ((packed)) PC_to_RDR_ResetParameters_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bProtocolNum;
|
||||
uint16_t abRFU;
|
||||
} __attribute__ ((packed)) PC_to_RDR_SetParameters_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bBWI;
|
||||
uint16_t wLevelParameter;
|
||||
} __attribute__ ((packed)) PC_to_RDR_Secure_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bPowerSelect;
|
||||
uint16_t abRFU;
|
||||
} __attribute__ ((packed)) PC_to_RDR_IccPowerOn_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bStatus;
|
||||
uint8_t bError;
|
||||
uint8_t bClockStatus;
|
||||
} __attribute__ ((packed)) RDR_to_PC_SlotStatus_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bStatus;
|
||||
uint8_t bError;
|
||||
uint8_t bChainParameter;
|
||||
} __attribute__ ((packed)) RDR_to_PC_DataBlock_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint32_t dwLength;
|
||||
uint8_t bSlot;
|
||||
uint8_t bSeq;
|
||||
uint8_t bStatus;
|
||||
uint8_t bError;
|
||||
uint8_t bProtocolNum;
|
||||
} __attribute__ ((packed)) RDR_to_PC_Parameters_t;
|
||||
typedef struct {
|
||||
uint8_t bMessageType;
|
||||
uint8_t bmSlotICCState; /* we support 1 slots, so we need 2*1 bits = 1 byte */
|
||||
} __attribute__ ((packed)) RDR_to_PC_NotifySlotChange_t;
|
||||
|
||||
struct hid_class_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
uint32_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -34,10 +34,6 @@
|
||||
#include "config.h"
|
||||
#include "scutil.h"
|
||||
|
||||
#ifndef HAVE_BOXING_BUF_TO_PACE_INPUT
|
||||
#include <libopensc/reader-boxing.c>
|
||||
#endif
|
||||
|
||||
static sc_context_t *ctx = NULL;
|
||||
static sc_card_t *card = NULL;
|
||||
static sc_reader_t *reader = NULL;
|
||||
@@ -464,11 +460,6 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
||||
}
|
||||
|
||||
if (sc_result >= 0) {
|
||||
#ifdef WITH_PACE
|
||||
#ifndef DISABLE_GLOBAL_BOXING_INITIALIZATION
|
||||
sc_initialize_boxing_cmds(ctx);
|
||||
#endif
|
||||
#endif
|
||||
return get_RDR_to_PC_SlotStatus(request->bSeq,
|
||||
sc_result, out, outlen, card->atr.value, card->atr.len);
|
||||
} else {
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#define _CCID_H
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <libopensc/opensc.h>
|
||||
#include "ccid-types.h"
|
||||
#include <libopensc/ccid-types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -20,29 +20,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "libopensc/internal.h"
|
||||
|
||||
#ifndef HAVE__SC_MATCH_ATR
|
||||
int sc_dlclose(void *handle) {}
|
||||
const char *sc_dlerror() {}
|
||||
void *sc_dlsym(void *handle, const char *symbol) {}
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz) {}
|
||||
int sc_mutex_create(const sc_context_t *ctx, void **mutex) {}
|
||||
int sc_mutex_destroy(const sc_context_t *ctx, void *mutex) {}
|
||||
int _sc_parse_atr(sc_reader_t *reader) {}
|
||||
void *sc_dlopen(const char *filename) {}
|
||||
int sc_mutex_lock(const sc_context_t *ctx, void *mutex) {}
|
||||
int sc_mutex_unlock(const sc_context_t *ctx, void *mutex) {}
|
||||
#include "libopensc/card.c"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SC_APDU_GET_OCTETS) || !defined(HAVE_SC_APDU_SET_RESP)
|
||||
#ifdef HAVE__SC_MATCH_ATR
|
||||
size_t sc_get_max_send_size(const sc_card_t *card) {return 0;}
|
||||
#endif
|
||||
#include "libopensc/apdu.c"
|
||||
#endif
|
||||
|
||||
#include <libopensc/internal.h>
|
||||
#include <libopensc/log.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -88,38 +88,5 @@ void _bin_log(sc_context_t *ctx, int type, const char *file, int line,
|
||||
*/
|
||||
int print_avail(int verbose);
|
||||
|
||||
/*
|
||||
* OPENSC functions that do not get exported (sometimes)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the encoded APDU in newly created buffer.
|
||||
* @param ctx sc_context_t object
|
||||
* @param apdu sc_apdu_t object with the APDU to encode
|
||||
* @param buf pointer to the newly allocated buffer
|
||||
* @param len length of the encoded APDU
|
||||
* @param proto protocol to be used
|
||||
* @return SC_SUCCESS on success and an error code otherwise
|
||||
*/
|
||||
int sc_apdu_get_octets(sc_context_t *ctx, const sc_apdu_t *apdu, u8 **buf,
|
||||
size_t *len, unsigned int proto);
|
||||
|
||||
/**
|
||||
* Sets the status bytes and return data in the APDU
|
||||
* @param ctx sc_context_t object
|
||||
* @param apdu the apdu to which the data should be written
|
||||
* @param buf returned data
|
||||
* @param len length of the returned data
|
||||
* @return SC_SUCCESS on success and an error code otherwise
|
||||
*/
|
||||
int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf,
|
||||
size_t len);
|
||||
|
||||
/* Returns an index number if a match was found, -1 otherwise. table has to
|
||||
* be null terminated. */
|
||||
int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *type_out);
|
||||
|
||||
int fread_to_eof(const char *file, unsigned char **buf, size_t *buflen);
|
||||
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
Reference in New Issue
Block a user