vsmartcard-3.3/0000755000175000017500000000000013672155300012201 5ustar philphilvsmartcard-3.3/npa/0000755000175000017500000000000013546304763012770 5ustar philphilvsmartcard-3.3/npa/README.md0000644000175000017500000000041713546304763014251 0ustar philphil# nPA Smart Card Library Access the German electronic identity card (neuer Personalausweis/nPA). The functionality of nPA Smart Card Library has been integrated into OpenSC. Developement and Support will continue at our new home https://github.com/frankmorgner/OpenSC. vsmartcard-3.3/npa/README.txt0000644000175000017500000000061613546304763014471 0ustar philphil.. meta:: :http-equiv=refresh: 0;URL='https://github.com/frankmorgner/OpenSC' ###################### nPA Smart Card Library ###################### Access the German electronic identity card (neuer Personalausweis/nPA). The functionality of nPA Smart Card Library has been integrated into OpenSC. Developement and Support will continue at our new home https://github.com/frankmorgner/OpenSC. vsmartcard-3.3/ccid/0000755000175000017500000000000013546304763013114 5ustar philphilvsmartcard-3.3/ccid/docs0000777000175000017500000000000013546304763015131 2../docs/ustar philphilvsmartcard-3.3/ccid/README.md0000644000175000017500000000071613546304763014377 0ustar philphil# USB CCID Emulator The USB CCID Emulator forwards a locally present PC/SC smart card reader as a standard USB CCID reader. USB CCID Emulator can be used as trusted intermediary enabling secure PIN entry and PIN modification. In combination with [OpenSC](https://github.com/frankmorgner/OpenSC) also PACE can be performed by the emulator. Please refer to [our project's website](http://frankmorgner.github.io/vsmartcard/ccid/README.html) for more information. vsmartcard-3.3/ccid/src/0000755000175000017500000000000013546304763013703 5ustar philphilvsmartcard-3.3/ccid/src/scutil.h0000644000175000017500000000767513546304763015376 0ustar philphil/* * Copyright (C) 2010 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 . */ /** * @file * @addtogroup scutil Wrappers around OpenSC * @{ */ #ifndef _CCID_SCUTIL_H #define _CCID_SCUTIL_H #include /** * @brief Initializes smart card context and reader * * @param[in] reader_id Index to the reader to be used. Set to -1 to use a reader with an inserted card. * @param[in] verbose verbosity level passed to \c sc_context_t * @param[in,out] ctx Where to write the sc context * @param[in,out] reader Where to write the reader context * * @return */ int initialize(int reader_id, int verbose, sc_context_t **ctx, sc_reader_t **reader); /** * @brief Print binary data to a file stream * * @param[in] file File for printing * @param[in] label Label to prepend to the buffer * @param[in] data Binary data * @param[in] len Length of \a data */ #define bin_print(file, label, data, len) \ _bin_log(NULL, 0, NULL, 0, NULL, label, data, len, file) /** * @brief Log binary data to a sc context * * @param[in] ctx Context for logging * @param[in] level * @param[in] label Label to prepend to the buffer * @param[in] data Binary data * @param[in] len Length of \a data */ #define bin_log(ctx, level, label, data, len) \ _bin_log(ctx, level, __FILE__, __LINE__, __FUNCTION__, label, data, len, NULL) /** * @brief Log binary data * * Either choose \a ctx or \a file for logging * * @param[in] ctx (optional) Context for logging * @param[in] type Debug level * @param[in] file File name to be prepended * @param[in] line Line to be prepended * @param[in] func Function to be prepended * @param[in] label label to prepend to the buffer * @param[in] data binary data * @param[in] len length of \a data * @param[in] f (optional) File for printing */ void _bin_log(sc_context_t *ctx, int type, const char *file, int line, const char *func, const char *label, const u8 *data, size_t len, FILE *f); /** * @brief Prints the available readers to stdout. * * @param verbose * * @return \c SC_SUCCESS or error code if an error occurred */ 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 /* @} */ vsmartcard-3.3/ccid/src/usb.c0000644000175000017500000012722513546304763014651 0ustar philphil/* * Copyright (C) 2009-2012 Frank Morgner * * This file is part of ccid-emulator. * * ccid-emulator 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-emulator 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-emulator. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include // #ifdef AIO /* this aio code works with libaio-0.3.106 */ #include #endif #include "ccid.h" #include "cmdline.h" #include "config.h" #include "scutil.h" #include "usbstring.h" #define DRIVER_VENDOR_NUM 0x0D46 /* KOBIL Systems */ #define DRIVER_PRODUCT_NUM 0x3010 /* KOBIL Class 3 Reader */ static int vendorid = DRIVER_VENDOR_NUM; static int productid = DRIVER_PRODUCT_NUM; static int verbose = 0; static int debug = 0; static int doint = 0; static const char *doiintf = NULL; static const char *gadgetfs = "/dev/gadget"; /* NOTE: these IDs don't imply endpoint numbering; host side drivers * should use endpoint descriptors, or perhaps bcdDevice, to configure * such things. Other product IDs could have different policies. */ /*-------------------------------------------------------------------------*/ /* these descriptors are modified based on what controller we find */ extern struct ccid_class_descriptor ccid_desc; #define STRINGID_MFGR 1 #define STRINGID_PRODUCT 2 #define STRINGID_SERIAL 3 #define STRINGID_CONFIG 4 #define STRINGID_INTERFACE 5 static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, //.bcdUSB = __constant_cpu_to_le16 (0x0110), .bDescriptorType = USB_DT_DEVICE, .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, .bDeviceSubClass = 0, .bDeviceProtocol = 0, // .bMaxPacketSize0 ... set by gadgetfs .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), .iManufacturer = STRINGID_MFGR, .iProduct = STRINGID_PRODUCT, .iSerialNumber = STRINGID_SERIAL, .bNumConfigurations = 1, }; #define MAX_USB_POWER 1 #define CONFIG_VALUE 3 static struct usb_config_descriptor config = { .bLength = sizeof config, .bDescriptorType = USB_DT_CONFIG, /* must compute wTotalLength ... */ .bNumInterfaces = 1, .bConfigurationValue = CONFIG_VALUE, .iConfiguration = STRINGID_CONFIG, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bMaxPower = (MAX_USB_POWER + 1) / 2, }; static struct usb_interface_descriptor source_sink_intf = { .bLength = sizeof source_sink_intf, .bDescriptorType = USB_DT_INTERFACE, .bInterfaceClass = USB_CLASS_CSCID, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = STRINGID_INTERFACE, }; /* Full speed configurations are used for full-speed only devices as * well as dual-speed ones (the only kind with high speed support). */ static struct usb_endpoint_descriptor fs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, /* NOTE some controllers may need FS bulk max packet size * to be smaller. it would be a chip-specific option. */ .wMaxPacketSize = __constant_cpu_to_le16 (64), }; static struct usb_endpoint_descriptor fs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16 (64), }; /* some devices can handle other result packet sizes */ /*#define STATUS_MAXPACKET 16*/ /*#define LOG2_STATUS_POLL_MSEC 5*/ #define STATUS_MAXPACKET 8 #define LOG2_STATUS_POLL_MSEC 3 static struct usb_endpoint_descriptor fs_status_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = __constant_cpu_to_le16 (STATUS_MAXPACKET), .bInterval = (1 << LOG2_STATUS_POLL_MSEC), }; static const struct usb_endpoint_descriptor *fs_eps [3] = { &fs_source_desc, &fs_sink_desc, &fs_status_desc, }; /* High speed configurations are used only in addition to a full-speed * ones ... since all high speed devices support full speed configs. * Of course, not all hardware supports high speed configurations. */ static struct usb_endpoint_descriptor hs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16 (512), }; static struct usb_endpoint_descriptor hs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = __constant_cpu_to_le16 (512), .bInterval = 1, }; static struct usb_endpoint_descriptor hs_status_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = __constant_cpu_to_le16 (STATUS_MAXPACKET), .bInterval = LOG2_STATUS_POLL_MSEC + 3, }; static const struct usb_endpoint_descriptor *hs_eps [] = { &hs_source_desc, &hs_sink_desc, &hs_status_desc, }; /*-------------------------------------------------------------------------*/ /* 56 is the maximum for the KOBIL Class 3 Reader */ /* Flawfinder: ignore */ static char serial [57]; static const char interrupt_on_string[] = "Insertion and removal events enabled"; static const char interrupt_off_string[] = "Insertion and removal events disabled"; static struct usb_string stringtab [] = { { STRINGID_MFGR, "Virtual Smart Card Architecture", }, { STRINGID_PRODUCT, "CCID Emulator", }, { STRINGID_SERIAL, serial, }, #ifdef WITH_PACE { STRINGID_CONFIG, "PACE support enabled", }, #else { STRINGID_CONFIG, "PACE support disabled", }, #endif { STRINGID_INTERFACE, interrupt_on_string, }, }; static struct usb_gadget_strings strings = { .language = 0x0409, /* "en-us" */ .strings = stringtab, }; /*-------------------------------------------------------------------------*/ /* kernel drivers could autoconfigure like this too ... if * they were willing to waste the relevant code/data space. */ static int HIGHSPEED; static char *DEVNAME; static char *EP_IN_NAME, *EP_OUT_NAME, *EP_STATUS_NAME; /* gadgetfs currently has no chunking (or O_DIRECT/zerocopy) support * to turn big requests into lots of smaller ones; so this is "small". */ #define USB_BUFSIZE (7 * 1024) static enum usb_device_speed current_speed; static int autoconfig () { struct stat statb; /* NetChip 2280 PCI device (or dummy_hcd), high/full speed */ if (stat (DEVNAME = "net2280", &statb) == 0 #ifdef OLD_KERNEL || stat (DEVNAME = "dummy_udc", &statb) == 0 #endif ) { HIGHSPEED = 1; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0100), fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 7; EP_IN_NAME = "ep-a"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 3; EP_OUT_NAME = "ep-b"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 11; EP_STATUS_NAME = "ep-f"; #ifndef OLD_KERNEL /* dummy_hcd, high/full speed */ } else if (stat (DEVNAME = "dummy_udc", &statb) == 0) { HIGHSPEED = 1; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0100), fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 7; EP_IN_NAME = "ep6in-bulk"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 3; EP_OUT_NAME = "ep7out-bulk"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 11; EP_STATUS_NAME = "ep11in-bulk"; #endif /* Intel PXA 2xx processor, full speed only */ } else if (stat (DEVNAME = "pxa2xx_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0101), fs_source_desc.bEndpointAddress = USB_DIR_IN | 6; EP_IN_NAME = "ep6in-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 7; EP_OUT_NAME = "ep7out-bulk"; /* using bulk for this since the pxa interrupt endpoints * always use the no-toggle scheme (discouraged). */ source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 11; EP_STATUS_NAME = "ep11in-bulk"; #if 0 /* AMD au1x00 processor, full speed only */ } else if (stat (DEVNAME = "au1x00_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0102), fs_source_desc.bEndpointAddress = USB_DIR_IN | 2; EP_IN_NAME = "ep2in"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 4; EP_OUT_NAME = "ep4out"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3in"; /* Intel SA-1100 processor, full speed only */ } else if (stat (DEVNAME = "sa1100", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0103), fs_source_desc.bEndpointAddress = USB_DIR_IN | 2; EP_IN_NAME = "ep2in-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1; EP_OUT_NAME = "ep1out-bulk"; source_sink_intf.bNumEndpoints = 2; ccid_desc.dwFeatures &= ~0x100000; // USB Wake up signaling not supported EP_STATUS_NAME = 0; #endif /* Toshiba TC86c001 PCI device, full speed only */ } else if (stat (DEVNAME = "goku_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0104), fs_source_desc.bEndpointAddress = USB_DIR_IN | 2; EP_IN_NAME = "ep2-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1; EP_OUT_NAME = "ep1-bulk"; source_sink_intf.bNumEndpoints = 3; EP_STATUS_NAME = "ep3-bulk"; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; /* Samsung S3C24xx series, full speed only */ } else if (stat (DEVNAME = "s3c2410_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0110), fs_source_desc.bEndpointAddress = USB_DIR_IN | 2; EP_IN_NAME = "ep2-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1; EP_OUT_NAME = "ep1-bulk"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3-bulk"; /* Renesas SH77xx processors, full speed only */ } else if (stat (DEVNAME = "sh_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0105), fs_source_desc.bEndpointAddress = USB_DIR_IN | 2; EP_IN_NAME = "ep2in-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1; EP_OUT_NAME = "ep1out-bulk"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3in-bulk"; /* OMAP 1610 and newer devices, full speed only, fifo mode 0 or 3 */ } else if (stat (DEVNAME = "omap_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0106), fs_source_desc.bEndpointAddress = USB_DIR_IN | 1; EP_IN_NAME = "ep1in-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 2; EP_OUT_NAME = "ep2out-bulk"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3in-int"; /* Something based on Mentor USB Highspeed Dual-Role Controller */ } else if (stat (DEVNAME = "musb_hdrc", &statb) == 0) { HIGHSPEED = 1; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0107), fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 1; EP_IN_NAME = "ep1in"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1; EP_OUT_NAME = "ep1out"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3"; /* Atmel AT91 processors, full speed only */ } else if (stat (DEVNAME = "at91_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0106), fs_source_desc.bEndpointAddress = USB_DIR_IN | 1; EP_IN_NAME = "ep1"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 2; EP_OUT_NAME = "ep2"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3-int"; /* Sharp LH740x processors, full speed only */ } else if (stat (DEVNAME = "lh740x_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0106), fs_source_desc.bEndpointAddress = USB_DIR_IN | 1; EP_IN_NAME = "ep1in-bulk"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 2; EP_OUT_NAME = "ep2out-bulk"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3in-int"; /* Atmel AT32AP700x processors, high/full speed */ } else if (stat (DEVNAME = "atmel_usba_udc", &statb) == 0) { HIGHSPEED = 1; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0108); fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 1; EP_IN_NAME = "ep1in-bulk"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 2; EP_OUT_NAME = "ep2out-bulk"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3in-int"; } else { DEVNAME = 0; return -ENODEV; } if (!doint) { source_sink_intf.bNumEndpoints = 2; int i; if (!doiintf) { for (i=0; i 1024) { interval = 0; bInterval = 1; /* "modprobe net2280 fifo_mode=1" may be needed */ if (bufsize > (2 * 1024)) { wMaxPacketSize = min ((bufsize + 2)/3, 1024); bufsize = min (3 * wMaxPacketSize, bufsize); wMaxPacketSize |= 2 << 11; } else { wMaxPacketSize = min ((bufsize + 1)/2, 1024); wMaxPacketSize |= 1 << 11; } } else { bInterval = interval + 4; wMaxPacketSize = bufsize; } fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 7; fs_source_desc.bmAttributes = hs_source_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_source_desc.wMaxPacketSize = min (bufsize, 1023); hs_source_desc.wMaxPacketSize = wMaxPacketSize; fs_source_desc.bInterval = interval + 1; hs_source_desc.bInterval = bInterval; EP_IN_NAME = "ep-a"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 3; fs_sink_desc.bmAttributes = hs_sink_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_sink_desc.wMaxPacketSize = min (bufsize, 1023); hs_sink_desc.wMaxPacketSize = wMaxPacketSize; fs_sink_desc.bInterval = interval + 1; hs_sink_desc.bInterval = bInterval; EP_OUT_NAME = "ep-b"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 11; EP_STATUS_NAME = "ep-f"; /* Intel PXA 2xx processor, full speed only */ } else if (stat (DEVNAME = "pxa2xx_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0101), bufsize = min (bufsize, 256); fs_source_desc.bEndpointAddress = USB_DIR_IN | 3; fs_source_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_source_desc.wMaxPacketSize = bufsize; fs_source_desc.bInterval = interval; EP_IN_NAME = "ep3in-iso"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 4; fs_sink_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_sink_desc.wMaxPacketSize = bufsize; fs_sink_desc.bInterval = interval; EP_OUT_NAME = "ep4out-iso"; /* using bulk for this since the pxa interrupt endpoints * always use the no-toggle scheme (discouraged). */ source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 11; EP_STATUS_NAME = "ep11in-bulk"; /* OMAP 1610 and newer devices, full speed only, fifo mode 3 */ } else if (stat (DEVNAME = "omap_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0102), fs_source_desc.bEndpointAddress = USB_DIR_IN | 7; fs_source_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_source_desc.wMaxPacketSize = min (bufsize, 256); fs_source_desc.bInterval = interval; EP_IN_NAME = "ep7in-iso"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 8; fs_sink_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_sink_desc.wMaxPacketSize = min (bufsize, 256); fs_sink_desc.bInterval = interval; EP_OUT_NAME = "ep8out-iso"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 9; EP_STATUS_NAME = "ep9in-int"; /* Something based on Mentor USB Highspeed Dual-Role Controller; * assumes a core that doesn't include high bandwidth support. */ } else if (stat (DEVNAME = "musb_hdrc", &statb) == 0) { unsigned bInterval, wMaxPacketSize; HIGHSPEED = 1; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0103); bInterval = interval + 4; wMaxPacketSize = bufsize; fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 1; fs_source_desc.bmAttributes = hs_source_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_source_desc.wMaxPacketSize = min (bufsize, 1023); hs_source_desc.wMaxPacketSize = wMaxPacketSize; fs_source_desc.bInterval = interval + 1; hs_source_desc.bInterval = bInterval; EP_IN_NAME = "ep1in"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 1; fs_sink_desc.bmAttributes = hs_sink_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_sink_desc.wMaxPacketSize = min (bufsize, 1023); hs_sink_desc.wMaxPacketSize = wMaxPacketSize; fs_sink_desc.bInterval = interval + 1; hs_sink_desc.bInterval = bInterval; EP_OUT_NAME = "ep1out"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 11; EP_STATUS_NAME = "ep3"; /* Atmel AT91 processors, full speed only */ } else if (stat (DEVNAME = "at91_udc", &statb) == 0) { HIGHSPEED = 0; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0104), fs_source_desc.bEndpointAddress = USB_DIR_IN | 4; fs_source_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_source_desc.wMaxPacketSize = min (bufsize, 256); fs_source_desc.bInterval = interval; EP_IN_NAME = "ep4"; fs_sink_desc.bEndpointAddress = USB_DIR_OUT | 2; fs_sink_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_sink_desc.wMaxPacketSize = min (bufsize, 256); fs_sink_desc.bInterval = interval; EP_OUT_NAME = "ep5"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3-int"; /* Atmel AT32AP700x processors, high/full speed */ } else if (stat (DEVNAME = "atmel_usba_udc", &statb) == 0){ HIGHSPEED = 1; device_desc.bcdDevice = __constant_cpu_to_le16 (0x0105); fs_source_desc.bEndpointAddress = hs_source_desc.bEndpointAddress = USB_DIR_IN | 5; fs_source_desc.bmAttributes = hs_source_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_source_desc.wMaxPacketSize = hs_source_desc.wMaxPacketSize = __cpu_to_le16(min (bufsize, 1024)); fs_source_desc.bInterval = hs_source_desc.bInterval = interval; EP_IN_NAME = "ep5in-iso"; fs_sink_desc.bEndpointAddress = hs_sink_desc.bEndpointAddress = USB_DIR_OUT | 6; fs_sink_desc.bmAttributes = hs_sink_desc.bmAttributes = USB_ENDPOINT_XFER_ISOC; fs_sink_desc.wMaxPacketSize = hs_sink_desc.wMaxPacketSize = __cpu_to_le16(min (bufsize, 1024)); fs_sink_desc.bInterval = hs_sink_desc.bInterval = interval; EP_OUT_NAME = "ep6out-iso"; source_sink_intf.bNumEndpoints = 3; fs_status_desc.bEndpointAddress = hs_status_desc.bEndpointAddress = USB_DIR_IN | 3; EP_STATUS_NAME = "ep3in-int"; } else { DEVNAME = 0; return -ENODEV; } if (verbose) { fprintf (stderr, "iso fs wMaxPacket %04x bInterval %02x\n", __le16_to_cpu(fs_sink_desc.wMaxPacketSize), fs_sink_desc.bInterval); if (HIGHSPEED) fprintf (stderr, "iso hs wMaxPacket %04x bInterval %02x\n", __le16_to_cpu(hs_sink_desc.wMaxPacketSize), hs_sink_desc.bInterval); } return 0; } #else #define iso 0 #endif /* AIO */ /*-------------------------------------------------------------------------*/ /* full duplex data, with at least three threads: ep0, sink, and source */ static pthread_t ep0; static pthread_t ccid_thread; static pthread_t interrupt_thread; static int source_fd = -1; static int sink_fd = -1; static int status_fd = -1; // FIXME no result i/o yet static void close_fd (void *fd_ptr) { int result, fd; fd = *(int *)fd_ptr; *(int *)fd_ptr = -1; /* test the FIFO ioctls (non-ep0 code paths) */ if (pthread_self () != ep0) { result = ioctl (fd, GADGETFS_FIFO_STATUS); if (result < 0) { /* ENODEV reported after disconnect */ if (errno != ENODEV && errno != EOPNOTSUPP) perror ("get fifo result"); } else { fprintf (stderr, "fd %d, unclaimed = %d\n", fd, result); if (result) { result = ioctl (fd, GADGETFS_FIFO_FLUSH); if (result < 0) perror ("fifo flush"); } } } if (close (fd) < 0) perror ("close fd"); else if (debug) fprintf (stderr, "closed fd\n"); } static void close_ccid() { ccid_shutdown(); } /* you should be able to open and configure endpoints * whether or not the host is connected */ static int ep_config (char *name, const char *label, struct usb_endpoint_descriptor *fs, struct usb_endpoint_descriptor *hs ) { int fd, result; char buf [USB_BUFSIZE]; /* open and initialize with endpoint descriptor(s) */ fd = open (name, O_RDWR); if (fd < 0) { result = -errno; fprintf (stderr, "%s open %s error %d (%s)\n", label, name, errno, strerror (errno)); return result; } /* one (fs or ls) or two (fs + hs) sets of config descriptors */ *(__u32 *)buf = 1; /* tag for this format */ memcpy (buf + 4, fs, USB_DT_ENDPOINT_SIZE); if (HIGHSPEED) memcpy (buf + 4 + USB_DT_ENDPOINT_SIZE, hs, USB_DT_ENDPOINT_SIZE); result = write (fd, buf, 4 + USB_DT_ENDPOINT_SIZE + (HIGHSPEED ? USB_DT_ENDPOINT_SIZE : 0)); if (result < 0) { result = -errno; fprintf (stderr, "%s config %s error %d (%s)\n", label, name, errno, strerror (errno)); close (fd); return result; } else if (verbose > 1) { unsigned long id; id = pthread_self (); fprintf (stderr, "%s (%ld): fd %d\n", label, id, fd); } return fd; } #define source_open(name) \ ep_config(name,__FUNCTION__, &fs_source_desc, &hs_source_desc) #define sink_open(name) \ ep_config(name,__FUNCTION__, &fs_sink_desc, &hs_sink_desc) #define status_open(name) \ ep_config(name,__FUNCTION__, &fs_status_desc, &hs_status_desc) static void *interrupt (void *param) { status_fd = status_open (((char **) param)[0]); if (source_fd < 0) { /* an error concerning status endpoint is not fatal for in/out bulk*/ /* transfer */ if (verbose > 1) perror("status_fd"); pthread_exit(0); } pthread_cleanup_push (close_fd, &status_fd); int result = 0; RDR_to_PC_NotifySlotChange_t *slotchange; do { /* original LinuxThreads cancelation didn't work right */ /* so test for it explicitly. */ pthread_testcancel (); if (ccid_state_changed(&slotchange, -1)) { /* don't bother host, when nothing changed */ if (verbose > 1) fprintf(stderr, "interrupt loop: writing RDR_to_PC_NotifySlotChange... "); result = write(status_fd, slotchange, sizeof *slotchange); if (verbose > 1) fprintf(stderr, "done (%d written).\n", result); } } while (result >= 0); if (errno != ESHUTDOWN || result < 0) { perror ("interrupt loop aborted"); pthread_cancel(ep0); } pthread_cleanup_pop (1); fflush (stdout); fflush (stderr); return 0; } /* ccid thread, forwards ccid requests to pcsc and returns results */ static void *ccid (void *param) { char **names = (char **) param; char *source_name = names[0]; char *sink_name = names[1]; int result; size_t bufsize = sizeof(PC_to_RDR_XfrBlock_t) + CCID_EXT_APDU_MAX; __u8 inbuf[bufsize]; source_fd = source_open (source_name); if (source_fd < 0) { if (verbose > 1) perror("source_fd"); goto error; } pthread_cleanup_push (close_fd, &source_fd); sink_fd = sink_open (sink_name); if (sink_fd < 0) { if (verbose > 1) perror("sink_fd"); goto error; } pthread_cleanup_push (close_fd, &sink_fd); pthread_cleanup_push (close_ccid, NULL); __u8 *outbuf = NULL; pthread_cleanup_push (free, outbuf); do { /* original LinuxThreads cancelation didn't work right * so test for it explicitly. */ pthread_testcancel (); if (verbose > 1) fprintf(stderr, "bulk loop: reading %lu bytes... ", (long unsigned) bufsize); result = read(sink_fd, inbuf, bufsize); if (result < 0) break; if (verbose > 1) fprintf(stderr, "bulk loop: got %d, done.\n", result); if (!result) break; result = ccid_parse_bulkout(inbuf, result, &outbuf); if (result < 0) break; if (verbose > 1) fprintf(stderr, "bulk loop: writing %d bytes... ", result); result = write(source_fd, outbuf, result); if (verbose > 1) fprintf(stderr, "done (%d written).\n", result); } while (result >= 0); if (errno != ESHUTDOWN || result < 0) { perror ("ccid loop aborted"); pthread_cancel(ep0); } pthread_cleanup_pop (1); pthread_cleanup_pop (1); pthread_cleanup_pop (1); pthread_cleanup_pop (1); fflush (stdout); fflush (stderr); return 0; error: pthread_cancel(ep0); pthread_exit(0); } static void start_io (void) { //int tmp; sigset_t allsig, oldsig; #ifdef AIO /* iso uses the same API as bulk/interrupt. we queue one * (u)frame's worth of data per i/o request, and the host * polls that queue once per interval. */ switch (current_speed) { case USB_SPEED_FULL: if (iso) iosize = __le16_to_cpup (&fs_source_desc .wMaxPacketSize); else iosize = bufsize; break; case USB_SPEED_HIGH: /* for iso, we updated bufsize earlier */ iosize = bufsize; break; default: fprintf (stderr, "bogus link speed %d\n", current_speed); return; } #endif /* AIO */ sigfillset (&allsig); errno = pthread_sigmask (SIG_SETMASK, &allsig, &oldsig); if (errno < 0) { perror ("set thread signal mask"); return; } /* is it true that the LSB requires programs to disconnect * from their controlling tty before pthread_create()? * why? this clearly doesn't ... */ static char *names[2]; names[0] = EP_IN_NAME; names[1] = EP_OUT_NAME; if (pthread_create (&ccid_thread, NULL, ccid, (void *) names) != 0) { perror ("can't create ccid thread"); goto cleanup; } if (doint) { static char * interruptnames[1]; interruptnames[0] = EP_STATUS_NAME; if (pthread_create (&interrupt_thread, NULL, interrupt, (void *) interruptnames) != 0) { perror ("can't create interrupt thread"); goto cleanup; } } else if (verbose) { fprintf (stderr, "interrupt pipe disabled\n"); } /* give the other threads a chance to run before we report * success to the host. * FIXME better yet, use pthread_cond_timedwait() and * synchronize on ep config success. */ sched_yield (); cleanup: errno = pthread_sigmask (SIG_SETMASK, &oldsig, 0); if (errno != 0) { perror ("restore sigmask"); exit (-1); } } static void stop_io () { if (!pthread_equal (ccid_thread, ep0)) { pthread_cancel (ccid_thread); if (pthread_join (ccid_thread, 0) != 0) perror ("can't join ccid thread"); ccid_thread = ep0; fprintf (stderr, "cancled ccid\n"); } if (!pthread_equal (interrupt_thread, ep0)) { pthread_cancel (interrupt_thread); if (pthread_join (interrupt_thread, 0) != 0) perror ("can't join interrupt thread"); interrupt_thread = ep0; fprintf (stderr, "cancled interrupt\n"); } } /*-------------------------------------------------------------------------*/ static char * build_config (char *cp, const struct usb_endpoint_descriptor **ep) { struct usb_config_descriptor *c; int i; c = (struct usb_config_descriptor *) cp; memcpy (cp, &config, config.bLength); cp += config.bLength; memcpy (cp, &source_sink_intf, sizeof source_sink_intf); cp += sizeof source_sink_intf; // Append vendor class specification memcpy (cp, &ccid_desc, sizeof ccid_desc); cp += sizeof ccid_desc; for (i = 0; i < source_sink_intf.bNumEndpoints; i++) { memcpy (cp, ep [i], USB_DT_ENDPOINT_SIZE); cp += USB_DT_ENDPOINT_SIZE; } c->wTotalLength = __cpu_to_le16 (cp - (char *) c); return cp; } static int init_device (void) { char buf [4096], *cp = &buf [0]; int fd; int result; #ifdef AIO if (iso) result = iso_autoconfig (); else #endif result = autoconfig (); if (result < 0) { fprintf (stderr, "?? don't recognize %s %s device\n", gadgetfs, iso ? "iso" : "bulk"); return result; } fd = open (DEVNAME, O_RDWR); if (fd < 0) { perror (DEVNAME); return -errno; } *(__u32 *)cp = 0; /* tag for this format */ cp += 4; /* write full then high speed configs */ cp = build_config (cp, fs_eps); if (HIGHSPEED) cp = build_config (cp, hs_eps); device_desc.idVendor = __cpu_to_le16 (vendorid); device_desc.idProduct = __cpu_to_le16 (productid); if (verbose) { fprintf(stderr, "idVendor=%04X idProduct=%04X\n", vendorid, productid); } /* and device descriptor at the end */ memcpy (cp, &device_desc, sizeof device_desc); cp += sizeof device_desc; result = write (fd, &buf [0], cp - &buf [0]); if (result < 0) { perror ("write dev descriptors"); close (fd); return result; } else if (result != (cp - buf)) { fprintf (stderr, "dev init, wrote %d expected %ld\n", result, (long int) (cp - buf)); close (fd); return -EIO; } return fd; } static void handle_control (int fd, struct usb_ctrlrequest *setup) { int result, tmp; __u8 buf [256]; __u16 value, index, length; value = __le16_to_cpu(setup->wValue); index = __le16_to_cpu(setup->wIndex); length = __le16_to_cpu(setup->wLength); if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) goto special; switch (setup->bRequest) { /* usb 2.0 spec ch9 requests */ case USB_REQ_GET_DESCRIPTOR: if (verbose > 1) fprintf(stderr, "USB_REQ_GET_DESCRIPTOR\n"); if (setup->bRequestType != USB_DIR_IN) goto stall; switch (value >> 8) { case USB_DT_STRING: tmp = value & 0x0ff; if (verbose > 1) fprintf (stderr, "... get string %d lang %04x\n", tmp, index); if (tmp != 0 && index != strings.language) { fprintf (stderr, "wrong language, returning defaults\n"); tmp = 0; } memset (buf, 0, 256); /* zero all the bytes */ result = usb_gadget_get_string (&strings, tmp, buf); if (result < 0) { perror("usb_gadget_get_string"); goto stall; } tmp = result; if (length < tmp) tmp = length; result = write (fd, buf, tmp); if (result < 0) { if (errno == EIDRM) fprintf (stderr, "string timeout\n"); else perror ("write string data"); } else if (result != tmp) { fprintf (stderr, "short string write, %d\n", result); } break; default: goto stall; } return; case USB_REQ_SET_CONFIGURATION: if (verbose > 1) fprintf (stderr, "USB_REQ_SET_CONFIGURATION #%d\n", value); if (setup->bRequestType != USB_DIR_OUT) goto stall; /* Kernel is normally waiting for us to finish reconfiguring * the device. * * Some hardware can't, notably older PXA2xx hardware. (With * racey and restrictive config change automagic. PXA 255 is * OK, most PXA 250s aren't. If it has a UDC CFR register, * it can handle deferred response for SET_CONFIG.) To handle * such hardware, don't write code this way ... instead, keep * the endpoints always active and don't rely on seeing any * config change events, either this or SET_INTERFACE. */ switch (value) { case CONFIG_VALUE: if ( source_fd >= 0 || sink_fd >= 0 || status_fd >= 0) stop_io (); start_io (); break; case 0: stop_io (); break; default: /* kernel bug -- "can't happen" */ fprintf (stderr, "? illegal config\n"); goto stall; } /* ... ack (a write would stall) */ result = read (fd, &result, 0); if (result) perror ("ack SET_CONFIGURATION"); return; case USB_REQ_GET_INTERFACE: if (verbose > 1) fprintf (stderr, "USB_REQ_GET_INTERFACE\n"); if (setup->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE) || index != 0 || length > 1) goto stall; /* only one altsetting in this driver */ buf [0] = 0; result = write (fd, buf, length); if (result < 0) { if (errno == EIDRM) fprintf (stderr, "GET_INTERFACE timeout\n"); else perror ("write GET_INTERFACE data"); } else if (result != length) { fprintf (stderr, "short GET_INTERFACE write, %d\n", result); } return; case USB_REQ_SET_INTERFACE: if (verbose > 1) fprintf (stderr, "USB_REQ_SET_INTERFACE\n"); if (setup->bRequestType != USB_RECIP_INTERFACE || index != 0 || value != 0) goto stall; /* just reset toggle/halt for the interface's endpoints */ result = 0; if (ioctl (source_fd, GADGETFS_CLEAR_HALT) < 0) { result = errno; perror ("reset source fd"); } if (ioctl (sink_fd, GADGETFS_CLEAR_HALT) < 0) { result = errno; perror ("reset sink fd"); } if (status_fd > 0) { if (ioctl (status_fd, GADGETFS_CLEAR_HALT) < 0) { result = errno; perror ("reset status fd"); } } /* FIXME eventually reset the result endpoint too */ if (result) goto stall; /* ... and ack (a write would stall) */ result = read (fd, &result, 0); if (result) perror ("ack SET_INTERFACE"); return; default: goto stall; } special: switch (setup->bRequestType) { case USB_REQ_CCID: { __u8 *outbuf = NULL; result = ccid_parse_control(setup, &outbuf); if (result < 0 || result > 256) goto stall; if (verbose > 1) fprintf(stderr, "control loop: writing %d bytes... ", result); result = write (fd, outbuf, result); /* TODO outbuf should also be freed on error */ free(outbuf); if (result < 0) goto stall; if (verbose > 1) fprintf(stderr, "done (%d written).\n", result); } return; default: goto stall; } stall: if (verbose) { fprintf (stderr, "... protocol stall %02x.%02x\n", setup->bRequestType, setup->bRequest); for (tmp = 0; tmp<5; tmp++) { printf("%d: %s\n", stringtab[tmp].id, stringtab[tmp].s); } } /* non-iso endpoints are stalled by issuing an i/o request * in the "wrong" direction. ep0 is special only because * the direction isn't fixed. */ if (setup->bRequestType & USB_DIR_IN) result = read (fd, &result, 0); else result = write (fd, &result, 0); if (result != -1) fprintf (stderr, "can't stall ep0 for %02x.%02x\n", setup->bRequestType, setup->bRequest); else if (errno != EL2HLT) perror ("ep0 stall"); } static void signothing (int sig, siginfo_t *info, void *ptr) { unsigned int seconds = 4; switch (sig) { case SIGQUIT: seconds /= 2; case SIGINT: if (verbose > 1) fprintf (stderr, "\nInitializing shutdown, " "waiting %d seconds for threads to terminate\n", seconds); pthread_cancel(ep0); sleep(seconds); fprintf (stderr, "Doing immediate shutdown.\n"); exit(1); break; default: if (verbose > 1) fprintf (stderr, "Received unhandled signal %u\n", sig); } } static const char *speed (enum usb_device_speed s) { switch (s) { case USB_SPEED_LOW: return "low speed"; case USB_SPEED_FULL: return "full speed"; case USB_SPEED_HIGH: return "high speed"; default: return "UNKNOWN speed"; } } /*-------------------------------------------------------------------------*/ /* control thread, handles main event loop */ #define NEVENT 5 #define LOGDELAY (15 * 60) /* seconds before stdout timestamp */ static void *ep0_thread (void *param) { int fd = *(int*) param; struct sigaction action; time_t now, last; struct pollfd ep0_poll; interrupt_thread = ccid_thread = ep0 = pthread_self (); pthread_cleanup_push (stop_io, NULL); pthread_cleanup_push (close_fd, param); /* REVISIT signal handling ... normally one pthread should * be doing sigwait() to handle all async signals. */ action.sa_sigaction = signothing; sigfillset (&action.sa_mask); action.sa_flags = SA_SIGINFO; if (sigaction (SIGINT, &action, NULL) < 0) { perror ("SIGINT"); return 0; } if (sigaction (SIGQUIT, &action, NULL) < 0) { perror ("SIGQUIT"); return 0; } ep0_poll.fd = fd; ep0_poll.events = POLLIN | POLLOUT | POLLHUP; /* event loop */ last = 0; for (;;) { int tmp; struct usb_gadgetfs_event event [NEVENT]; int connected = 0; int i, nevent; /* Use poll() to test that mechanism, to generate * activity timestamps, and to make it easier to * tweak this code to work without pthreads. When * AIO is needed without pthreads, ep0 can be driven * instead using SIGIO. */ tmp = poll(&ep0_poll, 1, -1); if (verbose) { time (&now); if ((now - last) > LOGDELAY) { char timebuf[26]; last = now; ctime_r (&now, timebuf); printf ("\n** %s", timebuf); } } if (tmp < 0) { /* exit path includes EINTR exits */ perror("poll"); break; } tmp = read (fd, &event, sizeof event); if (tmp < 0) { if (errno == EAGAIN) { sleep (1); continue; } perror ("ep0 read after poll"); goto done; } nevent = tmp / sizeof event [0]; if (nevent != 1 && verbose > 1) fprintf (stderr, "read %d ep0 events\n", nevent); for (i = 0; i < nevent; i++) { switch (event [i].type) { case GADGETFS_NOP: if (verbose) fprintf (stderr, "NOP\n"); break; case GADGETFS_CONNECT: connected = 1; current_speed = event [i].u.speed; if (verbose) fprintf (stderr, "CONNECT %s\n", speed (event [i].u.speed)); break; case GADGETFS_SETUP: connected = 1; handle_control (fd, &event [i].u.setup); break; case GADGETFS_DISCONNECT: connected = 0; current_speed = USB_SPEED_UNKNOWN; if (verbose) fprintf(stderr, "DISCONNECT\n"); stop_io (); break; case GADGETFS_SUSPEND: // connected = 1; if (verbose) fprintf (stderr, "SUSPEND\n"); break; default: fprintf (stderr, "* unhandled event %d\n", event [i].type); } } continue; done: fflush (stdout); if (connected) stop_io (); break; } if (verbose) fprintf (stderr, "ep0 done.\n"); pthread_cleanup_pop (1); pthread_cleanup_pop (1); fflush (stdout); fflush (stderr); return 0; } int main (int argc, char **argv) { /*printf("%s:%d\n", __FILE__, __LINE__);*/ int fd, c, i; struct gengetopt_args_info cmdline; /* Parse command line */ if (cmdline_parser (argc, argv, &cmdline) != 0) exit(1); doiintf = cmdline.interface_arg; productid = cmdline.product_arg; vendorid = cmdline.vendor_arg; verbose = cmdline.verbose_given; doint = cmdline.interrupt_flag; gadgetfs = cmdline.gadgetfs_arg; if (cmdline.info_flag) return print_avail(verbose); if (ccid_initialize(cmdline.reader_arg, verbose) < 0) { fprintf (stderr, "Can't initialize ccid\n"); return 1; } if (chdir (gadgetfs) < 0) { fprintf (stderr, "Error changing directory to %s\n", gadgetfs); return 1; } if (strncmp(cmdline.serial_arg, "random", strlen("random")) == 0) { /* random initial serial number */ srand ((int) time (0)); for (i = 0; i < sizeof serial - 1; ) { c = rand () % 127; if ((('a' <= c && c <= 'z') || ('0' <= c && c <= '9'))) serial [i++] = c; } if (verbose) fprintf (stderr, "serial=\"%s\"\n", serial); } else { for (i=0; i. */ /** * @file */ #ifndef _CCID_TYPES_H #define _CCID_TYPES_H #include #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 vsmartcard-3.3/ccid/src/ccid.h0000644000175000017500000000562013546304763014761 0ustar philphil/* * 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 . */ /** * @file */ #ifndef _CCID_H #define _CCID_H #include #include #include "ccid-types.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Initializes reader for relaying * * @param[in] reader_id (optional) Index to the reader to be used. Set to -1 to use the first reader with a card or the first reader if no card is available. * @param[in] verbose Verbosity level passed to \c sc_context_t * * @return \c SC_SUCCESS or error code if an error occurred */ int ccid_initialize(int reader_id, int verbose); /** * @brief Disconnects from card, reader and releases allocated memory */ void ccid_shutdown(void); /** * @brief Parses input from PC and generates the appropriate RDR response * * Parses command pipe bulk-OUT messages and generates resoponse pipe bulk-IN * messages according to CCID Rev 1.1 section 6.1, 6.2 * * @param[in] inbuf input buffer (command pipe bulk-OUT message) * @param[in] inlen length of \a inbuf * @param[in,out] outbuf where to save the output buffer (resoponse pipe bulk-IN message), memory is reused via \c realloc() * * @return length of \a outbuf or -1 if an error occurred */ int ccid_parse_bulkout(const __u8* inbuf, size_t inlen, __u8** outbuf); /** * @brief Parses input from control pipe and generates the appropriate response * * Parses CCID class-specific requests according to CCID Rev 1.1 section 5.3 * * @param[in] setup input from control pipe * @param[in,out] outbuf where to save the output buffer, memory is reused via \c realloc() * * @return length of \a outbuf or -1 if an error occurred */ int ccid_parse_control(struct usb_ctrlrequest *setup, __u8 **outbuf); /** * @brief Generates event messages * * @param[in,out] slotchange where to save the output * @param[in] timeout currently not used * @note ccid_state_changed() must be called periodically. Because the OpenSC implementation of \c sc_wait_for_event() blocks all other operations with the reader, it can't be used for slot state detection. * * @return 1 if a card is present and/or the state is changed or 0 */ int ccid_state_changed(RDR_to_PC_NotifySlotChange_t **slotchange, int timeout); #ifdef __cplusplus } #endif #endif vsmartcard-3.3/ccid/src/Makefile.am0000644000175000017500000000264513546304763015746 0ustar philphildo_subst = $(SED) \ -e 's,[@]PACKAGE[@],$(PACKAGE),g' \ -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \ -e 's,[@]PACKAGE_TARNAME[@],$(PACKAGE_TARNAME),g' \ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \ -e 's,[@]PACKAGE_SUMMARY[@],$(PACKAGE_SUMMARY),g' \ -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' 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 = ccid.c usbstring.c usb.c scutil.c $(BUILT_SOURCES) ccid_emulator_LDADD = $(OPENSC_LIBS) $(OPENSSL_LIBS) $(PTHREAD_LIBS) ccid_emulator_CFLAGS = $(OPENSSL_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_srcdir)/src/OpenSC/src ccid-emulator.c: $(BUILT_SOURCES) $(BUILT_SOURCES): ccid-emulator.ggo $(GENGETOPT) --output-dir=$(srcdir) < $< ccid-emulator.ggo: ccid-emulator.ggo.in $(do_subst) < $< > $(srcdir)/$@ ccid-emulator.1: $(HELP2MAN) \ --output=$@ \ --no-info \ --source='$(PACKAGE_STRING)' \ --version-string='$(PACKAGE) $(VERSION)' \ $(builddir)/ccid-emulator bin_PROGRAMS = ccid-emulator noinst_HEADERS = \ ccid.h \ ccid-types.h \ scutil.h \ usbstring.h vsmartcard-3.3/ccid/src/ccid-emulator.ggo.in0000644000175000017500000000207013546304763017535 0ustar philphilpurpose "@PACKAGE_SUMMARY@" option "info" i "Print available readers and drivers." flag off option "reader" r "Number of the PC/SC reader to use (-1 for autodetect)" int default="-1" optional option "gadgetfs" - "Directory where GadgetFS is mounted" string typestr="FILENAME" default="/dev/gadget" optional option "verbose" v "Use (several times) to be more verbose" multiple optional section "Changing the appearance on the Universal Serial Bus" option "product" p "USB product ID" int default="0x3010" optional option "vendor" e "USB vendor ID" int default="0x0D46" optional option "serial" - "USB serial number" string default="random" optional option "interface" - "USB serial number" string default="notification status" optional option "interrupt" - "Add interrupt pipe for CCID" flag off text " Report bugs to @PACKAGE_BUGREPORT@ Written by Frank Morgner " vsmartcard-3.3/ccid/src/scutil.c0000644000175000017500000001230413546304763015352 0ustar philphil/* * Copyright (C) 2010 Frank Morgner * * This file is part of libnpa. * * libnpa 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. * * libnpa 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 * libnpa. If not, see . */ #ifdef HAVE_CONFIG_H #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 #include #include #include int initialize(int reader_id, int verbose, sc_context_t **ctx, sc_reader_t **reader) { unsigned int i, reader_count; if (!ctx || !reader) return SC_ERROR_INVALID_ARGUMENTS; int r = sc_establish_context(ctx, ""); if (r < 0 || !*ctx) { fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); return r; } (*ctx)->debug = verbose; (*ctx)->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; reader_count = sc_ctx_get_reader_count(*ctx); if (reader_count == 0) { sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No reader not found.\n"); return SC_ERROR_NO_READERS_FOUND; } if (reader_id < 0) { /* 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) & SC_READER_CARD_PRESENT) { reader_id = i; 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, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader."); reader_id = 0; } } if (reader_id >= reader_count) { sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Invalid reader number " "(%d), only %d available.\n", reader_id, reader_count); return SC_ERROR_NO_READERS_FOUND; } *reader = sc_ctx_get_reader(*ctx, reader_id); return SC_SUCCESS; } void _bin_log(sc_context_t *ctx, int type, const char *file, int line, const char *func, const char *label, const u8 *data, size_t len, FILE *f) { if (!f) { char buf[1800]; if (data) sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, data, len, buf, sizeof buf); else buf[0] = 0; sc_do_log(ctx, type, file, line, func, "\n%s (%u byte%s)%s%s", label, (unsigned int) len, len==1?"":"s", len==0?"":":\n", buf); } else { fprintf(f, "%s (%u byte%s)%s%s\n", label, (unsigned int) len, len==1?"":"s", len==0?"":":\n", sc_dump_hex(data, len)); } } static int list_readers(sc_context_t *ctx) { char card_atr[0x3e]; sc_card_t *card; sc_reader_t *reader; size_t i, rcount = sc_ctx_get_reader_count(ctx); if (rcount == 0) { printf("No smart card readers found.\n"); return 0; } printf("%-4s %-7s %s\n", "Nr.", "Driver", "Smart Card Reader"); for (i = 0; i < rcount; i++) { reader = sc_ctx_get_reader(ctx, i); memset(card_atr, '\0', sizeof card_atr); if (sc_detect_card_presence(reader) & SC_READER_CARD_PRESENT) { if (sc_connect_card(reader, &card) == SC_SUCCESS) { sc_bin_to_hex(card->atr.value, card->atr.len, card_atr, sizeof card_atr, ':'); } sc_disconnect_card(card); } else { strncpy(card_atr, "[no card present]", sizeof card_atr); } printf("%-4zu %-7s %s\n", i, reader->driver->short_name, reader->name); printf(" ATR: %s\n", card_atr); } return 0; } int print_avail(int verbose) { sc_context_t *ctx = NULL; int r; r = sc_establish_context(&ctx, ""); if (r) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } ctx->debug = verbose; ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; r = list_readers(ctx); sc_release_context(ctx); return r; } vsmartcard-3.3/ccid/src/OpenSC/0000755000175000017500000000000013546304763015032 5ustar philphilvsmartcard-3.3/ccid/src/usbstring.c0000644000175000017500000000670113546304763016073 0ustar philphil/* * Copyright (C) 2003 David Brownell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include "usbstring.h" static inline void put_unaligned_le16(__u16 val, __u16 *cp) { __u8 *p = (void *)cp; *p++ = (__u8) val; *p++ = (__u8) (val >> 8); } static int utf8_to_utf16le(const char *s, __u16 *cp, unsigned len) { int count = 0; __u8 c; __u16 uchar; /* this insists on correct encodings, though not minimal ones. * BUT it currently rejects legit 4-byte UTF-8 code points, * which need surrogate pairs. (Unicode 3.1 can use them.) */ while (len != 0 && (c = (__u8) *s++) != 0) { if (c & 0x80) { // 2-byte sequence: // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx if ((c & 0xe0) == 0xc0) { uchar = (c & 0x1f) << 6; c = (__u8) *s++; if ((c & 0xc0) != 0xc0) goto fail; c &= 0x3f; uchar |= c; // 3-byte sequence (most CJKV characters): // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx } else if ((c & 0xf0) == 0xe0) { uchar = (c & 0x0f) << 12; c = (__u8) *s++; if ((c & 0xc0) != 0xc0) goto fail; c &= 0x3f; uchar |= c << 6; c = (__u8) *s++; if ((c & 0xc0) != 0xc0) goto fail; c &= 0x3f; uchar |= c; /* no bogus surrogates */ if (0xd800 <= uchar && uchar <= 0xdfff) goto fail; // 4-byte sequence (surrogate pairs, currently rare): // 11101110wwwwzzzzyy + 110111yyyyxxxxxx // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx // (uuuuu = wwww + 1) // FIXME accept the surrogate code points (only) } else goto fail; } else uchar = c; put_unaligned_le16 (uchar, cp++); count++; len--; } return count; fail: return -1; } /** * usb_gadget_get_string - fill out a string descriptor * @table: of c strings encoded using UTF-8 * @id: string id, from low byte of wValue in get string descriptor * @buf: at least 256 bytes * * Finds the UTF-8 string matching the ID, and converts it into a * string descriptor in utf16-le. * Returns length of descriptor (always even) or negative errno * * If your driver needs strings in multiple languages, you'll probably * "switch (wIndex) { ... }" in your ep0 string descriptor logic, * using this routine after choosing which set of UTF-8 strings to use. * * Note that US-ASCII is a strict subset of UTF-8; any string bytes with * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 * characters. */ int usb_gadget_get_string (struct usb_gadget_strings *table, int id, __u8 *buf) { struct usb_string *s; int len; /* descriptor 0 has the language id */ if (id == 0) { buf [0] = 4; buf [1] = USB_DT_STRING; buf [2] = (__u8) table->language; buf [3] = (__u8) (table->language >> 8); return 4; } for (s = table->strings; s && s->s; s++) { if (s->id == id) break; } /* unrecognized: stall. */ if (!s || !s->s) return -EINVAL; /* string descriptors have length, tag, then UTF16-LE text */ len = strlen (s->s); if (len > 126) len = 126; memset (buf + 2, 0, 2 * len); /* zero all the bytes */ len = utf8_to_utf16le(s->s, (__u16 *)&buf[2], len); if (len < 0) return -EINVAL; buf [0] = (len + 1) * 2; buf [1] = USB_DT_STRING; return buf [0]; } vsmartcard-3.3/ccid/src/ccid.c0000644000175000017500000016245513546304763014766 0ustar philphil/* * 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ccid.h" #include "config.h" #include "scutil.h" #ifndef HAVE_BOXING_BUF_TO_PACE_INPUT #include #endif static sc_context_t *ctx = NULL; static sc_card_t *card = NULL; static sc_reader_t *reader = NULL; static int perform_pseudo_apdu_EstablishPACEChannel(sc_apdu_t *apdu) { struct establish_pace_channel_input pace_input; struct establish_pace_channel_output pace_output; int r; memset(&pace_input, 0, sizeof pace_input); memset(&pace_output, 0, sizeof pace_output); r = boxing_buf_to_pace_input(reader->ctx, apdu->data, apdu->datalen, &pace_input); if (r < 0) goto err; r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); if (r < 0) goto err; r = boxing_pace_output_to_buf(reader->ctx, &pace_output, &apdu->resp, &apdu->resplen); err: free((unsigned char *) pace_input.chat); free((unsigned char *) pace_input.certificate_description); free((unsigned char *) pace_input.pin); free(pace_output.ef_cardaccess); free(pace_output.recent_car); free(pace_output.previous_car); free(pace_output.id_icc); free(pace_output.id_pcd); return r; } static int perform_pseudo_apdu_GetReaderPACECapabilities(sc_apdu_t *apdu) { unsigned long sc_reader_t_capabilities = SC_READER_CAP_PACE_GENERIC | SC_READER_CAP_PACE_EID | SC_READER_CAP_PACE_ESIGN; return boxing_pace_capabilities_to_buf(reader->ctx, sc_reader_t_capabilities, &apdu->resp, &apdu->resplen); } static int perform_PC_to_RDR_GetSlotStatus(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen); static int perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen); static int perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen); static int perform_pseudo_apdu(sc_reader_t *reader, sc_apdu_t *apdu); static int perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outlen); static int perform_PC_to_RDR_GetParamters(const __u8 *in, size_t inlen, __u8** out, size_t *outlen); static int perform_PC_to_RDR_Secure_EstablishPACEChannel(sc_card_t *card, const __u8 *abData, size_t abDatalen, __u8 **abDataOut, size_t *abDataOutLen); static int perform_PC_to_RDR_Secure_GetReadersPACECapabilities(__u8 **abDataOut, size_t *abDataOutLen); static int perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outlen); static int perform_unknown(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen); unsigned int skipfirst = 0; struct ccid_class_descriptor ccid_desc = { .bLength = sizeof ccid_desc, .bDescriptorType = 0x21, .bcdCCID = __constant_cpu_to_le16(0x0110), .bMaxSlotIndex = 0, .bVoltageSupport = 0x01, // 5.0V .dwProtocols = __constant_cpu_to_le32( 0x01| // T=0 0x02), // T=1 .dwDefaultClock = __constant_cpu_to_le32(0xDFC), .dwMaximumClock = __constant_cpu_to_le32(0xDFC), .bNumClockSupport = 1, .dwDataRate = __constant_cpu_to_le32(0x2580), .dwMaxDataRate = __constant_cpu_to_le32(0x2580), .bNumDataRatesSupported = 1, .dwMaxIFSD = __constant_cpu_to_le32(0xFF), // IFSD is handled by the real reader driver .dwSynchProtocols = __constant_cpu_to_le32(0), .dwMechanical = __constant_cpu_to_le32(0), .dwFeatures = __constant_cpu_to_le32( 0x00000002| // Automatic parameter configuration based on ATR data 0x00000004| // Automatic activation of ICC on inserting 0x00000008| // Automatic ICC voltage selection 0x00000010| // Automatic ICC clock frequency change 0x00000020| // Automatic baud rate change 0x00000040| // Automatic parameters negotiation 0x00000080| // Automatic PPS 0x00000400| // Automatic IFSD exchange as first exchange 0x00040000| // Short and Extended APDU level exchange with CCID 0x00100000), // USB Wake up signaling supported .dwMaxCCIDMessageLength = __constant_cpu_to_le32(CCID_EXT_APDU_MAX), .bClassGetResponse = 0xFF, .bclassEnvelope = 0xFF, .wLcdLayout = __constant_cpu_to_le16( 0xFF00| // Number of lines for the LCD display 0x00FF), // Number of characters per line .bPINSupport = 0x1| // PIN Verification supported 0x2| // PIN Modification supported 0x10| // PIN PACE Capabilities supported 0x20, // PIN PACE Verification supported .bMaxCCIDBusySlots = 0x01, }; #define debug_sc_result(sc_result) \ { \ if (sc_result < 0) \ sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, sc_strerror(sc_result)); \ else \ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, sc_strerror(sc_result)); \ } static int detect_card_presence(void) { int sc_result; sc_result = sc_detect_card_presence(reader); if (sc_result == 0 && card) { /* FIXME recent OpenSC versions throw an error when disconnecting an * obsolete card handle sc_disconnect_card(card); */ card = NULL; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card removed"); } if (sc_result & SC_READER_CARD_CHANGED) { /* FIXME recent OpenSC versions throw an error when disconnecting an * obsolete card handle sc_disconnect_card(card); */ card = NULL; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card exchanged"); } if (sc_result & SC_READER_CARD_PRESENT && !card) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unused card"); } return sc_result; } int ccid_initialize(int reader_id, int verbose) { int i; i = initialize(reader_id, verbose, &ctx, &reader); if (i < 0) return i; return SC_SUCCESS; } void ccid_shutdown(void) { sc_sm_stop(card); if (card) { sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); } static int get_rapdu(sc_apdu_t *apdu, __u8 **buf, size_t *resplen) { int sc_result; if (!apdu || !buf || !resplen || !card) { sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } apdu->resplen = apdu->le; if (0 != apdu->resplen) { apdu->resp = realloc(*buf, apdu->resplen); if (!apdu->resp) { sc_result = SC_ERROR_OUT_OF_MEMORY; goto err; } *buf = apdu->resp; } if (apdu->cla == 0xff) { sc_result = perform_pseudo_apdu(card->reader, apdu); } else { sc_result = sc_transmit_apdu(card, apdu); } if (sc_result < 0) { goto err; } if (apdu->sw1 > 0xff || apdu->sw2 > 0xff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Received invalid status bytes SW1=%d SW2=%d", apdu->sw1, apdu->sw2); sc_result = SC_ERROR_INVALID_DATA; goto err; } /* Get two more bytes to use as return buffer including sw1 and sw2 */ *buf = realloc(apdu->resp, apdu->resplen + sizeof(__u8) + sizeof(__u8)); if (!*buf) { sc_result = SC_ERROR_OUT_OF_MEMORY; goto err; } (*buf)[apdu->resplen] = apdu->sw1; (*buf)[apdu->resplen + sizeof(__u8)] = apdu->sw2; *resplen = apdu->resplen + sizeof(__u8) + sizeof(__u8); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "R-APDU, %d byte%s:\tsw1=%02x sw2=%02x", (unsigned int) *resplen, !*resplen ? "" : "s", apdu->sw1, apdu->sw2); sc_result = SC_SUCCESS; err: return sc_result; } static __u8 get_bError(int sc_result) { if (sc_result < 0) { switch (sc_result) { case SC_ERROR_KEYPAD_TIMEOUT: return CCID_BERROR_PIN_TIMEOUT; case SC_ERROR_KEYPAD_CANCELLED: return CCID_BERROR_PIN_CANCELLED; case SC_ERROR_EVENT_TIMEOUT: case SC_ERROR_CARD_UNRESPONSIVE: return CCID_BERROR_ICC_MUTE; default: return CCID_BERROR_HW_ERROR; } } else return CCID_BERROR_OK; } static __u8 get_bStatus(int sc_result) { int flags; __u8 bstatus = 0; if (skipfirst > 10) flags = detect_card_presence(); else { skipfirst += 1; flags = SC_SUCCESS; } if (flags >= 0) { if (sc_result < 0) { if (flags & SC_READER_CARD_PRESENT) { if (flags & SC_READER_CARD_CHANGED && !card) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error inactive"); bstatus = CCID_BSTATUS_ERROR_INACTIVE; } else { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error active"); bstatus = CCID_BSTATUS_ERROR_ACTIVE; } } else { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error no icc"); bstatus = CCID_BSTATUS_ERROR_NOICC; } } else { if (flags & SC_READER_CARD_PRESENT) { if (flags & SC_READER_CARD_CHANGED && !card) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ok inactive"); bstatus = CCID_BSTATUS_OK_INACTIVE; } else { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ok active"); bstatus = CCID_BSTATUS_OK_ACTIVE; } } else { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ok no icc"); bstatus = CCID_BSTATUS_OK_NOICC; } } } else { debug_sc_result(flags); sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not detect card presence." " Falling back to default (bStatus=0x%02X).", bstatus); } return bstatus; } static int get_RDR_to_PC_SlotStatus(__u8 bSeq, int sc_result, __u8 **outbuf, size_t *outlen, const __u8 *abProtocolDataStructure, size_t abProtocolDataStructureLen) { if (!outbuf) return SC_ERROR_INVALID_ARGUMENTS; if (abProtocolDataStructureLen > 0xffff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "abProtocolDataStructure %u bytes too long", abProtocolDataStructureLen-0xffff); return SC_ERROR_INVALID_DATA; } RDR_to_PC_SlotStatus_t *status = realloc(*outbuf, sizeof(*status) + abProtocolDataStructureLen); if (!status) return SC_ERROR_OUT_OF_MEMORY; *outbuf = (__u8 *) status; *outlen = sizeof(*status) + abProtocolDataStructureLen; status->bMessageType = 0x81; status->dwLength = __constant_cpu_to_le32(abProtocolDataStructureLen); status->bSlot = 0; status->bSeq = bSeq; status->bStatus = get_bStatus(sc_result); status->bError = get_bError(sc_result); status->bClockStatus = 0; /* Flawfinder: ignore */ memcpy((*outbuf) + sizeof(*status), abProtocolDataStructure, abProtocolDataStructureLen); return SC_SUCCESS; } static int get_RDR_to_PC_DataBlock(__u8 bSeq, int sc_result, __u8 **outbuf, size_t *outlen, const __u8 *abData, size_t abDataLen) { if (!outbuf) return SC_ERROR_INVALID_ARGUMENTS; if (abDataLen > 0xffff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "abProtocolDataStructure %u bytes too long", abDataLen-0xffff); return SC_ERROR_INVALID_DATA; } RDR_to_PC_DataBlock_t *data = realloc(*outbuf, sizeof(*data) + abDataLen); if (!data) return SC_ERROR_OUT_OF_MEMORY; *outbuf = (__u8 *) data; *outlen = sizeof(*data) + abDataLen; data->bMessageType = 0x80; data->dwLength = __constant_cpu_to_le32(abDataLen); data->bSlot = 0; data->bSeq = bSeq; data->bStatus = get_bStatus(sc_result); data->bError = get_bError(sc_result); data->bChainParameter = 0; /* Flawfinder: ignore */ memcpy((*outbuf) + sizeof(*data), abData, abDataLen); return SC_SUCCESS; } static int perform_PC_to_RDR_GetSlotStatus(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen) { const PC_to_RDR_GetSlotStatus_t *request = (PC_to_RDR_GetSlotStatus_t *) in; if (!out || !outlen || !in) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); *outlen = sizeof(RDR_to_PC_SlotStatus_t); if (request->bMessageType != 0x65 || request->dwLength != __constant_cpu_to_le32(0) || request->bSlot != 0 || request->abRFU1 != 0 || request->abRFU2 != 0) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed PC_to_RDR_GetSlotStatus"); return get_RDR_to_PC_SlotStatus(request->bSeq, SC_SUCCESS, out, outlen, NULL, 0); } static int perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen) { const PC_to_RDR_IccPowerOn_t *request = (PC_to_RDR_IccPowerOn_t *) in; int sc_result; if (!out || !outlen || !in) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); if (request->bMessageType != 0x62 || request->dwLength != __constant_cpu_to_le32(0) || request->bSlot != 0 || !( request->bPowerSelect == 0 || request->bPowerSelect & ccid_desc.bVoltageSupport) || request->abRFU != 0) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed PC_to_RDR_IccPowerOn"); if (card) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card is already powered on."); sc_result = SC_SUCCESS; } else { sc_sm_stop(card); sc_result = sc_connect_card(reader, &card); card->caps |= SC_CARD_CAP_APDU_EXT; } 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 { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Returning default status package."); return get_RDR_to_PC_SlotStatus(request->bSeq, sc_result, out, outlen, NULL, 0); } } static int perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen) { const PC_to_RDR_IccPowerOff_t *request = (PC_to_RDR_IccPowerOff_t *) in; int sc_result = SC_SUCCESS; if (!in || !out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); if (request->bMessageType != 0x63 || request->dwLength != __constant_cpu_to_le32(0) || request->bSlot != 0 || request->abRFU1 != 0 || request->abRFU2 != 0) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed PC_to_RDR_IccPowerOff"); //sc_reset(card, 1); //sc_result = sc_disconnect_card(card); return get_RDR_to_PC_SlotStatus(request->bSeq, sc_result, out, outlen, NULL, 0); } struct sw { unsigned char sw1; unsigned char sw2; }; static const struct sw iso_sw_ok = { 0x90, 0x00}; static const struct sw iso_sw_incorrect_p1_p2 = { 0x6A, 0x86}; static const struct sw iso_sw_ref_data_not_found = {0x6A, 0x88}; static const struct sw iso_sw_inconsistent_data = {0x6A, 0x87}; static const struct sw iso_sw_func_not_supported = {0x6A, 0x81}; static const struct sw iso_sw_ins_not_supported = {0x6D, 0x00}; #define min(a,b) (acla != 0xff) return SC_ERROR_INVALID_ARGUMENTS; apdu->resplen = 0; switch (apdu->ins) { case 0x9A: switch (apdu->p1) { case 0x01: /* GetReaderInfo */ if (apdu->datalen != 0) { apdu->sw1 = iso_sw_incorrect_p1_p2.sw1; apdu->sw2 = iso_sw_incorrect_p1_p2.sw2; goto err; } /* TODO Merge this with STRINGID_MFGR, STRINGID_PRODUCT in usb.c */ /* Copied from olsc/AusweisApp/Data/siqTerminalsInfo.cfg */ char *Herstellername = "REINER SCT"; char *Produktname = "cyberJack RFID komfort"; char *Firmwareversion = "1.0"; char *Treiberversion = "3.99.5"; switch (apdu->p2) { case 0x01: apdu->resplen = min(apdu->resplen, strlen(Herstellername)); memcpy(apdu->resp, Herstellername, apdu->resplen); break; case 0x03: apdu->resplen = min(apdu->resplen, strlen(Produktname)); memcpy(apdu->resp, Produktname, apdu->resplen); break; case 0x06: apdu->resplen = min(apdu->resplen, strlen(Firmwareversion)); memcpy(apdu->resp, Firmwareversion, apdu->resplen); break; case 0x07: apdu->resplen = min(apdu->resplen, strlen(Treiberversion)); memcpy(apdu->resp, Treiberversion, apdu->resplen); break; default: apdu->sw1 = iso_sw_ref_data_not_found.sw1; apdu->sw2 = iso_sw_ref_data_not_found.sw2; goto err; } break; case 0x04: switch (apdu->p2) { case 0x10: /* VerifyPIN/ModifyPIN */ LOG_TEST_RET(ctx, perform_PC_to_RDR_Secure(apdu->data, apdu->datalen, &apdu->resp, &apdu->resplen), "Could not perform PC_to_RDR_Secure"); apdu->sw1 = iso_sw_ok.sw1; apdu->sw2 = iso_sw_ok.sw2; break; case 0x01: /* GetReaderPACECapabilities */ LOG_TEST_RET(ctx, perform_pseudo_apdu_GetReaderPACECapabilities(apdu), "Could not get reader's PACE Capabilities"); apdu->sw1 = iso_sw_ok.sw1; apdu->sw2 = iso_sw_ok.sw2; break; case 0x02: /* EstablishPACEChannel */ LOG_TEST_RET(ctx, perform_pseudo_apdu_EstablishPACEChannel(apdu), "Could not perform PACE"); apdu->sw1 = iso_sw_ok.sw1; apdu->sw2 = iso_sw_ok.sw2; break; case 0x03: /* DestroyPACEChannel */ default: apdu->sw1 = iso_sw_func_not_supported.sw1; apdu->sw2 = iso_sw_func_not_supported.sw2; goto err; } break; default: apdu->sw1 = iso_sw_func_not_supported.sw1; apdu->sw2 = iso_sw_func_not_supported.sw2; goto err; } break; default: apdu->sw1 = iso_sw_ins_not_supported.sw1; apdu->sw2 = iso_sw_ins_not_supported.sw2; goto err; } err: return SC_SUCCESS; } static int perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outlen) { const PC_to_RDR_XfrBlock_t *request = (PC_to_RDR_XfrBlock_t *) in; const __u8 *abDataIn = in + sizeof *request; int sc_result; size_t abDataOutLen = 0, apdulen; sc_apdu_t apdu; __u8 *abDataOut = NULL; if (!in || !out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); if (request->bMessageType != 0x6F || request->bSlot != 0 || request->bBWI != 0) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "malformed PC_to_RDR_XfrBlock, will continue anyway"); apdulen = __le32_to_cpu(request->dwLength); if (inlen < apdulen+sizeof *request) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Not enough Data for APDU"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); } sc_result = sc_bytes2apdu(ctx, abDataIn, apdulen, &apdu); if (sc_result >= 0) sc_result = get_rapdu(&apdu, &abDataOut, &abDataOutLen); else bin_log(ctx, SC_LOG_DEBUG_VERBOSE, "Invalid APDU", abDataIn, __le32_to_cpu(request->dwLength)); sc_result = get_RDR_to_PC_DataBlock(request->bSeq, sc_result, out, outlen, abDataOut, abDataOutLen); free(abDataOut); return sc_result; } static int perform_PC_to_RDR_GetParamters(const __u8 *in, size_t inlen, __u8** out, size_t *outlen) { const PC_to_RDR_GetParameters_t *request = (PC_to_RDR_GetParameters_t *) in; RDR_to_PC_Parameters_t *result; abProtocolDataStructure_T1_t *t1; abProtocolDataStructure_T0_t *t0; int sc_result; if (!in || !out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); if (request->bMessageType != 0x6C || request->dwLength != __constant_cpu_to_le32(0) || request->bSlot != 0) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed PC_to_RDR_GetParamters"); switch (reader->active_protocol) { case SC_PROTO_T0: result = realloc(*out, sizeof *result + sizeof *t0); if (!result) return SC_ERROR_OUT_OF_MEMORY; *out = (__u8 *) result; result->bProtocolNum = 0; result->dwLength = __constant_cpu_to_le32(sizeof *t0); t0 = (abProtocolDataStructure_T0_t *) result + sizeof *result; /* values taken from ISO 7816-3 defaults * FIXME analyze ATR to get values */ t0->bmFindexDindex = 1<<4| // index to table 7 ISO 7816-3 (Fi) 1; // index to table 8 ISO 7816-3 (Di) t0->bmTCCKST0 = 0<<1; // convention (direct) t0->bGuardTimeT0 = 0xFF; t0->bWaitingIntegerT0 = 0x10; t0->bClockStop = 0; // (not allowed) sc_result = SC_SUCCESS; break; case SC_PROTO_T1: result = realloc(*out, sizeof *result + sizeof *t1); if (!result) return SC_ERROR_OUT_OF_MEMORY; *out = (__u8 *) result; result->bProtocolNum = 1; result->dwLength = __constant_cpu_to_le32(sizeof *t1); t1 = (abProtocolDataStructure_T1_t *) (result + sizeof *result); /* values taken from OpenPGP-card * FIXME analyze ATR to get values */ t1->bmFindexDindex = 1<<4| // index to table 7 ISO 7816-3 (Fi) 3; // index to table 8 ISO 7816-3 (Di) t1->bmTCCKST1 = 0| // checksum type (CRC) 0<<1| // convention (direct) 0x10; t1->bGuardTimeT1 = 0xFF; t1->bWaitingIntegersT1 = 4<<4| // BWI 5; // CWI t1->bClockStop = 0; // (not allowed) t1->bIFSC = 0x80; t1->bNadValue = 0; // see 7816-3 9.4.2.1 (only default value) sc_result = SC_SUCCESS; break; default: sc_result = SC_ERROR_INVALID_DATA; break; } result = realloc(*out, sizeof *result); if (!result) return SC_ERROR_OUT_OF_MEMORY; *out = (__u8 *) result; result->bMessageType = 0x82; result->bSlot = 0; result->bSeq = request->bSeq; result->bStatus = get_bStatus(sc_result); result->bError = get_bError(sc_result); if (sc_result < 0) debug_sc_result(sc_result); return SC_SUCCESS; } static int get_effective_offset(uint8_t system_units, uint8_t off, size_t *eff_off, int *sc_result) { if (!eff_off || !sc_result) { if (sc_result) *sc_result = SC_ERROR_INVALID_ARGUMENTS; return 0; } if (system_units) *eff_off = off; else if (off == 0) *eff_off = 0; else if (off == 8) *eff_off = 1; *sc_result = SC_SUCCESS; return 1; } static size_t get_datasize_for_pin(const struct sc_pin_cmd_pin *pin, uint8_t length_size) { size_t bytes_for_length, bytes_for_pin; if (!pin) return 0; bytes_for_length = pin->length_offset + (length_size+7)/8; if (pin->encoding == CCID_PIN_ENCODING_BCD) bytes_for_pin = pin->offset + (pin->len+1)/2; else bytes_for_pin = pin->offset + pin->len; if (bytes_for_length > bytes_for_pin) return bytes_for_length; return bytes_for_pin; } static int write_pin_length(sc_apdu_t *apdu, const struct sc_pin_cmd_pin *pin, uint8_t system_units, uint8_t length_size, int *sc_result) { u8 *p; if (!apdu || !apdu->data || !pin || apdu->datalen <= pin->length_offset || !sc_result) { if (sc_result) *sc_result = SC_ERROR_INVALID_ARGUMENTS; return 0; } if (length_size) { if (length_size != 8) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Writing PIN length only if it fits into " "a full byte (length of PIN size was %u bits)", length_size); *sc_result = SC_ERROR_NOT_SUPPORTED; return 0; } p = (u8 *) apdu->data; p[pin->length_offset] = pin->len; } *sc_result = SC_SUCCESS; return 1; } static int encode_pin(u8 *buf, size_t buf_len, struct sc_pin_cmd_pin *pin, uint8_t encoding, int *sc_result) { const u8 *p; if (!pin || !buf || !sc_result) { if (sc_result) *sc_result = SC_ERROR_INVALID_ARGUMENTS; return 0; } if (encoding == CCID_PIN_ENCODING_BIN) { for (p = pin->data; *p && buf_len>0; buf++, p++, buf_len--) { switch (*p) { case '0': *buf = 0x00; break; case '1': *buf = 0x01; break; case '2': *buf = 0x02; break; case '3': *buf = 0x03; break; case '4': *buf = 0x04; break; case '5': *buf = 0x05; break; case '6': *buf = 0x06; break; case '7': *buf = 0x07; break; case '8': *buf = 0x08; break; case '9': *buf = 0x09; break; default: *sc_result = SC_ERROR_INVALID_ARGUMENTS; return 0; } } if (!buf_len && *p) { /* pin is longer than buf_len */ *sc_result = SC_ERROR_OUT_OF_MEMORY; return 0; } *sc_result = SC_SUCCESS; } else { if (encoding == CCID_PIN_ENCODING_BCD) pin->encoding = SC_PIN_ENCODING_BCD; else if (encoding == CCID_PIN_ENCODING_ASCII) pin->encoding = SC_PIN_ENCODING_ASCII; else { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "PIN encoding not supported (0x%02x)", encoding); *sc_result = SC_ERROR_NOT_SUPPORTED; return 0; } *sc_result = sc_build_pin(buf, buf_len, pin, 0); if (*sc_result < 0) return 0; } return 1; } static int write_pin(sc_apdu_t *apdu, struct sc_pin_cmd_pin *pin, uint8_t blocksize, uint8_t justify_right, uint8_t encoding, int *sc_result) { /* offset due to right alignment */ uint8_t justify_offset; if (!apdu || !pin || !sc_result) { if (sc_result) *sc_result = SC_ERROR_INVALID_ARGUMENTS; return 0; } if (justify_right) { if (encoding == CCID_PIN_ENCODING_BCD) { if (pin->len % 2) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Right aligning BCD encoded PIN only if it fits " "into a full byte (length of encoded PIN was %u bits)", (pin->len)*4); *sc_result = SC_ERROR_NOT_SUPPORTED; return 0; } else justify_offset = blocksize - pin->len/2; } else justify_offset = blocksize - pin->len; } else justify_offset = 0; return encode_pin((u8 *) apdu->data + justify_offset, blocksize - justify_offset, pin, encoding, sc_result); } static int perform_PC_to_RDR_Secure_EstablishPACEChannel(sc_card_t *card, const __u8 *abData, size_t abDatalen, __u8 **abDataOut, size_t *abDataOutLen) { struct establish_pace_channel_input pace_input; struct establish_pace_channel_output pace_output; size_t parsed = 0; int sc_result; __le16 word; __le32 dword; __u8 *p; memset(&pace_input, 0, sizeof pace_input); memset(&pace_output, 0, sizeof pace_output); if (!abDataOut || !abDataOutLen) { sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } bin_log(ctx, SC_LOG_DEBUG_VERBOSE, "EstablishPACEChannel InBuffer", abData, abDatalen); if (abDatalen < parsed+1) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get PinID"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } pace_input.pin_id = abData[parsed]; parsed++; if (abDatalen < parsed+1) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get lengthCHAT"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } pace_input.chat_length = abData[parsed]; parsed++; if (abDatalen < parsed+pace_input.chat_length) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get CHAT"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } pace_input.chat = &abData[parsed]; parsed += pace_input.chat_length; if (pace_input.chat_length) { bin_log(ctx, SC_LOG_DEBUG_VERBOSE, "Card holder authorization template", pace_input.chat, pace_input.chat_length); } if (abDatalen < parsed+1) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get lengthPIN"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } pace_input.pin_length = abData[parsed]; parsed++; if (abDatalen < parsed+pace_input.pin_length) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get PIN"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } pace_input.pin = &abData[parsed]; parsed += pace_input.pin_length; if (abDatalen < parsed+sizeof word) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get lengthCertificateDescription"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } /* Flawfinder: ignore */ memcpy(&word, &abData[parsed], sizeof word); pace_input.certificate_description_length = __le16_to_cpu(word); parsed += sizeof word; if (abDatalen < parsed+pace_input.certificate_description_length) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Buffer too small, could not get CertificateDescription"); sc_result = SC_ERROR_INVALID_ARGUMENTS; goto err; } pace_input.certificate_description = &abData[parsed]; if (pace_input.certificate_description_length) { bin_log(ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description", pace_input.certificate_description, pace_input.certificate_description_length); } sc_result = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02); if (sc_result < 0) goto err; p = realloc(*abDataOut, 4 + /* Result */ 2 + /* length Output data */ 2 + /* Statusbytes */ 2+pace_output.ef_cardaccess_length + /* EF.CardAccess */ 1+pace_output.recent_car_length + /* Most recent CAR */ 1+pace_output.previous_car_length + /* Previous CAR */ 2+pace_output.id_icc_length); /* identifier of the MRTD chip */ if (!p) { sc_result = SC_ERROR_OUT_OF_MEMORY; goto err; } *abDataOut = p; dword = __cpu_to_le32(pace_output.result); /* Flawfinder: ignore */ memcpy(p, &dword, sizeof dword); p += sizeof dword; word = __cpu_to_le16( 2 + 2+pace_output.ef_cardaccess_length + 1+pace_output.recent_car_length + 1+pace_output.previous_car_length + 2+pace_output.id_icc_length); /* Flawfinder: ignore */ memcpy(p, &word, sizeof word); p += sizeof word; *p = pace_output.mse_set_at_sw1; p += 1; *p = pace_output.mse_set_at_sw2; p += 1; if (pace_output.ef_cardaccess_length > 0xffff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "EF.CardAcces %u bytes too long", pace_output.ef_cardaccess_length-0xffff); sc_result = SC_ERROR_INVALID_DATA; goto err; } word = __cpu_to_le16(pace_output.ef_cardaccess_length); /* Flawfinder: ignore */ memcpy(p, &word, sizeof word); p += sizeof word; /* Flawfinder: ignore */ memcpy(p, pace_output.ef_cardaccess, pace_output.ef_cardaccess_length); p += pace_output.ef_cardaccess_length; if (pace_output.recent_car_length > 0xff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Most recent CAR %u bytes too long", pace_output.recent_car_length-0xff); sc_result = SC_ERROR_INVALID_DATA; goto err; } *p = pace_output.recent_car_length; p += 1; /* Flawfinder: ignore */ memcpy(p, pace_output.recent_car, pace_output.recent_car_length); p += pace_output.recent_car_length; if (pace_output.previous_car_length > 0xff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Previous CAR %u bytes too long", pace_output.previous_car_length-0xff); sc_result = SC_ERROR_INVALID_DATA; goto err; } *p = pace_output.previous_car_length; p += 1; /* Flawfinder: ignore */ memcpy(p, pace_output.previous_car, pace_output.previous_car_length); p += pace_output.previous_car_length; if (pace_output.id_icc_length > 0xffff) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "ID ICC %u bytes too long", pace_output.id_icc_length-0xffff); sc_result = SC_ERROR_INVALID_DATA; goto err; } word = __cpu_to_le16(pace_output.id_icc_length); /* Flawfinder: ignore */ memcpy(p, &word, sizeof word); p += sizeof word; /* Flawfinder: ignore */ memcpy(p, pace_output.id_icc, pace_output.id_icc_length); *abDataOutLen = 4 + /* Result */ 2 + /* length Output data */ 2 + /* Statusbytes */ 2+pace_output.ef_cardaccess_length + /* EF.CardAccess */ 1+pace_output.recent_car_length + /* Most recent CAR */ 1+pace_output.previous_car_length + /* Previous CAR */ 2+pace_output.id_icc_length ; /* identifier of the MRTD chip */ sc_result = SC_SUCCESS; err: free(pace_output.ef_cardaccess); free(pace_output.recent_car); free(pace_output.previous_car); free(pace_output.id_icc); free(pace_output.id_pcd); return sc_result; } static int perform_PC_to_RDR_Secure_GetReadersPACECapabilities(__u8 **abDataOut, size_t *abDataOutLen) { int sc_result; u8 *BitMap; if (!abDataOut || !abDataOutLen) return SC_ERROR_INVALID_ARGUMENTS; BitMap = realloc(*abDataOut, sizeof *BitMap); if (!BitMap) return SC_ERROR_OUT_OF_MEMORY; *abDataOut = BitMap; sc_result = get_pace_capabilities(BitMap); if (sc_result < 0) return sc_result; *abDataOutLen = sizeof *BitMap; return SC_SUCCESS; } static int perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outlen) { int sc_result; u8 curr_pin_data[0xff], new_pin_data[0xff], apdu_data[0xf]; struct sc_pin_cmd_pin curr_pin, new_pin; sc_apdu_t apdu; const PC_to_RDR_Secure_t *request = (PC_to_RDR_Secure_t *) in; const __u8* abData = in + sizeof *request; size_t abDatalen = inlen - sizeof *request; u8 *abDataOut = NULL; size_t abDataOutLen = 0; memset(&curr_pin, 0, sizeof(curr_pin)); memset(&new_pin, 0, sizeof(new_pin)); memset(curr_pin_data, 0, sizeof curr_pin_data); memset(new_pin_data, 0, sizeof new_pin_data); curr_pin.data = curr_pin_data; curr_pin.len = sizeof curr_pin_data; new_pin.data = new_pin_data; new_pin.len = sizeof new_pin_data; if (!in || !out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request + 1) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); if (request->bMessageType != 0x69 || request->bSlot != 0) sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed PC_to_RDR_Secure"); if (request->wLevelParameter != CCID_WLEVEL_DIRECT) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Received request with unsupported wLevelParameter (0x%04x)", __le16_to_cpu(request->wLevelParameter)); sc_result = SC_ERROR_NOT_SUPPORTED; goto err; } __u8 bmPINLengthFormat, bmPINBlockString, bmFormatString, bNumberMessage; __u8 *abPINApdu; uint32_t apdulen; uint16_t wPINMaxExtraDigit; abPINDataStucture_Verification_t *verify = NULL; abPINDataStucture_Modification_t *modify = NULL; switch (*abData) { // first byte of abData is bPINOperation case 0x00: // PIN Verification verify = (abPINDataStucture_Verification_t *) (abData + sizeof(__u8)); if (abDatalen < sizeof *verify) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Not enough data for abPINDataStucture_Verification_t"); sc_result = SC_ERROR_INVALID_DATA; goto err; } wPINMaxExtraDigit = verify->wPINMaxExtraDigit; bmPINLengthFormat = verify->bmPINLengthFormat; bmPINBlockString = verify->bmPINBlockString; bmFormatString = verify->bmFormatString; bNumberMessage = verify->bNumberMessage; abPINApdu = (__u8*) verify + sizeof(*verify); apdulen = __le32_to_cpu(request->dwLength) - sizeof(*verify) - sizeof(__u8); break; case 0x01: // PIN Modification modify = (abPINDataStucture_Modification_t *) (abData + sizeof(__u8)); /* bTeoPrologue adds another 3 bytes */ if (abDatalen < sizeof *modify + 3*(sizeof(__u8))) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Not enough data for abPINDataStucture_Modification_t"); sc_result = SC_ERROR_INVALID_DATA; goto err; } wPINMaxExtraDigit = modify->wPINMaxExtraDigit; bmPINLengthFormat = modify->bmPINLengthFormat; bmPINBlockString = modify->bmPINBlockString; bmFormatString = modify->bmFormatString; bNumberMessage = modify->bNumberMessage; /* bTeoPrologue adds another 3 bytes */ abPINApdu = (__u8*) modify + sizeof *modify + 3*(sizeof(__u8)); apdulen = __le32_to_cpu(request->dwLength) - sizeof *modify - 4*sizeof(__u8); switch (bNumberMessage) { case 0x03: /* bMsgIndex3 is present */ abPINApdu++; apdulen--; /* fall through */ case 0x02: /* bMsgIndex2 is present */ abPINApdu++; apdulen--; break; } break; case 0x10: sc_result = perform_PC_to_RDR_Secure_GetReadersPACECapabilities( &abDataOut, &abDataOutLen); if (card) bin_log(card->ctx, SC_LOG_DEBUG_VERBOSE, "PACE Capabilities", abDataOut, abDataOutLen); goto err; break; case 0x20: sc_result = perform_PC_to_RDR_Secure_EstablishPACEChannel(card, abData+1, abDatalen-1, &abDataOut, &abDataOutLen); goto err; break; case 0x04: // Cancel PIN function default: sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Received request with unsupported PIN operation (bPINOperation=0x%02x)", *abData); sc_result = SC_ERROR_NOT_SUPPORTED; goto err; } if (inlen - (abData - abPINApdu) < apdulen) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Not enough Data for APDU"); sc_result = SC_ERROR_INVALID_DATA; goto err; } sc_result = sc_bytes2apdu(ctx, abPINApdu, apdulen, &apdu); if (sc_result < 0) { bin_log(ctx, SC_LOG_DEBUG_VERBOSE, "Invalid APDU", abPINApdu, apdulen); goto err; } new_pin.min_length = curr_pin.min_length = wPINMaxExtraDigit >> 8; new_pin.max_length = curr_pin.max_length = wPINMaxExtraDigit & 0x00ff; if (new_pin.min_length > new_pin.max_length) { /* If maximum length is smaller than minimum length, suppose minimum * length defines the exact length of the pin. */ curr_pin.max_length = curr_pin.min_length; new_pin.max_length = new_pin.min_length; } uint8_t system_units = bmFormatString & CCID_PIN_UNITS_BYTES; uint8_t pin_offset = (bmFormatString >> 3) & 0xf; uint8_t length_offset = bmPINLengthFormat & 0xf; uint8_t length_size = bmPINBlockString >> 4; uint8_t justify_right = bmFormatString & CCID_PIN_JUSTIFY_RIGHT; uint8_t encoding = bmFormatString & 2; uint8_t blocksize = bmPINBlockString & 0xf; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN %s block (%d bytes) proberties:\n" "\tminimum %d, maximum %d PIN digits\n" "\t%s PIN encoding, %s justification\n" "\tsystem units are %s\n" "\twrite PIN length on %d bits with %d system units offset\n" "\tcurrent PIN offset is %d %s\n", modify ? "modification" : "verification", blocksize, modify ? (unsigned int) new_pin.min_length : (unsigned int) curr_pin.min_length, modify ? (unsigned int) new_pin.max_length : (unsigned int) curr_pin.max_length, encoding == CCID_PIN_ENCODING_BIN ? "binary" : encoding == CCID_PIN_ENCODING_BCD ? "BCD" : encoding == CCID_PIN_ENCODING_ASCII ? "ASCII" :"unknown", justify_right ? "right" : "left", system_units ? "bytes" : "bits", length_size, length_offset, modify ? modify->bInsertionOffsetOld : pin_offset, modify ? "bytes" : "system units"); /* get the PIN */ if (verify) { if (0 > EVP_read_pw_string_min((char *) curr_pin.data, curr_pin.min_length, curr_pin.max_length, "Please enter your PIN for verification: ", 0)) { sc_result = SC_ERROR_INTERNAL; sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not read PIN.\n"); goto err; } } else { if (modify->bConfirmPIN & CCID_PIN_INSERT_OLD) { /* if only the new pin is requested, it is stored in curr_pin */ if (0 > EVP_read_pw_string_min((char *) curr_pin.data, curr_pin.min_length, curr_pin.max_length, "Please enter your current PIN for modification: ", 0)) { sc_result = SC_ERROR_INTERNAL; sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not read current PIN.\n"); goto err; } } if (0 > EVP_read_pw_string_min((char *) new_pin.data, new_pin.min_length, new_pin.max_length, "Please enter your new PIN for modification: ", modify->bConfirmPIN & CCID_PIN_CONFIRM_NEW)) { sc_result = SC_ERROR_INTERNAL; sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n"); goto err; } } /* set length of PIN */ curr_pin.len = strnlen((char *) curr_pin.data, curr_pin.max_length); if (modify) { new_pin.len = strnlen((char *) new_pin.data, new_pin.max_length); } if (!apdu.datalen || !apdu.data) { /* Host did not provide any data in the APDU, so we have to assign * something for the pin block */ if (verify) { apdu.lc = get_datasize_for_pin(&curr_pin, length_size); blocksize = apdu.lc; } else { apdu.lc = get_datasize_for_pin(&new_pin, length_size); blocksize = apdu.lc; if (modify->bConfirmPIN & CCID_PIN_INSERT_OLD) { if (get_datasize_for_pin(&curr_pin, length_size) > apdu.lc) apdu.lc = get_datasize_for_pin(&curr_pin, length_size); } } if (apdu.lc > sizeof apdu_data) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for PIN block.\n"); sc_result = SC_ERROR_INTERNAL; goto err; } apdu.data = apdu_data; apdu.datalen = apdu.lc; switch (apdu.cse) { case SC_APDU_CASE_1: apdu.cse = SC_APDU_CASE_3_SHORT; break; case SC_APDU_CASE_2_SHORT: apdu.cse = SC_APDU_CASE_4_SHORT; break; case SC_APDU_CASE_2_EXT: apdu.cse = SC_APDU_CASE_4_EXT; break; default: /* Don't change APDU Case */ break; } } /* Note: pin.offset and pin.length_offset are relative to the first * databyte */ if (verify || (modify->bConfirmPIN & CCID_PIN_INSERT_OLD)) { if (!get_effective_offset(system_units, pin_offset, &curr_pin.offset, &sc_result) || !write_pin(&apdu, &curr_pin, blocksize, justify_right, encoding, &sc_result) || !get_effective_offset(system_units, length_offset, &curr_pin.length_offset, &sc_result) || !write_pin_length(&apdu, &curr_pin, system_units, length_size, &sc_result)) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Writing current PIN to PIN block failed.\n"); goto err; } } if (modify) { if (modify->bConfirmPIN & CCID_PIN_INSERT_OLD && modify->bInsertionOffsetOld != curr_pin.offset) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Inconsistent PIN block proberties.\n"); sc_result = SC_ERROR_INVALID_DATA; goto err; } new_pin.offset = modify->bInsertionOffsetNew; if (!write_pin(&apdu, &new_pin, blocksize, justify_right, encoding, &sc_result)) goto err; } sc_result = get_rapdu(&apdu, &abDataOut, &abDataOutLen); /* clear PINs that have been transmitted */ sc_mem_clear((u8 *) apdu.data, apdu.datalen); err: sc_mem_clear((u8 *) curr_pin.data, curr_pin.len); sc_mem_clear((u8 *) new_pin.data, new_pin.len); sc_result = get_RDR_to_PC_DataBlock(request->bSeq, sc_result, out, outlen, abDataOut, abDataOutLen); free(abDataOut); return sc_result; } /* XXX calling sc_wait_for_event blocks all other threads, thats why it * can't be used here... */ static int get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out) { int sc_result; uint8_t oldmask; uint8_t changed [] = { CCID_SLOT1_CHANGED, CCID_SLOT2_CHANGED, CCID_SLOT3_CHANGED, CCID_SLOT4_CHANGED, }; uint8_t present [] = { CCID_SLOT1_CARD_PRESENT, CCID_SLOT2_CARD_PRESENT, CCID_SLOT3_CARD_PRESENT, CCID_SLOT4_CARD_PRESENT, }; if (!out) return SC_ERROR_INVALID_ARGUMENTS; RDR_to_PC_NotifySlotChange_t *result = realloc(*out, sizeof *result); if (!result) return SC_ERROR_OUT_OF_MEMORY; *out = result; result->bMessageType = 0x50; result->bmSlotICCState = CCID_SLOTS_UNCHANGED; oldmask = CCID_SLOTS_UNCHANGED; sc_result = detect_card_presence(); if (sc_result < 0) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not detect card presence."); debug_sc_result(sc_result); } if (sc_result & SC_READER_CARD_PRESENT) oldmask |= present[0]; if (sc_result & SC_READER_CARD_CHANGED) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card status changed."); result->bmSlotICCState |= changed[0]; } sleep(10); sc_result = detect_card_presence(); if (sc_result < 0) { sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Could not detect card presence."); debug_sc_result(sc_result); } if (sc_result & SC_READER_CARD_PRESENT) result->bmSlotICCState |= present[0]; if (sc_result & SC_READER_CARD_CHANGED) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card status changed."); result->bmSlotICCState |= changed[0]; } if ((oldmask & present[0]) != (result->bmSlotICCState & present[0])) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Card status changed."); result->bmSlotICCState |= changed[0]; } return SC_SUCCESS; } static int perform_unknown(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen) { const PC_to_RDR_GetSlotStatus_t *request = (PC_to_RDR_GetSlotStatus_t *) in; RDR_to_PC_SlotStatus_t *result; if (!in || !out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; if (inlen < sizeof *request) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); result = realloc(*out, sizeof *result); if (!result) return SC_ERROR_OUT_OF_MEMORY; *out = (__u8 *) result; switch (request->bMessageType) { case 0x62: case 0x6F: case 0x69: result->bMessageType = 0x80; break; case 0x63: case 0x65: case 0x6E: case 0x6A: case 0x71: case 0x72: result->bMessageType = 0x81; break; case 0x61: case 0x6C: case 0x6D: result->bMessageType = 0x82; break; case 0x6B: result->bMessageType = 0x83; break; case 0x73: result->bMessageType = 0x84; break; default: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unknown message type in request (0x%02x). " "Using bMessageType=0x%02x for output.", request->bMessageType, 0); result->bMessageType = 0; } result->dwLength = __constant_cpu_to_le32(0); result->bSlot = 0, result->bSeq = request->bSeq; result->bStatus = get_bStatus(SC_ERROR_UNKNOWN_DATA_RECEIVED); result->bError = 0; result->bClockStatus = 0; *outlen = sizeof *result; return SC_SUCCESS; } int ccid_parse_bulkout(const __u8* inbuf, size_t inlen, __u8** outbuf) { int sc_result; size_t outlen; if (!inbuf) return 0; bin_log(ctx, SC_LOG_DEBUG_VERBOSE, "CCID input", inbuf, inlen); switch (*inbuf) { case 0x62: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PC_to_RDR_IccPowerOn"); sc_result = perform_PC_to_RDR_IccPowerOn(inbuf, inlen, outbuf, &outlen); break; case 0x63: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PC_to_RDR_IccPowerOff"); sc_result = perform_PC_to_RDR_IccPowerOff(inbuf, inlen, outbuf, &outlen); break; case 0x65: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PC_to_RDR_GetSlotStatus"); sc_result = perform_PC_to_RDR_GetSlotStatus(inbuf, inlen, outbuf, &outlen); break; case 0x6F: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PC_to_RDR_XfrBlock"); sc_result = perform_PC_to_RDR_XfrBlock(inbuf, inlen, outbuf, &outlen); break; case 0x6C: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PC_to_RDR_GetParameters"); sc_result = perform_PC_to_RDR_GetParamters(inbuf, inlen, outbuf, &outlen); break; case 0x69: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PC_to_RDR_Secure"); sc_result = perform_PC_to_RDR_Secure(inbuf, inlen, outbuf, &outlen); break; default: sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Unknown ccid bulk-in message. " "Starting default handler..."); sc_result = perform_unknown(inbuf, inlen, outbuf, &outlen); } if (sc_result < 0) { debug_sc_result(sc_result); return -1; } return outlen; } int ccid_parse_control(struct usb_ctrlrequest *setup, __u8 **outbuf) { int r; __u16 value, index, length; __u8 *tmp; if (!setup || !outbuf) return -1; value = __le16_to_cpu(setup->wValue); index = __le16_to_cpu(setup->wIndex); length = __le16_to_cpu(setup->wLength); if (setup->bRequestType == USB_REQ_CCID) { switch(setup->bRequest) { case CCID_CONTROL_ABORT: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ABORT"); if (length != 0x00) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed ABORT"); } r = 0; break; case CCID_CONTROL_GET_CLOCK_FREQUENCIES: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "GET_CLOCK_FREQUENCIES"); if (value != 0x00) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed GET_CLOCK_FREQUENCIES"); } r = sizeof(__le32); tmp = realloc(*outbuf, r); if (!tmp) { r = SC_ERROR_OUT_OF_MEMORY; break; } *outbuf = tmp; __le32 clock = ccid_desc.dwDefaultClock; /* Flawfinder: ignore */ memcpy(*outbuf, &clock, sizeof (__le32)); break; case CCID_CONTROL_GET_DATA_RATES: sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "GET_DATA_RATES"); if (value != 0x00) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: malformed GET_DATA_RATES"); } r = sizeof (__le32); tmp = realloc(*outbuf, r); if (tmp == NULL) { r = -1; break; } *outbuf = tmp; __le32 drate = ccid_desc.dwDataRate; /* Flawfinder: ignore */ memcpy(*outbuf, &drate, sizeof (__le32)); break; default: sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Unknown ccid control command."); r = SC_ERROR_NOT_SUPPORTED; } } else { r = SC_ERROR_INVALID_ARGUMENTS; } if (r < 0) debug_sc_result(r); return r; } int ccid_state_changed(RDR_to_PC_NotifySlotChange_t **slotchange, int timeout) { int sc_result; if (!slotchange) return 0; sc_result = get_RDR_to_PC_NotifySlotChange(slotchange); if (sc_result < 0) { debug_sc_result(sc_result); } if ((*slotchange)->bmSlotICCState) return 1; return 0; } vsmartcard-3.3/ccid/src/usbstring.h0000644000175000017500000000201413546304763016071 0ustar philphil/* * (c) Copyright 2003 by David Brownell * All Rights Reserved. * * This software is licensed under the GNU LGPL version 2. */ /* utility to simplify dealing with string descriptors */ /** * struct usb_string - wraps a C string and its USB id * @id: the (nonzero) ID for this string * @s: the string, in UTF-8 encoding * * If you're using usb_gadget_get_string(), use this to wrap a string * together with its ID. */ struct usb_string { __u8 id; const char *s; }; /** * struct usb_gadget_strings - a set of USB strings in a given language * @language: identifies the strings' language (0x0409 for en-us) * @strings: array of strings with their ids * * If you're using usb_gadget_get_string(), use this to wrap all the * strings for a given language. */ struct usb_gadget_strings { __u16 language; /* 0x0409 for en-us */ struct usb_string *strings; }; /* put descriptor for string with that id into buf (buflen >= 256) */ int usb_gadget_get_string (struct usb_gadget_strings *table, int id, __u8 *buf); vsmartcard-3.3/ccid/doc/0000755000175000017500000000000013546304763013661 5ustar philphilvsmartcard-3.3/ccid/doc/Makefile.am0000644000175000017500000000216213546304763015716 0ustar philphildo_subst = $(SED) \ -e 's,[@]PACKAGE[@],$(PACKAGE),g' \ -e 's,[@]PACKAGE_NAME[@],$(PACKAGE_NAME),g' \ -e 's,[@]PACKAGE_TARNAME[@],$(PACKAGE_TARNAME),g' \ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \ -e 's,[@]PACKAGE_SUMMARY[@],$(PACKAGE_SUMMARY),g' \ -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \ -e 's,[@]RECOMMENDED_CONF_OPTS[@],,g' \ -e 's,[@]builddir[@],$(builddir),g' \ -e 's,[@]prefix[@],$(prefix),g' \ -e 's,[@]exec_prefix[@],$(exec_prefix),g' \ -e 's,[@]libdir[@],$(libdir),g' \ -e 's,[@]includedir[@],$(includedir),g' \ -e 's,[@]VERSION[@],$(VERSION),g' \ -e 's,[@]OPENSC_LIBS[@],$(OPENSC_LIBS),g' \ -e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \ -e 's,[@]top_srcdir[@],$(top_srcdir),g' EXTRA_DIST = README.txt.in autotools.txt.in questions.txt.in download.txt.in doc: *.in $(do_subst) < autotools.txt.in > autotools.txt $(do_subst) < questions.txt.in > questions.txt $(do_subst) < download.txt.in > download.txt $(do_subst) < README.txt.in > README.txt touch doc clean-local: rm -f doc vsmartcard-3.3/ccid/doc/questions.txt.in0000777000175000017500000000000013546304763023451 2../../doc/questions.txt.inustar philphilvsmartcard-3.3/ccid/doc/download.txt.in0000777000175000017500000000000013546304763023003 2../../doc/download.txt.inustar philphilvsmartcard-3.3/ccid/doc/autotools.txt.in0000777000175000017500000000000013546304763023447 2../../doc/autotools.txt.inustar philphilvsmartcard-3.3/ccid/doc/README.txt.in0000644000175000017500000003670413546304763015776 0ustar philphil.. highlight:: sh .. |PACE| replace:: :abbr:`PACE (Password Authenticated Connection Establishment)` .. _ccid-emulator: ################################################################################ @PACKAGE_NAME@ ################################################################################ .. sidebar:: @PACKAGE_SUMMARY@ :License: GPL version 3 :Tested Platforms: Linux (Debian, Ubuntu, OpenMoko) The @PACKAGE_NAME@ forwards a locally present PC/SC smart card reader as a standard USB CCID reader. @PACKAGE_NAME@ can be used as trusted intermediary enabling secure PIN entry and PIN modification. In combination with OpenSC_ also |PACE| can be performed by the emulator. .. tikz:: Portable smart card reader with trusted user interface :stringsubst: :libs: arrows, calc, fit, patterns, plotmarks, shapes.geometric, shapes.misc, shapes.symbols, shapes.arrows, shapes.callouts, shapes.multipart, shapes.gates.logic.US, shapes.gates.logic.IEC, er, automata, backgrounds, chains, topaths, trees, petri, mindmap, matrix, calendar, folding, fadings, through, positioning, scopes, decorations.fractals, decorations.shapes, decorations.text, decorations.pathmorphing, decorations.pathreplacing, decorations.footprints, decorations.markings, shadows \input{$wd/bilder/tikzstyles.tex} \tikzstyle{bla}=[kleiner, text width=.45\textwidth] \node (reader) {\includegraphics[width=1cm]{$wd/bilder/my_cardreader.pdf}}; \node (readertext) [right=0of reader, bla] {Smartphone provides smart card reader via USB}; \node (display) [below=0of reader] {\includegraphics[width=1cm]{$wd/bilder/display.pdf}}; \node (displaytext) [right=0of display, bla] {Secure display of service provider and purpose of transaction}; \node (keyboard) [below=0of display] {\includegraphics[width=1cm]{$wd/bilder/keyboard.pdf}}; \node (keyboardtext) [right=0of keyboard, bla] {Secure PIN Entry}; \node (firewall) [below=0of keyboard] {\includegraphics[width=1cm]{$wd/bilder/Firewall.pdf}}; \node (firewalltext) [right=0of firewall, bla] {Verification of terminal authentication and sanitiy checks}; \node (features) [fit=(display) (keyboard) (reader) (firewall)] {}; \node (moko) [left=0of features.west] {\includegraphics[height=4cm]{$wd/bilder/phone-fic-neo-freerunner.pdf}}; \node (epa) [left=1.5of moko, yshift=-2cm] {\includegraphics[width=3cm]{$wd/bilder/nPA_VS.png}}; \node (pc) [left=1.5of moko, yshift=1.5cm] {\includegraphics[width=3cm]{$wd/bilder/computer-tango.pdf}}; \begin{pgfonlayer}{background} \node (mokobox) [box, fit=(moko) (readertext) (displaytext) (keyboardtext) (firewalltext) (features)] {}; \draw [usb] (moko) -- (pc.center) ; \draw [decorate, decoration={expanding waves, angle=20, segment length=6}, nichtrundelinie] (moko) -- (epa) ; \end{pgfonlayer} If the machine running :command:`ccid-emulator` is in USB device mode, a local reader is forwareded via USB to another machine. If in USB host mode, the USB CCID reader will locally be present. Applications on Windows and Unix-like systems can access the @PACKAGE_NAME@ through PC/SC as if it was a real smart card reader. No installation of a smart card driver is required since USB CCID drivers are usually shipped with the modern OS. Here is a subset of USB CCID commands supported by the @PACKAGE_NAME@ with their PC/SC counterpart: ================================== ============================================================ USB CCID PC/SC ================================== ============================================================ ``PC_to_RDR_XfrBlock`` ``SCardTransmit`` ``PC_to_RDR_Secure`` ``FEATURE_VERIFY_PIN_DIRECT``, ``FEATURE_MODIFY_PIN_DIRECT`` ``PC_to_RDR_Secure`` (proprietary) ``FEATURE_EXECUTE_PACE`` ================================== ============================================================ PIN verification/modification and |PACE| can also be started by the application transmitting (SCardTransmit) specially crafted APDUs. Only the alternative initialization of |PACE| using SCardControl requires patching the driver (available for libccid, see :file:`patches`). The pseudo APDUs with no need for patches are defined as follows (see `BSI TR-03119 1.3`_ p. 33-34): +--------------------------+----------------------------------------------------------------------------+------------------------------------------------+ | | Command APDU | Response APDU | | +----------+----------+----------+----------+--------------------------------+-----------------------------------+------------+ | | CLA | INS | P1 | P2 | Command Data | Response Data | SW1/SW2 | +==========================+==========+==========+==========+==========+================================+===================================+============+ | GetReaderPACECapabilities| ``0xFF`` | ``0x9A`` | ``0x04`` | ``0x01`` | (No Data) | ``PACECapabilities`` | | +--------------------------+----------+----------+----------+----------+--------------------------------+-----------------------------------+ ``0x9000`` | | EstablishPACEChannel | ``0xFF`` | ``0x9A`` | ``0x04`` | ``0x02`` | ``EstablishPACEChannelInput`` | ``EstablishPACEChannelOutput`` | or other | +--------------------------+----------+----------+----------+----------+--------------------------------+-----------------------------------+ in case of | | DestroyPACEChannel | ``0xFF`` | ``0x9A`` | ``0x04`` | ``0x03`` | (No Data) | (No Data) | an error | +--------------------------+----------+----------+----------+----------+--------------------------------+-----------------------------------+ | | Verify/Modify PIN | ``0xFF`` | ``0x9A`` | ``0x04`` | ``0x10`` | Coding as ``PC_to_RDR_Secure`` | Coding as ``RDR_to_PC_DataBlock`` | | +--------------------------+----------+----------+----------+----------+--------------------------------+-----------------------------------+------------+ The @PACKAGE_NAME@ is implemented using GadgetFS_. Some fragments of the source code are based on the GadgetFS example and on the source code of the OpenSC tools. .. tikz:: Software stack of the @PACKAGE_NAME@ running on the OpenMoko Neo FreeRunner :stringsubst: :libs: arrows, calc, fit, patterns, plotmarks, shapes.geometric, shapes.misc, shapes.symbols, shapes.arrows, shapes.callouts, shapes.multipart, shapes.gates.logic.US, shapes.gates.logic.IEC, er, automata, backgrounds, chains, topaths, trees, petri, mindmap, matrix, calendar, folding, fadings, through, positioning, scopes, decorations.fractals, decorations.shapes, decorations.text, decorations.pathmorphing, decorations.pathreplacing, decorations.footprints, decorations.markings, shadows \input{$wd/bilder/tikzstyles.tex} \tikzstyle{schicht}=[text width=5cm, align=right] \tikzstyle{fade down}=[path fading=south, color=huslateblue] \node (kernel) [box, shape=rectangle split, rectangle split parts=3, kleiner] {Linux Kernel \nodepart{second} \footnotesize S3C24xx Controller Driver \nodepart{third} \footnotesize GadgetFS }; \node (ccid) [aktivbox, shape=rectangle split, rectangle split parts=2, below=of kernel] {CCID Emulator \nodepart{second} \texttt{usb}\qquad\texttt{ccid} }; \draw [box] ($(ccid.text split)-(.05cm,0)$) -- ($(ccid.south)-(.05cm,0)$); \node (opensc) [box, below=of ccid, kleiner] {OpenSC}; \node (controller) [klein, right=0of kernel.two east, schicht] {Driver for USB Controller}; \node (gadget) [klein, right=0of kernel.three east, schicht] {Gadget Driver}; \node (upper) [klein, right=0of kernel.three east, schicht, yshift=-1.75cm] {Upper Layers}; \tikzstyle{rechts}=[to path={-- ++(1,0) |- (\tikztotarget)}] \tikzstyle{links}=[to path={-- ++(-1,0) |- (\tikztotarget)}] \begin{pgfonlayer}{background} \path (ccid.two west) edge [links, linie] (kernel.three west) (ccid.two east) edge [rechts, linie] (opensc.east) ; \path [color=black!30] (controller.north east) edge +(-9,0) (gadget.north east) edge +(-9,0) (upper.north east) edge +(-9,0) ; \end{pgfonlayer} \node [kleiner, anchor=east, text width=3cm] at ($($(ccid.two west)+(-3,0)$)!.5!(kernel.three west)$) {\color{hublue} \texttt{/dev/gadget/ep1-bulk}\\ \texttt{/dev/gadget/ep2-bulk}\\ \texttt{/dev/gadget/ep3-bulk}\\}; Running the @PACKAGE_NAME@ has the following dependencies: - Linux Kernel with GadgetFS_ - OpenSC_ Whereas using the @PACKAGE_NAME@ on the host system as smart card reader only needs a usable PC/SC middleware with USB CCID driver. This is the case for most modern Windows and Unix-like systems by default. .. tikz:: Implementation of a mobile smart card reader for the German ID card :stringsubst: :libs: arrows, calc, fit, patterns, plotmarks, shapes.geometric, shapes.misc, shapes.symbols, shapes.arrows, shapes.callouts, shapes.multipart, shapes.gates.logic.US, shapes.gates.logic.IEC, er, automata, backgrounds, chains, topaths, trees, petri, mindmap, matrix, calendar, folding, fadings, through, positioning, scopes, decorations.fractals, decorations.shapes, decorations.text, decorations.pathmorphing, decorations.pathreplacing, decorations.footprints, decorations.markings, shadows \input{$wd/bilder/tikzstyles.tex} \tikzstyle{keks}=[to path={-- ++(.1,0) |- (\tikztotarget)}] \tikzstyle{bla}=[shape=rectangle split, rectangle split parts=2, every text node part/.style={align=center, klein}, text width=7cm, every second node part/.style={kleiner}, inner sep=0pt] \node (ccid-emulator) {\texttt{ccid-emulator}}; \node (basis) [below=3of ccid-emulator] {\includegraphics[keepaspectratio, height=2cm, width=2cm]{$wd/bilder/moko/basisleser_plain_klein.png}}; \node (basisbeschreibung) [below=0cm of basis, kleiner, text width=2cm] {Reiner SCT RFID basis}; \node (npa) [left=1.5of basis] {\includegraphics[keepaspectratio, height=3cm, width=3cm]{$wd/bilder/nPA_VS.png}}; \node (npabeschreibung) [below=0cm of npa, kleiner] {German identity card}; \node (funktionenchat) [right=.6cm of ccid-emulator.east, anchor=text west, bla] { PACE \nodepart{second} \begin{itemize} \item Display CHAT \begin{itemize} \item Display context (eID/eSign) \item Display requested permissions \end{itemize} \item Display certificate description \begin{itemize} \item Identification of service provider \item Display purpose of transaction \end{itemize} \item Secure PIN entry \end{itemize} }; \node (funktionenpace) [below=.5 of funktionenchat, bla] { Terminal Authentication \nodepart{second} \begin{itemize} \item Verify authenticy of terminal \item Check freshness of cv certificate \end{itemize} }; \begin{pgfonlayer}{background} \node (box) [fit=(ccid-emulator) (basis) (basisbeschreibung) (funktionenchat) (funktionenpace), box, inner sep=.5cm] {}; \node (boxbild) at (box.north west) {\includegraphics[keepaspectratio, height=1.5cm, width=1.5cm]{$wd/bilder/moko/moko_reader.png}}; \node [right=0cm of boxbild.east, yshift=.3cm] {Openmoko Neo FreeRunner}; \end{pgfonlayer} \node (a) [above=1of npa] {\includegraphics[keepaspectratio, height=3cm, width=3cm]{$wd/bilder/computer-tango.pdf}}; \begin{pgfonlayer}{background} \path (ccid-emulator) edge [doppelpfeil] (basis) (basis) edge [rfid] (npa) (a.center) edge [usb] (ccid-emulator) (ccid-emulator.east) edge [pfeil, keks] (funktionenchat.text west) (ccid-emulator.east) edge [pfeil, keks] (funktionenpace.text west); \end{pgfonlayer} .. include:: download.txt .. include:: autotools.txt ================= Hints on GadgetFS ================= To create a USB Gadget in both USB host and USB client mode, you need to load the kernel module :program:`gadgetfs`. Here is how to get a running version of GadgetFS on a Debian system (see also `OpenMoko Wiki`_):: sudo apt-get install linux-source linux-headers-`uname -r` sudo tar xjf /usr/src/linux-source-*.tar.bz2 cd linux-source-*/drivers/usb/gadget # build dummy_hcd and gadgetfs echo "KDIR := /lib/modules/`uname -r`/build" >> Makefile echo "PWD := `pwd`" >> Makefile echo "obj-m := dummy_hcd.o gadgetfs.o" >> Makefile echo "default: " >> Makefile echo -e "\t\$(MAKE) -C \$(KDIR) SUBDIRS=\$(PWD) modules" >> Makefile make # load GadgetFS with its dependencies sudo modprobe udc-core sudo insmod ./dummy_hcd.ko sudo insmod ./gadgetfs.ko default_uid=`id -u` # mount GadgetFS sudo mkdir /dev/gadget sudo mount -t gadgetfs gadgetfs /dev/gadget On OpenMoko it is likely that you need to `patch your kernel `_. If you also want to switch multiple times between :program:`gadgetfs` and :program:`g_ether`, `another patch is needed `_. If you are using a more recent version of :program:`dummy_hcd` and get an error loading the module, you maybe want to check out `this patch `_. =============== Hints on OpenSC =============== @PACKAGE_NAME@ needs the OpenSC components to be installed (especially :file:`libopensc.so`). Here is an example of how to get the standard installation of OpenSC without |PACE|:: PREFIX=/tmp/install VSMARTCARD=$PWD/vsmartcard git clone https://github.com/frankmorgner/vsmartcard.git $VSMARTCARD cd $VSMARTCARD git submodule init git submodule update cd $VSMARTCARD/ccid/src/opensc autoreconf --verbose --install ./configure --prefix=$PREFIX make install && cd - Now :file:`libopensc.so` should be located in ``$PREFIX/lib``. Here is how to configure the @PACKAGE_NAME@ to use it:: cd $VSMARTCARD/ccid ./configure --prefix=$PREFIX OPENSC_LIBS="-L$PREFIX/lib -lopensc" make install && cd - ***** Usage ***** The @PACKAGE_NAME@ has various command line options to customize the appearance on the USB host. In order to run the @PACKAGE_NAME@ GadgetFS must be loaded and mounted. The @PACKAGE_NAME@ is compatible with the unix driver libccid_ and the `Windows USB CCID driver`_. PIN commands are supported if implemented by the driver. .. versionadded:: 0.7 @PACKAGE_NAME@ now supports the boxing commands defined in `BSI TR-03119 1.3`_. .. program-output:: ccid-emulator --help .. include:: questions.txt ******************** Notes and References ******************** .. target-notes:: .. _`GadgetFS`: http://www.linux-usb.org/gadget/ .. _`OpenSC`: https://github.com/frankmorgner/OpenSC .. _`libccid`: http://pcsclite.alioth.debian.org/ccid.html .. _`Windows USB CCID driver`: http://msdn.microsoft.com/en-us/windows/hardware/gg487509 .. _`OpenMoko Wiki`: http://wiki.openmoko.org/wiki/Building_Gadget_USB_Module .. _`BSI TR-03119 1.3`: https://www.bsi.bund.de/DE/Publikationen/TechnischeRichtlinien/tr03119/index_htm.html vsmartcard-3.3/ccid/Makefile.am0000644000175000017500000000011013546304763015140 0ustar philphilACLOCAL_AMFLAGS = -I m4 SUBDIRS = src m4 patches doc EXTRA_DIST = docs vsmartcard-3.3/ccid/configure.ac0000644000175000017500000001126313546304763015405 0ustar philphil# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) AC_INIT([USB CCID Emulator], [0.8], [https://github.com/frankmorgner/vsmartcard/issues], [ccid-emulator], [http://frankmorgner.github.io/vsmartcard/ccid/README.html]) AC_CONFIG_SRCDIR([src/ccid.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE(foreign) AC_USE_SYSTEM_EXTENSIONS LT_INIT # Checks for programs. AC_PROG_CXX AC_PROG_CC AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_LIBTOOL AM_PROG_CC_C_O AC_PROG_SED PKG_PROG_PKG_CONFIG AC_ARG_VAR([HELP2MAN], [absolute path to help2man used for man page generation of ccid-emulator]) AC_PATH_PROG(HELP2MAN, help2man, not found) if test ! -r src/ccid-emulator.1 -a "${HELP2MAN}" = "not found" then AC_MSG_ERROR([Need help2man to generate man page for ccid-emulator]) fi AC_ARG_VAR([GENGETOPT], [absolute path to gengetopt used for command line parsing of ccid-emulator]) AC_PATH_PROG(GENGETOPT, gengetopt, not found) if test ! -r src/cmdline.h -a "${GENGETOPT}" = "not found" then AC_MSG_ERROR([Need gengetopt for parsing command line of ccid-emulator]) fi # If you need to see the details, just run make V=1. m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) # Checks for libraries. AC_CHECK_HEADERS(linux/usb/gadgetfs.h,, [ AC_MSG_ERROR([linux/usb/gadgetfs.h not found, maybe you want to disable ccid]) ]) ACX_PTHREAD saved_CPPFLAGS="$CPPFLAGS" saved_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS" LIBS="$LDFLAGS $PTHREAD_LIBS" AC_CHECK_HEADERS(pthread.h, [], [ AC_MSG_ERROR([pthread.h not found, use ./configure PTHREAD_CFLAGS=... or disable ccid]) ]) AC_MSG_CHECKING([for pthread_create]) AC_TRY_LINK_FUNC(pthread_create, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([pthread not found, use ./configure PTHREAD_LIBS=... or disable ccid]) ]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" PKG_CHECK_EXISTS([libcrypto], [PKG_CHECK_MODULES([OPENSSL], [libcrypto >= 1.0.0])], [AC_MSG_WARN([libcrypto not found by pkg-config])]) saved_CPPFLAGS="$CPPFLAGS" saved_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $OPENSSL_CFLAGS" LIBS="$LDFLAGS $OPENSSL_LIBS" AC_CHECK_HEADERS(openssl/evp.h, [], [ AC_MSG_ERROR([openssl/evp.h not found, install OpenSSL >= 1.0.0 or use ./configure OPENSSL_CFLAGS=...]) ]) AC_MSG_CHECKING([for EVP_read_pw_string_min]) AC_TRY_LINK_FUNC(EVP_read_pw_string_min, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([OpenSSL >= 1.0.0 not found, use ./configure OPENSSL_LIBS=...]) ]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" saved_CPPFLAGS="$CPPFLAGS" saved_LIBS="$LIBS" PKG_CHECK_EXISTS([libopensc], [PKG_CHECK_MODULES([OPENSC], [libopensc >= 0.12.1])], [AC_MSG_WARN([libopensc >= 0.12.1 not found by pkg-config])]) test -z "$OPENSC_LIBS" && OPENSC_LIBS="-lopensc $OPENSSL_LIBS" LIBS="$LDFLAGS $OPENSC_LIBS" AC_MSG_CHECKING([for sc_bytes2apdu]) AC_TRY_LINK_FUNC(sc_bytes2apdu, [ AC_MSG_RESULT([yes]) ], [ AC_MSG_ERROR([libopensc >= 0.12.1 not found, use ./configure OPENSC_LIBS=...]) ]) AC_CHECK_FUNCS([sc_apdu_set_resp sc_apdu_get_octets _sc_match_atr boxing_buf_to_pace_input]) CPPFLAGS="$saved_CPPFLAGS" LIBS="$saved_LIBS" PACKAGE_SUMMARY="Emulate a USB CCID compliant smart card reader" AC_SUBST(PACKAGE_SUMMARY) # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h fcntl.h memory.h stdint.h stdlib.h string.h sys/ioctl.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT8_T # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_STRNLEN AC_CHECK_FUNCS([memmove memset strerror strtol]) cat << EOF ${PACKAGE} has been configured with following options: Version: ${PACKAGE_VERSION} User binaries: $(eval eval eval echo "${bindir}") Libraries: $(eval eval eval echo "${libdir}") Configuration files: $(eval eval eval echo "${sysconfdir}") Host: ${host} Compiler: ${CC} Preprocessor flags: ${CPPFLAGS} Compiler flags: ${CFLAGS} Preprocessor flags: ${CPPFLAGS} Linker flags: ${LDFLAGS} Libraries: ${LIBS} PTHREAD_CFLAGS: ${PTHREAD_CFLAGS} PTHREAD_LIBS: ${PTHREAD_LIBS} OPENSC_LIBS: ${OPENSC_LIBS} OPENSSL_CFLAGS: ${OPENSSL_CFLAGS} OPENSSL_LIBS: ${OPENSSL_LIBS} HELP2MAN: ${HELP2MAN} GENGETOPT: ${GENGETOPT} EOF AC_CONFIG_FILES([ Makefile m4/Makefile patches/Makefile src/Makefile doc/Makefile ]) AC_OUTPUT vsmartcard-3.3/ccid/patches/0000755000175000017500000000000013546304763014543 5ustar philphilvsmartcard-3.3/ccid/patches/ccid-1.3.11.patch0000644000175000017500000005045013546304763017211 0ustar philphilIndex: ccid-1.3.11/src/ccid.h =================================================================== --- ccid-1.3.11.orig/src/ccid.h 2009-06-30 21:42:38.000000000 +0200 +++ ccid-1.3.11/src/ccid.h 2011-11-28 15:47:16.230511000 +0100 @@ -137,8 +137,10 @@ #define CCID_CLASS_EXCHANGE_MASK 0x00070000 /* Features from bPINSupport */ -#define CCID_CLASS_PIN_VERIFY 0x01 -#define CCID_CLASS_PIN_MODIFY 0x02 +#define CCID_CLASS_PIN_VERIFY 0x01 +#define CCID_CLASS_PIN_MODIFY 0x02 +#define CCID_CLASS_PIN_PACE_CAPABILITIES 0x10 +#define CCID_CLASS_PIN_PACE_EXECUTE 0x20 /* See CCID specs ch. 4.2.1 */ #define CCID_ICC_PRESENT_ACTIVE 0x00 /* 00 0000 00 */ @@ -149,6 +151,25 @@ #define CCID_COMMAND_FAILED 0x40 /* 01 0000 00 */ #define CCID_TIME_EXTENSION 0x80 /* 10 0000 00 */ +#define PACE_SUCCESS 0x00000000 +#define PACE_ERROR_LENGTH_INCONSISTENT 0xD0000001 +#define PACE_ERROR_UNEXPECTED_DATA 0xD0000002 +#define PACE_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003 +#define PACE_ERROR_CARD_NOT_SUPPORTED 0xE0000001 +#define PACE_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002 +#define PACE_ERROR_PINID_NOT_SUPPORTED 0xE0000003 +#define PACE_ERROR_SELECT_EF_CARDACCESS 0xF0000000 +#define PACE_ERROR_READ_BINARY 0xF0010000 +#define PACE_ERROR_MSE_SET_AT 0xF0020000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000 +#define PACE_ERROR_COMMUNICATION 0xF0100001 +#define PACE_ERROR_NO_CARD 0xF0100002 +#define PACE_ERROR_ABORTED 0xF0200001 +#define PACE_ERROR_TIMEOUT 0xF0200002 + /* bInterfaceProtocol for ICCD */ #define ICCD_A 1 /* ICCD Version A */ #define ICCD_B 2 /* ICCD Version B */ @@ -216,6 +237,8 @@ /* convert a 4 byte integer in USB format into an int */ #define dw2i(a, x) (unsigned int)((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x]) +/* convert a 2 byte integer in USB format into an int */ +#define w2i(a, x) (unsigned int)(((a[x+1]) << 8) + a[x]) /* all the data rates specified by ISO 7816-3 Fi/Di tables */ #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ Index: ccid-1.3.11/src/ccid_ifdhandler.h =================================================================== --- ccid-1.3.11.orig/src/ccid_ifdhandler.h 2009-06-30 21:42:38.000000000 +0200 +++ ccid-1.3.11/src/ccid_ifdhandler.h 2011-11-28 15:53:02.574510999 +0100 @@ -38,6 +38,11 @@ #define IOCTL_FEATURE_IFD_PIN_PROPERTIES \ SCARD_CTL_CODE(FEATURE_IFD_PIN_PROPERTIES + CLASS2_IOCTL_MAGIC) #endif +#ifndef FEATURE_EXECUTE_PACE +#define FEATURE_EXECUTE_PACE 0x20 +#endif +#define IOCTL_FEATURE_EXECUTE_PACE \ + SCARD_CTL_CODE(FEATURE_EXECUTE_PACE + CLASS2_IOCTL_MAGIC) #define DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED 1 #define DRIVER_OPTION_GEMPC_TWIN_KEY_APDU 2 Index: ccid-1.3.11/src/commands.c =================================================================== --- ccid-1.3.11.orig/src/commands.c 2009-06-12 15:06:22.000000000 +0200 +++ ccid-1.3.11/src/commands.c 2011-11-28 15:47:16.234511000 +0100 @@ -68,7 +68,19 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); +static RESPONSECODE SecurePINPACE(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength, + unsigned char bPINOperation); + +static RESPONSECODE transform_EstablishPACEChannel_InputData( + unsigned char input[], unsigned int input_length); + +static RESPONSECODE transform_EstablishPACEChannel_OutputData( + unsigned char output[], unsigned int output_length); + static void i2dw(int value, unsigned char *buffer); +static void i2w(uint16_t value, unsigned char *buffer); /***************************************************************************** @@ -691,6 +703,341 @@ return ret; } /* SecurePINModify */ +static RESPONSECODE transform_EstablishPACEChannel_InputData( + unsigned char input[], unsigned int input_length) +{ + uint8_t lengthCHAT, lengthPIN; + uint16_t lengthCertificateDescription; + size_t parsed = 0; + + /* transform length fields of input data to little endian */ + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + switch (input[parsed]) { + case 0x01: + DEBUG_COMM("Initiating PACE with MRZ"); + break; + case 0x02: + DEBUG_COMM("Initiating PACE with CAN"); + break; + case 0x03: + DEBUG_COMM("Initiating PACE with PIN"); + break; + case 0x04: + DEBUG_COMM("Initiating PACE with PUK"); + break; + default: + DEBUG_COMM("Initiating PACE with unknown PACE secret type"); + break; + } + parsed += 1; + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCHAT = input[parsed]; + parsed += 1; + + if (input_length < parsed+lengthCHAT) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCHAT) + DEBUG_INFO_XXD("CHAT:\n", &input[parsed], lengthCHAT); + parsed += lengthCHAT; + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + lengthPIN = input[parsed]; + parsed += 1; + + if (input_length < parsed+lengthPIN) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } +#if 0 + /* dont print secrets... */ + if (lengthPIN) + DEBUG_INFO_XXD("PIN:\n", &input[parsed], lengthPIN); +#endif + parsed += lengthPIN; + + if (input_length < parsed+2) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + memcpy(&lengthCertificateDescription, &input[parsed], 2); + i2w(lengthCertificateDescription, &input[parsed]); + parsed += 2; + + if (input_length < parsed+lengthCertificateDescription) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCertificateDescription) + DEBUG_INFO_XXD("Certificate description:\n", &input[parsed], lengthCertificateDescription); + parsed += lengthCertificateDescription; + + if (parsed < input_length) { + DEBUG_CRITICAL2("Overrun by %u bytes", input_length - parsed); + return IFD_COMMUNICATION_ERROR; + } + + return IFD_SUCCESS; +} + +static RESPONSECODE transform_EstablishPACEChannel_OutputData( + unsigned char output[], unsigned int output_length) +{ + uint8_t lengthCAR, lengthCARprev; + uint16_t lengthOutputData, lengthEF_CardAccess, length_IDicc; + uint32_t result; + size_t parsed = 0; + + if (parsed+4 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + result = dw2i(output, parsed); + memcpy(&output[parsed], &result, 4); + DEBUG_INFO2("EstablishPACEChannel Result: %08X", result); + parsed += 4; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthOutputData = w2i(output, parsed); + if ((unsigned int)lengthOutputData+6 != output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + parsed += 2; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", + output[parsed+0], output[parsed+1]); + parsed += 2; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthEF_CardAccess = w2i(output, parsed); + memcpy(&output[parsed], &lengthEF_CardAccess, 2); + parsed += 2; + + if (parsed+lengthEF_CardAccess > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthEF_CardAccess) + DEBUG_INFO_XXD("EF.CardAccess:\n", &output[parsed], lengthEF_CardAccess); + parsed += lengthEF_CardAccess; + + if (parsed+1 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCAR = output[parsed]; + parsed += 1; + + if (parsed+lengthCAR > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCAR) + DEBUG_INFO_XXD("Recent Certificate Authority:\n", + &output[parsed], lengthCAR); + parsed += lengthCAR; + + if (parsed+1 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCARprev = output[parsed]; + parsed += 1; + + if (parsed+lengthCARprev > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCARprev) + DEBUG_INFO_XXD("Previous Certificate Authority:\n", + &output[parsed], lengthCARprev); + parsed += lengthCARprev; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + length_IDicc = w2i(output, parsed); + memcpy(&output[parsed], &length_IDicc, 2); + parsed += 2; + + if (parsed+length_IDicc > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (length_IDicc) + DEBUG_INFO_XXD("IDicc:\n", &output[parsed], length_IDicc); + parsed += length_IDicc; + + if (parsed < output_length) { + DEBUG_CRITICAL2("Overrun by %u bytes", output_length - parsed); + return IFD_COMMUNICATION_ERROR; + } + + return IFD_SUCCESS; +} + +RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength) +{ + /* bPINOperation: PIN PACE Capabilities */ + RESPONSECODE return_value; + int old_read_timeout; + _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index); + + old_read_timeout= ccid_descriptor -> readTimeout; + ccid_descriptor -> readTimeout = 30*1000; /* 30 seconds */ + + return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); + if (IFD_SUCCESS != return_value) + goto err; + + return_value = SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer, + RxLength, CCID_CLASS_PIN_PACE_EXECUTE); + if (IFD_SUCCESS != return_value) + goto err; + + if (*RxLength < 6) { + DEBUG_CRITICAL("Malformed Establish PACE output buffer."); + return_value = IFD_COMMUNICATION_ERROR; + goto err; + } + + return_value = transform_EstablishPACEChannel_OutputData(RxBuffer, *RxLength); + if (IFD_SUCCESS != return_value) + goto err; + +err: + ccid_descriptor -> readTimeout = old_read_timeout; + return return_value; +} + +RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength) +{ + /* bPINOperation: PIN PACE Capabilities */ + if (*RxLength < 6) { + DEBUG_CRITICAL2("overrun by %d bytes", 6 - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } + + unsigned int length = *RxLength - 6; + RESPONSECODE r = SecurePINPACE(reader_index, TxBuffer, TxLength, + RxBuffer+6, &length, CCID_CLASS_PIN_PACE_CAPABILITIES); + if (r != IFD_SUCCESS) + return r; + + uint32_t s = PACE_SUCCESS; + memcpy(RxBuffer, &s, 4); /* Result */ + memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ + *RxLength = length + 6; + + return IFD_SUCCESS; +} + +static RESPONSECODE SecurePINPACE(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength, + unsigned char bPINOperation) +{ + unsigned char cmd[11+0xffff]; + unsigned int length; + _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index); + status_t res; + + cmd[0] = 0x69; /* Secure */ + i2dw(TxLength, cmd+1); + cmd[5] = ccid_descriptor->bCurrentSlotIndex; + cmd[6] = (*ccid_descriptor->pbSeq)++; + cmd[7] = 0; + cmd[8] = 0; + cmd[9] = 0; + cmd[10] = bPINOperation; + + if (sizeof(cmd) < 11+TxLength) + { + DEBUG_CRITICAL2("Too much data in input (overrun by %d bytes)", + 11+TxLength - sizeof(cmd)); + return IFD_COMMUNICATION_ERROR; + } + memcpy(cmd+11, TxBuffer, TxLength); + + res = WritePort(reader_index, 11+TxLength, cmd); + if (res != STATUS_SUCCESS) + { + if (STATUS_NO_SUCH_DEVICE == res) + return IFD_NO_SUCH_DEVICE; + return IFD_COMMUNICATION_ERROR; + } + + length = sizeof(cmd); + res = ReadPort(reader_index, &length, cmd); + if (res != STATUS_SUCCESS) + { + if (STATUS_NO_SUCH_DEVICE == res) + return IFD_NO_SUCH_DEVICE; + return IFD_COMMUNICATION_ERROR; + } + + if (length < STATUS_OFFSET+1) + { + DEBUG_CRITICAL2("Not enough data received: %d bytes", length); + return IFD_COMMUNICATION_ERROR; + } + + if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED) + { + ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */ + return IFD_COMMUNICATION_ERROR; + } + + /* we have read less (or more) data than the CCID frame says to contain */ + if (length-10 != dw2i(cmd, 1)) + { + DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)", + length-10, dw2i(cmd, 1)); + return IFD_COMMUNICATION_ERROR; + } + + length = dw2i(cmd, 1); + if (length <= *RxLength) + *RxLength = length; + else + { + DEBUG_CRITICAL2("overrun by %d bytes", length - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } + + memcpy(RxBuffer, cmd+10, *RxLength); + + return IFD_SUCCESS; +} + /***************************************************************************** * @@ -2081,3 +2428,15 @@ buffer[3] = (value >> 24) & 0xFF; } /* i2dw */ + +/***************************************************************************** + * + * i2w + * + ****************************************************************************/ +static void i2w(uint16_t value, unsigned char buffer[]) +{ + buffer[0] = value & 0xFF; + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + Index: ccid-1.3.11/src/commands.h =================================================================== --- ccid-1.3.11.orig/src/commands.h 2009-01-07 00:14:35.000000000 +0100 +++ ccid-1.3.11/src/commands.h 2011-11-28 15:47:16.234511000 +0100 @@ -37,6 +37,14 @@ unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); +RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength); + +RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength); + RESPONSECODE CmdEscape(unsigned int reader_index, const unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); Index: ccid-1.3.11/src/defs.h =================================================================== --- ccid-1.3.11.orig/src/defs.h 2009-07-01 14:28:01.000000000 +0200 +++ ccid-1.3.11/src/defs.h 2011-11-28 15:47:16.234511000 +0100 @@ -66,16 +66,10 @@ /* Flag set when a power down is requested */ #define MASK_POWERFLAGS_PDWN 0x02 -/* Kobil readers does not support APDU chaining for T=1 so you can't send an - * extended APDU. The readers supports a command of up to 512 or 420 bytes. - * For a Kobil KAAN Base/advanced reader you should use - * #define CMD_BUF_SIZE 420 - * For the other models you should use - * #define CMD_BUF_SIZE 512 - * Kobil is aware of the problem and do not plan to solve it. - */ -/* Communication buffer size (max=adpu+Lc+data+Le) */ -#define CMD_BUF_SIZE (4+1+256+1) +/* Communication buffer size (max=adpu+Lc+data+Le) + * * we use a 64kB for extended APDU on APDU mode readers */ +#define CMD_BUF_SIZE (4 +3 +64*1024 +3) + /* Larger communication buffer size (max=reader status+data+sw) */ #define RESP_BUF_SIZE (1+256+2) Index: ccid-1.3.11/src/ifdhandler.c =================================================================== --- ccid-1.3.11.orig/src/ifdhandler.c 2009-07-28 22:57:07.000000000 +0200 +++ ccid-1.3.11/src/ifdhandler.c 2011-11-28 15:47:16.234511000 +0100 @@ -68,6 +68,71 @@ int clock_frequency); static unsigned int T1_card_timeout(double f, double d, int TC1, int BWI, int CWI, int clock_frequency); +static RESPONSECODE do_feature_execute_pace(unsigned int reader_index, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned); + +static RESPONSECODE do_feature_execute_pace(unsigned int reader_index, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned) +{ + uint16_t lengthInputData; + unsigned int i; + RESPONSECODE r; + + if (TxLength < 3 || !TxBuffer) { + DEBUG_CRITICAL("Buffer too small, could not determine length of " + "input data"); + i = PACE_ERROR_LENGTH_INCONSISTENT; + goto err; + } + + memcpy(&lengthInputData, &TxBuffer[1], 2); + + if (TxLength != 3+lengthInputData) { + DEBUG_CRITICAL3("Buffer too small or too big to contain only " + "function index and input data (expected %u, got %u)", + 3+lengthInputData, TxLength); + i = PACE_ERROR_LENGTH_INCONSISTENT; + goto err; + } + + switch(*TxBuffer) { + case 1: + r = SecurePINPACECapabilities(reader_index, + TxBuffer+3, lengthInputData, RxBuffer, &i); + *pdwBytesReturned = i; + return r; + + case 2: + r = SecurePINPACEVerify(reader_index, TxBuffer+3, + lengthInputData, RxBuffer, &i); + *pdwBytesReturned = i; + return r; + + default: + DEBUG_CRITICAL2("Unknown PACE function %u", + (unsigned char)*TxBuffer); + if (RxLength < 6 || !RxBuffer) { + DEBUG_CRITICAL2("Need %u more bytes in RxBuffer", + RxLength>6 ? (unsigned int)6-RxLength : 0); + return IFD_COMMUNICATION_ERROR; + } + + i = PACE_ERROR_UNEXPECTED_DATA; + goto err; + } + +err: + memcpy(RxBuffer, &i, 4); + memset(RxBuffer + 4, 0, 2); + + *pdwBytesReturned = 6; + + return IFD_SUCCESS; +} + + EXTERNAL RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR lpcDevice) @@ -1266,6 +1331,16 @@ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); } + if (get_ccid_descriptor(reader_index) -> bPINSupport & CCID_CLASS_PIN_PACE_CAPABILITIES) + { + pcsc_tlv -> tag = FEATURE_EXECUTE_PACE; + pcsc_tlv -> length = 0x04; /* always 0x04 */ + pcsc_tlv -> value = htonl(IOCTL_FEATURE_EXECUTE_PACE); + + pcsc_tlv++; + iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); + } + #ifdef FEATURE_IFD_PIN_PROPERTIES /* We can always forward wLcdLayout */ pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES; @@ -1365,6 +1440,12 @@ } } + if (IOCTL_FEATURE_EXECUTE_PACE == dwControlCode) + { + return_value = do_feature_execute_pace(reader_index, TxBuffer, + TxLength, RxBuffer, RxLength, pdwBytesReturned); + } + if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; vsmartcard-3.3/ccid/patches/Makefile.am0000644000175000017500000000012313546304763016573 0ustar philphilEXTRA_DIST = ccid-1.3.11.patch \ pcsc-lite-1.5.5.patch pcsc-lite-1.6.1.patch vsmartcard-3.3/ccid/patches/ccid-1.4.5.patch0000644000175000017500000004634113546304763017141 0ustar philphilIndex: ccid-1.4.5/src/ccid.h =================================================================== --- ccid-1.4.5.orig/src/ccid.h 2011-10-11 22:27:44.000000000 +0200 +++ ccid-1.4.5/src/ccid.h 2012-01-24 21:25:58.287191632 +0100 @@ -152,8 +152,10 @@ #define CCID_CLASS_EXCHANGE_MASK 0x00070000 /* Features from bPINSupport */ -#define CCID_CLASS_PIN_VERIFY 0x01 -#define CCID_CLASS_PIN_MODIFY 0x02 +#define CCID_CLASS_PIN_VERIFY 0x01 +#define CCID_CLASS_PIN_MODIFY 0x02 +#define CCID_CLASS_PIN_PACE_CAPABILITIES 0x10 +#define CCID_CLASS_PIN_PACE_EXECUTE 0x20 /* See CCID specs ch. 4.2.1 */ #define CCID_ICC_PRESENT_ACTIVE 0x00 /* 00 0000 00 */ @@ -164,6 +166,25 @@ #define CCID_COMMAND_FAILED 0x40 /* 01 0000 00 */ #define CCID_TIME_EXTENSION 0x80 /* 10 0000 00 */ +#define PACE_SUCCESS 0x00000000 +#define PACE_ERROR_LENGTH_INCONSISTENT 0xD0000001 +#define PACE_ERROR_UNEXPECTED_DATA 0xD0000002 +#define PACE_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003 +#define PACE_ERROR_CARD_NOT_SUPPORTED 0xE0000001 +#define PACE_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002 +#define PACE_ERROR_PINID_NOT_SUPPORTED 0xE0000003 +#define PACE_ERROR_SELECT_EF_CARDACCESS 0xF0000000 +#define PACE_ERROR_READ_BINARY 0xF0010000 +#define PACE_ERROR_MSE_SET_AT 0xF0020000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000 +#define PACE_ERROR_COMMUNICATION 0xF0100001 +#define PACE_ERROR_NO_CARD 0xF0100002 +#define PACE_ERROR_ABORTED 0xF0200001 +#define PACE_ERROR_TIMEOUT 0xF0200002 + /* bInterfaceProtocol for ICCD */ #define PROTOCOL_CCID 0 /* plain CCID */ #define PROTOCOL_ICCD_A 1 /* ICCD Version A */ @@ -240,6 +261,8 @@ /* convert a 4 byte integer in USB format into an int */ #define dw2i(a, x) (unsigned int)((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x]) +/* convert a 2 byte integer in USB format into an int */ +#define w2i(a, x) (unsigned int)(((a[x+1]) << 8) + a[x]) /* all the data rates specified by ISO 7816-3 Fi/Di tables */ #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ Index: ccid-1.4.5/src/ccid_ifdhandler.h =================================================================== --- ccid-1.4.5.orig/src/ccid_ifdhandler.h 2010-06-04 14:31:15.000000000 +0200 +++ ccid-1.4.5/src/ccid_ifdhandler.h 2012-01-24 21:25:58.287191632 +0100 @@ -59,4 +59,9 @@ CcidDesc *get_ccid_slot(unsigned int reader_index); #endif +#ifndef FEATURE_EXECUTE_PACE +#define FEATURE_EXECUTE_PACE 0x20 +#endif +#define IOCTL_FEATURE_EXECUTE_PACE \ + SCARD_CTL_CODE(FEATURE_EXECUTE_PACE + CLASS2_IOCTL_MAGIC) Index: ccid-1.4.5/src/commands.c =================================================================== --- ccid-1.4.5.orig/src/commands.c 2011-08-24 11:15:36.000000000 +0200 +++ ccid-1.4.5/src/commands.c 2012-01-24 21:26:31.815357930 +0100 @@ -75,6 +75,18 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); +static RESPONSECODE SecurePINPACE(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength, + unsigned char bPINOperation); + +static RESPONSECODE transform_EstablishPACEChannel_InputData( + unsigned char input[], unsigned int input_length); + +static RESPONSECODE transform_EstablishPACEChannel_OutputData( + unsigned char output[], unsigned int output_length); + +static void i2w(uint16_t value, unsigned char *buffer); static void i2dw(int value, unsigned char *buffer); static unsigned int bei2i(unsigned char *buffer); @@ -739,6 +751,341 @@ return ret; } /* SecurePINModify */ +static RESPONSECODE transform_EstablishPACEChannel_InputData( + unsigned char input[], unsigned int input_length) +{ + uint8_t lengthCHAT, lengthPIN; + uint16_t lengthCertificateDescription; + size_t parsed = 0; + + /* transform length fields of input data to little endian */ + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + switch (input[parsed]) { + case 0x01: + DEBUG_COMM("Initiating PACE with MRZ"); + break; + case 0x02: + DEBUG_COMM("Initiating PACE with CAN"); + break; + case 0x03: + DEBUG_COMM("Initiating PACE with PIN"); + break; + case 0x04: + DEBUG_COMM("Initiating PACE with PUK"); + break; + default: + DEBUG_COMM("Initiating PACE with unknown PACE secret type"); + break; + } + parsed += 1; + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCHAT = input[parsed]; + parsed += 1; + + if (input_length < parsed+lengthCHAT) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCHAT) + DEBUG_INFO_XXD("CHAT:\n", &input[parsed], lengthCHAT); + parsed += lengthCHAT; + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + lengthPIN = input[parsed]; + parsed += 1; + + if (input_length < parsed+lengthPIN) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } +#if 0 + /* dont print secrets... */ + if (lengthPIN) + DEBUG_INFO_XXD("PIN:\n", &input[parsed], lengthPIN); +#endif + parsed += lengthPIN; + + if (input_length < parsed+2) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + memcpy(&lengthCertificateDescription, &input[parsed], 2); + i2w(lengthCertificateDescription, &input[parsed]); + parsed += 2; + + if (input_length < parsed+lengthCertificateDescription) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCertificateDescription) + DEBUG_INFO_XXD("Certificate description:\n", &input[parsed], lengthCertificateDescription); + parsed += lengthCertificateDescription; + + if (parsed < input_length) { + DEBUG_CRITICAL2("Overrun by %u bytes", input_length - parsed); + return IFD_COMMUNICATION_ERROR; + } + + return IFD_SUCCESS; +} + +static RESPONSECODE transform_EstablishPACEChannel_OutputData( + unsigned char output[], unsigned int output_length) +{ + uint8_t lengthCAR, lengthCARprev; + uint16_t lengthOutputData, lengthEF_CardAccess, length_IDicc; + uint32_t result; + size_t parsed = 0; + + if (parsed+4 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + result = dw2i(output, parsed); + memcpy(&output[parsed], &result, 4); + DEBUG_INFO2("EstablishPACEChannel Result: %08X", result); + parsed += 4; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthOutputData = w2i(output, parsed); + if ((unsigned int)lengthOutputData+6 != output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + parsed += 2; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", + output[parsed+0], output[parsed+1]); + parsed += 2; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthEF_CardAccess = w2i(output, parsed); + memcpy(&output[parsed], &lengthEF_CardAccess, 2); + parsed += 2; + + if (parsed+lengthEF_CardAccess > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthEF_CardAccess) + DEBUG_INFO_XXD("EF.CardAccess:\n", &output[parsed], lengthEF_CardAccess); + parsed += lengthEF_CardAccess; + + if (parsed+1 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCAR = output[parsed]; + parsed += 1; + + if (parsed+lengthCAR > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCAR) + DEBUG_INFO_XXD("Recent Certificate Authority:\n", + &output[parsed], lengthCAR); + parsed += lengthCAR; + + if (parsed+1 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCARprev = output[parsed]; + parsed += 1; + + if (parsed+lengthCARprev > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCARprev) + DEBUG_INFO_XXD("Previous Certificate Authority:\n", + &output[parsed], lengthCARprev); + parsed += lengthCARprev; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + length_IDicc = w2i(output, parsed); + memcpy(&output[parsed], &length_IDicc, 2); + parsed += 2; + + if (parsed+length_IDicc > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (length_IDicc) + DEBUG_INFO_XXD("IDicc:\n", &output[parsed], length_IDicc); + parsed += length_IDicc; + + if (parsed < output_length) { + DEBUG_CRITICAL2("Overrun by %u bytes", output_length - parsed); + return IFD_COMMUNICATION_ERROR; + } + + return IFD_SUCCESS; +} + +RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength) +{ + /* bPINOperation: PIN PACE Capabilities */ + RESPONSECODE return_value; + int old_read_timeout; + _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index); + + old_read_timeout= ccid_descriptor -> readTimeout; + ccid_descriptor -> readTimeout = 30*1000; /* 30 seconds */ + + return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); + if (IFD_SUCCESS != return_value) + goto err; + + return_value = SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer, + RxLength, CCID_CLASS_PIN_PACE_EXECUTE); + if (IFD_SUCCESS != return_value) + goto err; + + if (*RxLength < 6) { + DEBUG_CRITICAL("Malformed Establish PACE output buffer."); + return_value = IFD_COMMUNICATION_ERROR; + goto err; + } + + return_value = transform_EstablishPACEChannel_OutputData(RxBuffer, *RxLength); + if (IFD_SUCCESS != return_value) + goto err; + +err: + ccid_descriptor -> readTimeout = old_read_timeout; + return return_value; +} + +RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength) +{ + /* bPINOperation: PIN PACE Capabilities */ + if (*RxLength < 6) { + DEBUG_CRITICAL2("overrun by %d bytes", 6 - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } + + unsigned int length = *RxLength - 6; + RESPONSECODE r = SecurePINPACE(reader_index, TxBuffer, TxLength, + RxBuffer+6, &length, CCID_CLASS_PIN_PACE_CAPABILITIES); + if (r != IFD_SUCCESS) + return r; + + uint32_t s = PACE_SUCCESS; + memcpy(RxBuffer, &s, 4); /* Result */ + memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ + *RxLength = length + 6; + + return IFD_SUCCESS; +} + +static RESPONSECODE SecurePINPACE(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength, + unsigned char bPINOperation) +{ + unsigned char cmd[11+0xffff]; + unsigned int length; + _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index); + status_t res; + + cmd[0] = 0x69; /* Secure */ + i2dw(TxLength, cmd+1); + cmd[5] = ccid_descriptor->bCurrentSlotIndex; + cmd[6] = (*ccid_descriptor->pbSeq)++; + cmd[7] = 0; + cmd[8] = 0; + cmd[9] = 0; + cmd[10] = bPINOperation; + + if (sizeof(cmd) < 11+TxLength) + { + DEBUG_CRITICAL2("Too much data in input (overrun by %d bytes)", + 11+TxLength - sizeof(cmd)); + return IFD_COMMUNICATION_ERROR; + } + memcpy(cmd+11, TxBuffer, TxLength); + + res = WritePort(reader_index, 11+TxLength, cmd); + if (res != STATUS_SUCCESS) + { + if (STATUS_NO_SUCH_DEVICE == res) + return IFD_NO_SUCH_DEVICE; + return IFD_COMMUNICATION_ERROR; + } + + length = sizeof(cmd); + res = ReadPort(reader_index, &length, cmd); + if (res != STATUS_SUCCESS) + { + if (STATUS_NO_SUCH_DEVICE == res) + return IFD_NO_SUCH_DEVICE; + return IFD_COMMUNICATION_ERROR; + } + + if (length < STATUS_OFFSET+1) + { + DEBUG_CRITICAL2("Not enough data received: %d bytes", length); + return IFD_COMMUNICATION_ERROR; + } + + if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED) + { + ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */ + return IFD_COMMUNICATION_ERROR; + } + + /* we have read less (or more) data than the CCID frame says to contain */ + if (length-10 != dw2i(cmd, 1)) + { + DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)", + length-10, dw2i(cmd, 1)); + return IFD_COMMUNICATION_ERROR; + } + + length = dw2i(cmd, 1); + if (length <= *RxLength) + *RxLength = length; + else + { + DEBUG_CRITICAL2("overrun by %d bytes", length - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } + + memcpy(RxBuffer, cmd+10, *RxLength); + + return IFD_SUCCESS; +} + /***************************************************************************** * @@ -2123,6 +2470,18 @@ } /* i2dw */ /***************************************************************************** + * + * i2w + * + ****************************************************************************/ +static void i2w(uint16_t value, unsigned char buffer[]) +{ + buffer[0] = value & 0xFF; + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + + +/***************************************************************************** * * bei2i (big endian integer to host order interger) * Index: ccid-1.4.5/src/commands.h =================================================================== --- ccid-1.4.5.orig/src/commands.h 2010-06-04 14:31:15.000000000 +0200 +++ ccid-1.4.5/src/commands.h 2012-01-24 21:25:58.287191632 +0100 @@ -37,6 +37,14 @@ unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); +RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength); + +RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength); + RESPONSECODE CmdEscape(unsigned int reader_index, const unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); Index: ccid-1.4.5/src/ifdhandler.c =================================================================== --- ccid-1.4.5.orig/src/ifdhandler.c 2011-10-11 22:27:44.000000000 +0200 +++ ccid-1.4.5/src/ifdhandler.c 2012-01-24 21:25:58.291191648 +0100 @@ -66,6 +66,73 @@ static unsigned int T1_card_timeout(double f, double d, int TC1, int BWI, int CWI, int clock_frequency); static int get_IFSC(ATR_t *atr, int *i); +static RESPONSECODE do_feature_execute_pace(unsigned int reader_index, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned); + +static RESPONSECODE do_feature_execute_pace(unsigned int reader_index, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned) +{ + uint16_t lengthInputData; + unsigned int i; + RESPONSECODE r; + + if (TxLength < 3 || !TxBuffer) { + DEBUG_CRITICAL("Buffer too small, could not determine length of " + "input data"); + i = PACE_ERROR_LENGTH_INCONSISTENT; + goto err; + } + + memcpy(&lengthInputData, &TxBuffer[1], 2); + + if (TxLength != 3+lengthInputData) { + DEBUG_CRITICAL3("Buffer too small or too big to contain only " + "function index and input data (expected %u, got %u)", + 3+lengthInputData, TxLength); + i = PACE_ERROR_LENGTH_INCONSISTENT; + goto err; + } + + switch(*TxBuffer) { + case 1: + i = RxLength; + r = SecurePINPACECapabilities(reader_index, + TxBuffer+3, lengthInputData, RxBuffer, &i); + *pdwBytesReturned = i; + return r; + + case 2: + i = RxLength; + r = SecurePINPACEVerify(reader_index, TxBuffer+3, + lengthInputData, RxBuffer, &i); + *pdwBytesReturned = i; + return r; + + default: + DEBUG_CRITICAL2("Unknown PACE function %u", + (unsigned char)*TxBuffer); + if (RxLength < 6 || !RxBuffer) { + DEBUG_CRITICAL2("Need %u more bytes in RxBuffer", + RxLength>6 ? (unsigned int)6-RxLength : 0); + return IFD_COMMUNICATION_ERROR; + } + + i = PACE_ERROR_UNEXPECTED_DATA; + goto err; + } + +err: + memcpy(RxBuffer, &i, 4); + memset(RxBuffer + 4, 0, 2); + + *pdwBytesReturned = 6; + + return IFD_SUCCESS; +} + + EXTERNAL RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR lpcDevice) @@ -1412,6 +1479,17 @@ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); } + if (ccid_descriptor -> bPINSupport & CCID_CLASS_PIN_PACE_CAPABILITIES) + { + pcsc_tlv -> tag = FEATURE_EXECUTE_PACE; + pcsc_tlv -> length = 0x04; /* always 0x04 */ + pcsc_tlv -> value = htonl(IOCTL_FEATURE_EXECUTE_PACE); + + pcsc_tlv++; + iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); + } + + /* We can always forward wLcdLayout */ pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES; pcsc_tlv -> length = 0x04; /* always 0x04 */ @@ -1613,6 +1691,12 @@ } } + if (IOCTL_FEATURE_EXECUTE_PACE == dwControlCode) + { + return_value = do_feature_execute_pace(reader_index, TxBuffer, + TxLength, RxBuffer, RxLength, pdwBytesReturned); + } + if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; vsmartcard-3.3/ccid/patches/pcsc-lite-1.6.1.patch0000644000175000017500000000103413546304763020106 0ustar philphilIndex: pcsc-lite-1.6.1/src/PCSC/reader.h.in =================================================================== --- pcsc-lite-1.6.1/src/PCSC/reader.h.in (Revision 4978) +++ pcsc-lite-1.6.1/src/PCSC/reader.h.in (Arbeitskopie) @@ -121,6 +121,7 @@ #define FEATURE_IFD_DISPLAY_PROPERTIES 0x11 #define FEATURE_GET_TLV_PROPERTIES 0x12 #define FEATURE_CCID_ESC_COMMAND 0x13 +#define FEATURE_EXECUTE_PACE 0x20 /* structures used (but not defined) in PC/SC Part 10: * "IFDs with Secure Pin Entry Capabilities" */ vsmartcard-3.3/ccid/patches/pcsc-lite-1.5.5.patch0000644000175000017500000000105513546304763020114 0ustar philphilIndex: pcsc-lite-1.5.5/src/PCSC/reader.h.in =================================================================== --- pcsc-lite-1.5.5/src/PCSC/reader.h.in (Revision 4345) +++ pcsc-lite-1.5.5/src/PCSC/reader.h.in (Arbeitskopie) @@ -118,6 +118,7 @@ #define FEATURE_WRITE_DISPLAY 0x0F #define FEATURE_GET_KEY 0x10 #define FEATURE_IFD_DISPLAY_PROPERTIES 0x11 +#define FEATURE_EXECUTE_PACE 0x20 /* structures used (but not defined) in PC/SC Part 10 revision 2.02.05: * "IFDs with Secure Pin Entry Capabilities" */ vsmartcard-3.3/ccid/patches/ccid-1.4.4.patch0000644000175000017500000004634113546304763017140 0ustar philphilIndex: ccid-1.4.4/src/ccid.h =================================================================== --- ccid-1.4.4.orig/src/ccid.h 2011-05-13 10:56:01.000000000 +0200 +++ ccid-1.4.4/src/ccid.h 2011-09-02 16:07:03.000000000 +0200 @@ -142,8 +142,10 @@ #define CCID_CLASS_EXCHANGE_MASK 0x00070000 /* Features from bPINSupport */ -#define CCID_CLASS_PIN_VERIFY 0x01 -#define CCID_CLASS_PIN_MODIFY 0x02 +#define CCID_CLASS_PIN_VERIFY 0x01 +#define CCID_CLASS_PIN_MODIFY 0x02 +#define CCID_CLASS_PIN_PACE_CAPABILITIES 0x10 +#define CCID_CLASS_PIN_PACE_EXECUTE 0x20 /* See CCID specs ch. 4.2.1 */ #define CCID_ICC_PRESENT_ACTIVE 0x00 /* 00 0000 00 */ @@ -154,6 +156,25 @@ #define CCID_COMMAND_FAILED 0x40 /* 01 0000 00 */ #define CCID_TIME_EXTENSION 0x80 /* 10 0000 00 */ +#define PACE_SUCCESS 0x00000000 +#define PACE_ERROR_LENGTH_INCONSISTENT 0xD0000001 +#define PACE_ERROR_UNEXPECTED_DATA 0xD0000002 +#define PACE_ERROR_UNEXPECTED_DATA_COMBINATION 0xD0000003 +#define PACE_ERROR_CARD_NOT_SUPPORTED 0xE0000001 +#define PACE_ERROR_ALGORITH_NOT_SUPPORTED 0xE0000002 +#define PACE_ERROR_PINID_NOT_SUPPORTED 0xE0000003 +#define PACE_ERROR_SELECT_EF_CARDACCESS 0xF0000000 +#define PACE_ERROR_READ_BINARY 0xF0010000 +#define PACE_ERROR_MSE_SET_AT 0xF0020000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_1 0xF0030000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_2 0xF0040000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_3 0xF0050000 +#define PACE_ERROR_GENERAL_AUTHENTICATE_4 0xF0060000 +#define PACE_ERROR_COMMUNICATION 0xF0100001 +#define PACE_ERROR_NO_CARD 0xF0100002 +#define PACE_ERROR_ABORTED 0xF0200001 +#define PACE_ERROR_TIMEOUT 0xF0200002 + /* bInterfaceProtocol for ICCD */ #define PROTOCOL_CCID 0 /* plain CCID */ #define PROTOCOL_ICCD_A 1 /* ICCD Version A */ @@ -230,6 +251,8 @@ /* convert a 4 byte integer in USB format into an int */ #define dw2i(a, x) (unsigned int)((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x]) +/* convert a 2 byte integer in USB format into an int */ +#define w2i(a, x) (unsigned int)(((a[x+1]) << 8) + a[x]) /* all the data rates specified by ISO 7816-3 Fi/Di tables */ #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ Index: ccid-1.4.4/src/ccid_ifdhandler.h =================================================================== --- ccid-1.4.4.orig/src/ccid_ifdhandler.h 2010-06-04 14:31:15.000000000 +0200 +++ ccid-1.4.4/src/ccid_ifdhandler.h 2011-09-02 16:07:03.000000000 +0200 @@ -59,4 +59,9 @@ CcidDesc *get_ccid_slot(unsigned int reader_index); #endif +#ifndef FEATURE_EXECUTE_PACE +#define FEATURE_EXECUTE_PACE 0x20 +#endif +#define IOCTL_FEATURE_EXECUTE_PACE \ + SCARD_CTL_CODE(FEATURE_EXECUTE_PACE + CLASS2_IOCTL_MAGIC) Index: ccid-1.4.4/src/commands.c =================================================================== --- ccid-1.4.4.orig/src/commands.c 2011-02-22 23:20:26.000000000 +0100 +++ ccid-1.4.4/src/commands.c 2011-09-02 16:07:03.000000000 +0200 @@ -75,6 +75,18 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); +static RESPONSECODE SecurePINPACE(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength, + unsigned char bPINOperation); + +static RESPONSECODE transform_EstablishPACEChannel_InputData( + unsigned char input[], unsigned int input_length); + +static RESPONSECODE transform_EstablishPACEChannel_OutputData( + unsigned char output[], unsigned int output_length); + +static void i2w(uint16_t value, unsigned char *buffer); static void i2dw(int value, unsigned char *buffer); static unsigned int bei2i(unsigned char *buffer); @@ -753,6 +765,341 @@ return ret; } /* SecurePINModify */ +static RESPONSECODE transform_EstablishPACEChannel_InputData( + unsigned char input[], unsigned int input_length) +{ + uint8_t lengthCHAT, lengthPIN; + uint16_t lengthCertificateDescription; + size_t parsed = 0; + + /* transform length fields of input data to little endian */ + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + switch (input[parsed]) { + case 0x01: + DEBUG_COMM("Initiating PACE with MRZ"); + break; + case 0x02: + DEBUG_COMM("Initiating PACE with CAN"); + break; + case 0x03: + DEBUG_COMM("Initiating PACE with PIN"); + break; + case 0x04: + DEBUG_COMM("Initiating PACE with PUK"); + break; + default: + DEBUG_COMM("Initiating PACE with unknown PACE secret type"); + break; + } + parsed += 1; + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCHAT = input[parsed]; + parsed += 1; + + if (input_length < parsed+lengthCHAT) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCHAT) + DEBUG_INFO_XXD("CHAT:\n", &input[parsed], lengthCHAT); + parsed += lengthCHAT; + + if (input_length < parsed+1) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + lengthPIN = input[parsed]; + parsed += 1; + + if (input_length < parsed+lengthPIN) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } +#if 0 + /* dont print secrets... */ + if (lengthPIN) + DEBUG_INFO_XXD("PIN:\n", &input[parsed], lengthPIN); +#endif + parsed += lengthPIN; + + if (input_length < parsed+2) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + memcpy(&lengthCertificateDescription, &input[parsed], 2); + i2w(lengthCertificateDescription, &input[parsed]); + parsed += 2; + + if (input_length < parsed+lengthCertificateDescription) { + DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCertificateDescription) + DEBUG_INFO_XXD("Certificate description:\n", &input[parsed], lengthCertificateDescription); + parsed += lengthCertificateDescription; + + if (parsed < input_length) { + DEBUG_CRITICAL2("Overrun by %u bytes", input_length - parsed); + return IFD_COMMUNICATION_ERROR; + } + + return IFD_SUCCESS; +} + +static RESPONSECODE transform_EstablishPACEChannel_OutputData( + unsigned char output[], unsigned int output_length) +{ + uint8_t lengthCAR, lengthCARprev; + uint16_t lengthOutputData, lengthEF_CardAccess, length_IDicc; + uint32_t result; + size_t parsed = 0; + + if (parsed+4 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + result = dw2i(output, parsed); + memcpy(&output[parsed], &result, 4); + DEBUG_INFO2("EstablishPACEChannel Result: %08X", result); + parsed += 4; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthOutputData = w2i(output, parsed); + if ((unsigned int)lengthOutputData+6 != output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + parsed += 2; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", + output[parsed+0], output[parsed+1]); + parsed += 2; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthEF_CardAccess = w2i(output, parsed); + memcpy(&output[parsed], &lengthEF_CardAccess, 2); + parsed += 2; + + if (parsed+lengthEF_CardAccess > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthEF_CardAccess) + DEBUG_INFO_XXD("EF.CardAccess:\n", &output[parsed], lengthEF_CardAccess); + parsed += lengthEF_CardAccess; + + if (parsed+1 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCAR = output[parsed]; + parsed += 1; + + if (parsed+lengthCAR > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCAR) + DEBUG_INFO_XXD("Recent Certificate Authority:\n", + &output[parsed], lengthCAR); + parsed += lengthCAR; + + if (parsed+1 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + lengthCARprev = output[parsed]; + parsed += 1; + + if (parsed+lengthCARprev > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (lengthCARprev) + DEBUG_INFO_XXD("Previous Certificate Authority:\n", + &output[parsed], lengthCARprev); + parsed += lengthCARprev; + + if (parsed+2 > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + length_IDicc = w2i(output, parsed); + memcpy(&output[parsed], &length_IDicc, 2); + parsed += 2; + + if (parsed+length_IDicc > output_length) { + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } + if (length_IDicc) + DEBUG_INFO_XXD("IDicc:\n", &output[parsed], length_IDicc); + parsed += length_IDicc; + + if (parsed < output_length) { + DEBUG_CRITICAL2("Overrun by %u bytes", output_length - parsed); + return IFD_COMMUNICATION_ERROR; + } + + return IFD_SUCCESS; +} + +RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength) +{ + /* bPINOperation: PIN PACE Capabilities */ + RESPONSECODE return_value; + int old_read_timeout; + _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index); + + old_read_timeout= ccid_descriptor -> readTimeout; + ccid_descriptor -> readTimeout = 30*1000; /* 30 seconds */ + + return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); + if (IFD_SUCCESS != return_value) + goto err; + + return_value = SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer, + RxLength, CCID_CLASS_PIN_PACE_EXECUTE); + if (IFD_SUCCESS != return_value) + goto err; + + if (*RxLength < 6) { + DEBUG_CRITICAL("Malformed Establish PACE output buffer."); + return_value = IFD_COMMUNICATION_ERROR; + goto err; + } + + return_value = transform_EstablishPACEChannel_OutputData(RxBuffer, *RxLength); + if (IFD_SUCCESS != return_value) + goto err; + +err: + ccid_descriptor -> readTimeout = old_read_timeout; + return return_value; +} + +RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength) +{ + /* bPINOperation: PIN PACE Capabilities */ + if (*RxLength < 6) { + DEBUG_CRITICAL2("overrun by %d bytes", 6 - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } + + unsigned int length = *RxLength - 6; + RESPONSECODE r = SecurePINPACE(reader_index, TxBuffer, TxLength, + RxBuffer+6, &length, CCID_CLASS_PIN_PACE_CAPABILITIES); + if (r != IFD_SUCCESS) + return r; + + uint32_t s = PACE_SUCCESS; + memcpy(RxBuffer, &s, 4); /* Result */ + memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ + *RxLength = length + 6; + + return IFD_SUCCESS; +} + +static RESPONSECODE SecurePINPACE(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength, + unsigned char bPINOperation) +{ + unsigned char cmd[11+0xffff]; + unsigned int length; + _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index); + status_t res; + + cmd[0] = 0x69; /* Secure */ + i2dw(TxLength, cmd+1); + cmd[5] = ccid_descriptor->bCurrentSlotIndex; + cmd[6] = (*ccid_descriptor->pbSeq)++; + cmd[7] = 0; + cmd[8] = 0; + cmd[9] = 0; + cmd[10] = bPINOperation; + + if (sizeof(cmd) < 11+TxLength) + { + DEBUG_CRITICAL2("Too much data in input (overrun by %d bytes)", + 11+TxLength - sizeof(cmd)); + return IFD_COMMUNICATION_ERROR; + } + memcpy(cmd+11, TxBuffer, TxLength); + + res = WritePort(reader_index, 11+TxLength, cmd); + if (res != STATUS_SUCCESS) + { + if (STATUS_NO_SUCH_DEVICE == res) + return IFD_NO_SUCH_DEVICE; + return IFD_COMMUNICATION_ERROR; + } + + length = sizeof(cmd); + res = ReadPort(reader_index, &length, cmd); + if (res != STATUS_SUCCESS) + { + if (STATUS_NO_SUCH_DEVICE == res) + return IFD_NO_SUCH_DEVICE; + return IFD_COMMUNICATION_ERROR; + } + + if (length < STATUS_OFFSET+1) + { + DEBUG_CRITICAL2("Not enough data received: %d bytes", length); + return IFD_COMMUNICATION_ERROR; + } + + if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED) + { + ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */ + return IFD_COMMUNICATION_ERROR; + } + + /* we have read less (or more) data than the CCID frame says to contain */ + if (length-10 != dw2i(cmd, 1)) + { + DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)", + length-10, dw2i(cmd, 1)); + return IFD_COMMUNICATION_ERROR; + } + + length = dw2i(cmd, 1); + if (length <= *RxLength) + *RxLength = length; + else + { + DEBUG_CRITICAL2("overrun by %d bytes", length - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } + + memcpy(RxBuffer, cmd+10, *RxLength); + + return IFD_SUCCESS; +} + /***************************************************************************** * @@ -2155,6 +2502,18 @@ } /* i2dw */ /***************************************************************************** + * + * i2w + * + ****************************************************************************/ +static void i2w(uint16_t value, unsigned char buffer[]) +{ + buffer[0] = value & 0xFF; + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + + +/***************************************************************************** * * bei2i (big endian integer to host order interger) * Index: ccid-1.4.4/src/commands.h =================================================================== --- ccid-1.4.4.orig/src/commands.h 2010-06-04 14:31:15.000000000 +0200 +++ ccid-1.4.4/src/commands.h 2011-09-02 16:07:03.000000000 +0200 @@ -37,6 +37,14 @@ unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); +RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength); + +RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, + unsigned char TxBuffer[], unsigned int TxLength, + unsigned char RxBuffer[], unsigned int *RxLength); + RESPONSECODE CmdEscape(unsigned int reader_index, const unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); Index: ccid-1.4.4/src/ifdhandler.c =================================================================== --- ccid-1.4.4.orig/src/ifdhandler.c 2011-05-11 11:46:00.000000000 +0200 +++ ccid-1.4.4/src/ifdhandler.c 2011-09-02 16:12:56.000000000 +0200 @@ -65,6 +65,73 @@ static unsigned int T1_card_timeout(double f, double d, int TC1, int BWI, int CWI, int clock_frequency); static int get_IFSC(ATR_t *atr, int *i); +static RESPONSECODE do_feature_execute_pace(unsigned int reader_index, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned); + +static RESPONSECODE do_feature_execute_pace(unsigned int reader_index, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned) +{ + uint16_t lengthInputData; + unsigned int i; + RESPONSECODE r; + + if (TxLength < 3 || !TxBuffer) { + DEBUG_CRITICAL("Buffer too small, could not determine length of " + "input data"); + i = PACE_ERROR_LENGTH_INCONSISTENT; + goto err; + } + + memcpy(&lengthInputData, &TxBuffer[1], 2); + + if (TxLength != 3+lengthInputData) { + DEBUG_CRITICAL3("Buffer too small or too big to contain only " + "function index and input data (expected %u, got %u)", + 3+lengthInputData, TxLength); + i = PACE_ERROR_LENGTH_INCONSISTENT; + goto err; + } + + switch(*TxBuffer) { + case 1: + i = RxLength; + r = SecurePINPACECapabilities(reader_index, + TxBuffer+3, lengthInputData, RxBuffer, &i); + *pdwBytesReturned = i; + return r; + + case 2: + i = RxLength; + r = SecurePINPACEVerify(reader_index, TxBuffer+3, + lengthInputData, RxBuffer, &i); + *pdwBytesReturned = i; + return r; + + default: + DEBUG_CRITICAL2("Unknown PACE function %u", + (unsigned char)*TxBuffer); + if (RxLength < 6 || !RxBuffer) { + DEBUG_CRITICAL2("Need %u more bytes in RxBuffer", + RxLength>6 ? (unsigned int)6-RxLength : 0); + return IFD_COMMUNICATION_ERROR; + } + + i = PACE_ERROR_UNEXPECTED_DATA; + goto err; + } + +err: + memcpy(RxBuffer, &i, 4); + memset(RxBuffer + 4, 0, 2); + + *pdwBytesReturned = 6; + + return IFD_SUCCESS; +} + + EXTERNAL RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR lpcDevice) @@ -1400,6 +1467,17 @@ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); } + if (ccid_descriptor -> bPINSupport & CCID_CLASS_PIN_PACE_CAPABILITIES) + { + pcsc_tlv -> tag = FEATURE_EXECUTE_PACE; + pcsc_tlv -> length = 0x04; /* always 0x04 */ + pcsc_tlv -> value = htonl(IOCTL_FEATURE_EXECUTE_PACE); + + pcsc_tlv++; + iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); + } + + /* We can always forward wLcdLayout */ pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES; pcsc_tlv -> length = 0x04; /* always 0x04 */ @@ -1582,6 +1660,12 @@ } } + if (IOCTL_FEATURE_EXECUTE_PACE == dwControlCode) + { + return_value = do_feature_execute_pace(reader_index, TxBuffer, + TxLength, RxBuffer, RxLength, pdwBytesReturned); + } + if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; vsmartcard-3.3/ccid/COPYING0000644000175000017500000010451313546304763014153 0ustar philphil GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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. This program 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 this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . vsmartcard-3.3/ccid/m4/0000755000175000017500000000000013546304763013434 5ustar philphilvsmartcard-3.3/ccid/m4/Makefile.am0000644000175000017500000000012513546304763015466 0ustar philphil# Process this file with automake to create Makefile.in EXTRA_DIST = acx_pthread.m4 vsmartcard-3.3/ccid/m4/.gitignore0000644000175000017500000000010713546304763015422 0ustar philphil# Ignore everything in this directory * # Except this file !.gitignore vsmartcard-3.3/ccid/m4/acx_pthread.m40000644000175000017500000002237413546304763016170 0ustar philphildnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) dnl dnl @summary figure out how to build C programs using POSIX threads dnl dnl This macro figures out how to build C programs using POSIX threads. dnl It sets the PTHREAD_LIBS output variable to the threads library and dnl linker flags, and the PTHREAD_CFLAGS output variable to any special dnl C compiler flags that are needed. (The user can also force certain dnl compiler flags/libs to be tested by setting these environment dnl variables.) dnl dnl Also sets PTHREAD_CC to any special C compiler that is needed for dnl multi-threaded programs (defaults to the value of CC otherwise). dnl (This is necessary on AIX to use the special cc_r compiler alias.) dnl dnl NOTE: You are assumed to not only compile your program with these dnl flags, but also link it with them as well. e.g. you should link dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS dnl $LIBS dnl dnl If you are only building threads programs, you may wish to use dnl these variables in your default LIBS, CFLAGS, and CC: dnl dnl LIBS="$PTHREAD_LIBS $LIBS" dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" dnl CC="$PTHREAD_CC" dnl dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). dnl dnl ACTION-IF-FOUND is a list of shell commands to run if a threads dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the dnl default action will define HAVE_PTHREAD. dnl dnl Please let the authors know if this macro fails on any platform, or dnl if you have any other suggestions or comments. This macro was based dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. dnl We are also grateful for the helpful feedback of numerous users. dnl dnl @category InstalledPackages dnl @author Steven G. Johnson dnl @version 2006-05-29 dnl @license GPLWithACException AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [acx_pthread_ok=yes]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_TRY_LINK([#include ], [int attr=$attr; return attr;], [attr_name=$attr; break]) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_RESTORE ])dnl ACX_PTHREAD vsmartcard-3.3/docs/0000755000175000017500000000000013546304763013142 5ustar philphilvsmartcard-3.3/docs/npa/0000755000175000017500000000000013546304763013720 5ustar philphilvsmartcard-3.3/docs/npa/README.html0000644000175000017500000001400413546304763015542 0ustar philphil nPA Smart Card Library — vsmartcard 2017-01-16 documentation

nPA Smart Card Library¶

Access the German electronic identity card (neuer Personalausweis/nPA).

The functionality of nPA Smart Card Library has been integrated into OpenSC. Developement and Support will continue at our new home https://github.com/frankmorgner/OpenSC.

Back to top

© Copyright 2009-2017 by Dominik Oepen and Frank Morgner.

vsmartcard-3.3/docs/ccid/0000755000175000017500000000000013546304763014044 5ustar philphilvsmartcard-3.3/docs/ccid/README.html0000644000175000017500000007621513546304763015702 0ustar philphil USB CCID Emulator — vsmartcard 2017-01-16 documentation

USB CCID Emulator¶

The USB CCID Emulator forwards a locally present PC/SC smart card reader as a standard USB CCID reader. USB CCID Emulator can be used as trusted intermediary enabling secure PIN entry and PIN modification. In combination with OpenSC [2] also PACE can be performed by the emulator.

\input{$wd/bilder/tikzstyles.tex}
\tikzstyle{bla}=[kleiner, text width=.45\textwidth]

\node (reader)
{\includegraphics[width=1cm]{$wd/bilder/my_cardreader.pdf}};
\node (readertext) [right=0of reader, bla]
{Smartphone provides smart card reader via USB};
\node (display) [below=0of reader]
{\includegraphics[width=1cm]{$wd/bilder/display.pdf}};
\node (displaytext) [right=0of display, bla]
{Secure display of service provider and purpose of transaction};
\node (keyboard) [below=0of display]
{\includegraphics[width=1cm]{$wd/bilder/keyboard.pdf}};
\node (keyboardtext) [right=0of keyboard, bla]
{Secure PIN Entry};
\node (firewall) [below=0of keyboard]
{\includegraphics[width=1cm]{$wd/bilder/Firewall.pdf}};
\node (firewalltext) [right=0of firewall, bla]
{Verification of terminal authentication and sanitiy checks};

\node (features) [fit=(display) (keyboard) (reader) (firewall)] {};

\node (moko) [left=0of features.west] {\includegraphics[height=4cm]{$wd/bilder/phone-fic-neo-freerunner.pdf}};

\node (epa) [left=1.5of moko, yshift=-2cm]
{\includegraphics[width=3cm]{$wd/bilder/nPA_VS.png}};
\node (pc)  [left=1.5of moko, yshift=1.5cm]
{\includegraphics[width=3cm]{$wd/bilder/computer-tango.pdf}};

\begin{pgfonlayer}{background}

    \node (mokobox)
    [box,
    fit=(moko) (readertext) (displaytext) (keyboardtext) (firewalltext)
    (features)] {};

    \draw [usb]
    (moko) -- (pc.center) ;
    \draw [decorate, decoration={expanding waves, angle=20, segment length=6}, nichtrundelinie]
    (moko) -- (epa) ;

\end{pgfonlayer}

Portable smart card reader with trusted user interface

If the machine running ccid-emulator is in USB device mode, a local reader is forwareded via USB to another machine. If in USB host mode, the USB CCID reader will locally be present.

Applications on Windows and Unix-like systems can access the USB CCID Emulator through PC/SC as if it was a real smart card reader. No installation of a smart card driver is required since USB CCID drivers are usually shipped with the modern OS.

Here is a subset of USB CCID commands supported by the USB CCID Emulator with their PC/SC counterpart:

USB CCID PC/SC
PC_to_RDR_XfrBlock SCardTransmit
PC_to_RDR_Secure FEATURE_VERIFY_PIN_DIRECT, FEATURE_MODIFY_PIN_DIRECT
PC_to_RDR_Secure (proprietary) FEATURE_EXECUTE_PACE

PIN verification/modification and PACE can also be started by the application transmitting (SCardTransmit) specially crafted APDUs. Only the alternative initialization of PACE using SCardControl requires patching the driver (available for libccid, see patches). The pseudo APDUs with no need for patches are defined as follows (see BSI TR-03119 1.3 [6] p. 33-34):

  Command APDU Response APDU
CLA INS P1 P2 Command Data Response Data SW1/SW2
GetReaderPACECapabilities 0xFF 0x9A 0x04 0x01 (No Data) PACECapabilities 0x9000 or other in case of an error
EstablishPACEChannel 0xFF 0x9A 0x04 0x02 EstablishPACEChannelInput EstablishPACEChannelOutput
DestroyPACEChannel 0xFF 0x9A 0x04 0x03 (No Data) (No Data)
Verify/Modify PIN 0xFF 0x9A 0x04 0x10 Coding as PC_to_RDR_Secure Coding as RDR_to_PC_DataBlock

The USB CCID Emulator is implemented using GadgetFS [1]. Some fragments of the source code are based on the GadgetFS example and on the source code of the OpenSC tools.

\input{$wd/bilder/tikzstyles.tex}
\tikzstyle{schicht}=[text width=5cm, align=right]
\tikzstyle{fade down}=[path fading=south, color=huslateblue]

    \node (kernel)
[box, shape=rectangle split, rectangle split parts=3, kleiner]
    {Linux  Kernel
    \nodepart{second}
\footnotesize S3C24xx Controller Driver
    \nodepart{third}
\footnotesize GadgetFS
    };

    \node (ccid)
    [aktivbox, shape=rectangle split, rectangle split parts=2, below=of kernel]
    {CCID Emulator
    \nodepart{second}
\texttt{usb}\qquad\texttt{ccid}
    };
    \draw [box] ($(ccid.text split)-(.05cm,0)$) -- ($(ccid.south)-(.05cm,0)$);

    \node (opensc) [box, below=of ccid, kleiner] {OpenSC};

\node (controller) [klein, right=0of kernel.two east, schicht]
{Driver for USB Controller};
\node (gadget) [klein, right=0of kernel.three east, schicht]
{Gadget Driver};
\node (upper) [klein, right=0of kernel.three east, schicht, yshift=-1.75cm]
{Upper Layers};

\tikzstyle{rechts}=[to path={-- ++(1,0) |- (\tikztotarget)}]
\tikzstyle{links}=[to path={-- ++(-1,0) |- (\tikztotarget)}]
\begin{pgfonlayer}{background}
    \path
    (ccid.two west) edge [links, linie] (kernel.three west)
    (ccid.two east) edge [rechts, linie] (opensc.east)
    ;

    \path [color=black!30]
    (controller.north east) edge +(-9,0)
    (gadget.north east) edge +(-9,0)
    (upper.north east) edge +(-9,0)
    ;
\end{pgfonlayer}

\node [kleiner, anchor=east, text width=3cm]
at ($($(ccid.two west)+(-3,0)$)!.5!(kernel.three west)$)
{\color{hublue}
\texttt{/dev/gadget/ep1-bulk}\\
\texttt{/dev/gadget/ep2-bulk}\\
\texttt{/dev/gadget/ep3-bulk}\\};

Software stack of the USB CCID Emulator running on the OpenMoko Neo FreeRunner

Running the USB CCID Emulator has the following dependencies:

Whereas using the USB CCID Emulator on the host system as smart card reader only needs a usable PC/SC middleware with USB CCID driver. This is the case for most modern Windows and Unix-like systems by default.

\input{$wd/bilder/tikzstyles.tex}
\tikzstyle{keks}=[to path={-- ++(.1,0) |- (\tikztotarget)}]

\tikzstyle{bla}=[shape=rectangle split, rectangle split parts=2,
every text node part/.style={align=center, klein}, text width=7cm,
every second node part/.style={kleiner}, inner sep=0pt]

\node (ccid-emulator)
{\texttt{ccid-emulator}};

\node (basis) [below=3of ccid-emulator]
{\includegraphics[keepaspectratio, height=2cm,
    width=2cm]{$wd/bilder/moko/basisleser_plain_klein.png}};
\node (basisbeschreibung) [below=0cm of basis, kleiner, text width=2cm]
{Reiner SCT RFID basis};

\node (npa) [left=1.5of basis]
{\includegraphics[keepaspectratio, height=3cm,
    width=3cm]{$wd/bilder/nPA_VS.png}};
\node (npabeschreibung) [below=0cm of npa, kleiner]
{German identity card};

\node (funktionenchat) [right=.6cm of ccid-emulator.east, anchor=text west, bla]
{
    PACE
    \nodepart{second}
    \begin{itemize}

    \item Display CHAT
        \begin{itemize}
            \item Display context (eID/eSign)
            \item Display requested permissions
        \end{itemize}

        \item Display certificate description
        \begin{itemize}
            \item Identification of service provider
            \item Display purpose of transaction
        \end{itemize}

        \item Secure PIN entry
    \end{itemize}
};
\node (funktionenpace) [below=.5 of funktionenchat, bla]
{
    Terminal Authentication
    \nodepart{second}
            \begin{itemize}
        \item Verify authenticy of terminal
        \item Check freshness of cv certificate
    \end{itemize}
};

\begin{pgfonlayer}{background}
    \node (box) [fit=(ccid-emulator) (basis) (basisbeschreibung)
    (funktionenchat) (funktionenpace), box, inner sep=.5cm] {};
    \node (boxbild) at (box.north west)
    {\includegraphics[keepaspectratio, height=1.5cm,
    width=1.5cm]{$wd/bilder/moko/moko_reader.png}};
    \node [right=0cm of boxbild.east, yshift=.3cm]
    {Openmoko Neo FreeRunner};
\end{pgfonlayer}

\node (a) [above=1of npa]
    {\includegraphics[keepaspectratio, height=3cm,
    width=3cm]{$wd/bilder/computer-tango.pdf}};


\begin{pgfonlayer}{background}
    \path
    (ccid-emulator) edge [doppelpfeil] (basis)
    (basis) edge [rfid] (npa)
    (a.center) edge [usb] (ccid-emulator)
    (ccid-emulator.east) edge [pfeil, keks] (funktionenchat.text west)
    (ccid-emulator.east) edge [pfeil, keks] (funktionenpace.text west);
\end{pgfonlayer}

Implementation of a mobile smart card reader for the German ID card

Download¶

You can find the latest release of USB CCID Emulator on Github. Older releases are still available on Sourceforge.

Alternatively, you can clone our git repository:

git clone https://github.com/frankmorgner/vsmartcard.git

Installation¶

Installation on Linux, Unix and similar¶

The USB CCID Emulator uses the GNU Build System to compile and install. If you are unfamiliar with it, please have a look at INSTALL. If you can not find it, you are probably working bleeding edge in the repository. Run the following command in ccid-emulator to get the missing standard auxiliary files:

autoreconf --verbose --install

To configure (configure –help lists possible options), build and install the USB CCID Emulator now do the following:

./configure
make
make install

Hints on GadgetFS¶

To create a USB Gadget in both USB host and USB client mode, you need to load the kernel module gadgetfs. Here is how to get a running version of GadgetFS on a Debian system (see also OpenMoko Wiki [5]):

sudo apt-get install linux-source linux-headers-`uname -r`
sudo tar xjf /usr/src/linux-source-*.tar.bz2
cd linux-source-*/drivers/usb/gadget
# build dummy_hcd and gadgetfs
echo "KDIR := /lib/modules/`uname -r`/build" >> Makefile
echo "PWD := `pwd`" >> Makefile
echo "obj-m := dummy_hcd.o gadgetfs.o" >> Makefile
echo "default: " >> Makefile
echo -e "\t\$(MAKE) -C \$(KDIR) SUBDIRS=\$(PWD) modules" >> Makefile
make
# load GadgetFS with its dependencies
sudo modprobe udc-core
sudo insmod ./dummy_hcd.ko
sudo insmod ./gadgetfs.ko default_uid=`id -u`
# mount GadgetFS
sudo mkdir /dev/gadget
sudo mount -t gadgetfs gadgetfs /dev/gadget

On OpenMoko it is likely that you need to patch your kernel. If you also want to switch multiple times between gadgetfs and g_ether, another patch is needed.

If you are using a more recent version of dummy_hcd and get an error loading the module, you maybe want to check out this patch.

Hints on OpenSC¶

USB CCID Emulator needs the OpenSC components to be installed (especially libopensc.so). Here is an example of how to get the standard installation of OpenSC without PACE:

PREFIX=/tmp/install
VSMARTCARD=$PWD/vsmartcard
git clone https://github.com/frankmorgner/vsmartcard.git $VSMARTCARD
cd $VSMARTCARD
git submodule init
git submodule update
cd $VSMARTCARD/ccid/src/opensc
autoreconf --verbose --install
./configure --prefix=$PREFIX
make install && cd -

Now libopensc.so should be located in $PREFIX/lib. Here is how to configure the USB CCID Emulator to use it:

cd $VSMARTCARD/ccid
./configure --prefix=$PREFIX OPENSC_LIBS="-L$PREFIX/lib -lopensc"
make install && cd -

Usage¶

The USB CCID Emulator has various command line options to customize the appearance on the USB host. In order to run the USB CCID Emulator GadgetFS must be loaded and mounted. The USB CCID Emulator is compatible with the unix driver libccid [3] and the Windows USB CCID driver [4]. PIN commands are supported if implemented by the driver.

New in version 0.7: USB CCID Emulator now supports the boxing commands defined in BSI TR-03119 1.3 [6].

USB CCID Emulator 0.8

Emulate a USB CCID compliant smart card reader

Usage: ccid-emulator [OPTIONS]...

  -h, --help               Print help and exit
  -V, --version            Print version and exit
  -i, --info               Print available readers and drivers.  (default=off)
  -r, --reader=INT         Number of the PC/SC reader to use (-1 for
                             autodetect)  (default=`-1')
      --gadgetfs=FILENAME  Directory where GadgetFS is mounted
                             (default=`/dev/gadget')
  -v, --verbose            Use (several times) to be more verbose

Changing the appearance on the Universal Serial Bus:
  -p, --product=INT        USB product ID  (default=`0x3010')
  -e, --vendor=INT         USB vendor ID  (default=`0x0D46')
      --serial=STRING      USB serial number  (default=`random')
      --interface=STRING   USB serial number  (default=`notification status')
      --interrupt          Add interrupt pipe for CCID  (default=off)

Report bugs to https://github.com/frankmorgner/vsmartcard/issues

Written by Frank Morgner <frankmorgner@gmail.com>

Question¶

Do you have questions, suggestions or contributions? Feedback of any kind is more than welcome! Please use our project trackers.

Back to top

© Copyright 2009-2017 by Dominik Oepen and Frank Morgner.

vsmartcard-3.3/docs/index.html0000644000175000017500000003365613546304763015154 0ustar philphil Welcome to the Virtual Smart Card Architecture documentation! — vsmartcard 2017-01-16 documentation

Welcome to the Virtual Smart Card Architecture documentation!¶

Welcome to the Virtual Smart Card Architecture. Virtual Smart Card Architecture is an umbrella project for various projects concerned with the emulation of different types of smart card readers or smart cards themselves.

\input{$wd/bilder/tikzstyles.tex}
\tikzstyle{bla}=[box, klein, rounded rectangle,  inner sep=.3cm]
\node (a) {};

\node[bla, above left=.5cm of a]
(usb) {USB Terminal};

\node[bla, below left=.5cm of a]
(nfc) {NFC Terminal};

\node[bla, rounded rectangle left arc=concave, above right=.5cm of a]
(sc)  {Real Smart Card};

\node[bla, rounded rectangle left arc=concave, below right=.5cm of a]
(vsc) {Virtual Smart Card};

\begin{pgfonlayer}{background}
\path[line width=.8cm,color=hublue!20]
(a.mid) edge [out=180, in=0] (usb.center)
edge [out=180, in=0] (nfc.center)
edge [out=0, in=180] (sc.center)
edge [out=0, in=180] (vsc.center)
;
\end{pgfonlayer}

The Virtual Smart Card Architecture connects different aspects of smart card handling

Currently the following projects are part of Virtual Smart Card Architecture:

Looking for a feature the included programs do not offer? Want to extend the functionality of some library? Apart from requesting a new feature, you can have a look at these programming guides and try yourself:

Travis CI Build Status Image AppVeyor CI Build Status Image Coverity Scan Status

Download¶

You can download the latest release of the Virtual Smart Card Architecture here. Older releases are still available at the old project location.

Alternatively, you can clone our git repository:

git clone https://github.com/frankmorgner/vsmartcard.git

References¶

[Mor12]Frank Morgner. Mobiler chipkartenleser für den neuen personalausweis: Sicherheitsanalyse und erweiterung des “systems npa”. Master’s thesis, Humboldt-Universität zu Berlin, 2012. URL: https://sar.informatik.hu-berlin.de/research/publications/SAR-PR-2012-05/SAR-PR-2012-05_.pdf.
[MO10]Frank Morgner and Dominik Oepen. “die gesamte technik ist sicher”. besitz und wissen: Relay-angriffe auf den neuen personalausweis. In 27th Chaos Communication Congress, 26–31. Chaos Computer Club, 12 2010. URL: http://media.ccc.de/browse/congress/2010/27c3-4297-de-die_gesamte_technik_ist_sicher.html.
[MOMR12]Frank Morgner, Dominik Oepen, Wolf Müller, and Jens-Peter Redlich. Mobile smart card reader using nfc-enabled smartphones. In Andreas. Schmidt, Giovanni Russello, Ioannis Krontiris, and Shiguo Lian, editors, Security and Privacy in Mobile Information and Communication Systems, volume 107 of Lecture Notes of the Institute for Computer Sciences, Social Informatics and Telecommunications Engineering, 24–37. Springer Berlin Heidelberg, 2012. URL: http://sar.informatik.hu-berlin.de/research/publications/SAR-PR-2012-07/SAR-PR-2012-07_.pdf, doi:10.1007/978-3-642-33392-7_3.
[MMO11]Wolf Müller, Frank Morgner, and Dominik Oepen. Mobiles szenario für den neuen personalausweis. In Ulrich Waldmann, editor, Tagungsband zum 21. SIT-SmartCard Workshop, 179–188. Stuttgart, 2011. Fraunhofer-Institut für sichere Informationstechnologie, Fraunhofer Verlag. URL: http://sar.informatik.hu-berlin.de/research/publications/SAR-PR-2011-01/SAR-PR-2011-01.pdf.
[Oep10]Dominik Oepen. Authentisierung im mobilen web: Zur usability eid-basierter authentisierung auf einem nfc handy. Master’s thesis, Humboldt-Universität zu Berlin, Berlin, 2010. URL: http://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2010-11.
[OM11]Dominik Oepen and Frank Morgner. Foss im umfeld des neuen personalausweis. LinuxTag 2011, 2011.

Back to top

© Copyright 2009-2017 by Dominik Oepen and Frank Morgner.

vsmartcard-3.3/docs/_images/0000755000175000017500000000000013546304763014546 5ustar philphilvsmartcard-3.3/docs/_images/inheritance-6bbe035741f5d2dcb113ca7864c78d0280548c16.png.map0000644000175000017500000000057013546304763025612 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-e1d6573d10e97f2502d55eaa993e54e501d1540a.png.map0000644000175000017500000000053413546304763025612 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-8d7ae2bc5a5efc5bac682034d18967034c43784c.png.map0000644000175000017500000000056413546304763025770 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-4ccf04ec0e92318a21cb6d3d419a82fcf6101d07.png.map0000644000175000017500000000152013546304763026011 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-6200e2d9c7f43138ee8cae247df739aec4d9e742.png.map0000644000175000017500000000227513546304763026064 0ustar philphil vsmartcard-3.3/docs/_images/tikz-ae1e764f23cec8b5d67952bc6d8bbe66280e80d1.svg0000644000175000017500000233055213546304763024072 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-a86900bf11776a1a970033d4d69ace6796eff5e9.png.map0000644000175000017500000000144113546304763025721 0ustar philphil vsmartcard-3.3/docs/_images/tikz-b87c5ab6092153f7f845370e9964b266e5d97f55.svg0000644000175000017500000254207313546304763023465 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-4ccf04ec0e92318a21cb6d3d419a82fcf6101d07.png0000644000175000017500000001326213546304763025243 0ustar philphil‰PNG  IHDR UžÁbKGDÿÿÿ ½§“gIDATxœíÝPgþð'€ò#6Èœ´õG±gµÕ¡Öóæ ŠZSÀëݵ¶s\­gÇ9ÇoêÙvêµj›–³©J;#NÇ©W;V;^;­õ·ÕT Z~Œ!@Èóýã™ÛÉm²› &!ÙïûõWv³ù<Ÿýì>ϓ͆ ¢”P–ˆñNü<€a‚P Lð ´–>¼}ûö´´´ µjT*ÕÆ;‹`@²ï¿ÿ¾­­ÍuMð&x»Ý¾nݺ•+W­E€PS\\<Þ) ú;@¹/øˆ@0Á(&x @á1ÁŸ?žã¸¡¡!ÿ†=sæŒJ¥²Ûíþ dl/Çx'âOŠÜ) ý]B »ºž’„ÇŸ››k³Ù¢££ëèÇ?Õ³gÏ.\¸011111qÖ¬Y‡ò{ÁÙ)éÙ¶m›J¥Ú»w¯ «œœ~Ífã8Îã°Ðà06èïaí;Çq&%%¥¨¨¨µµ5ìšsV®}܇—ð˜à=ïäòcª2C åçç/Z´¨£££³³Ód2iµZåàS&÷JzGœNçž={fΜùÏþSðÂÑÑÑÓ§O³Çuuu:.ÈÁÁ¿Ðß!pñ-KccãĉŸ}öÙ0mB>÷J†ÄðBƒ¥¦¦¦¦¦Fz›wß}wæÌ™üâ7"""ZZZØÞ²ûöí›:u*!d„ „µZ­V«ß{ï=~3ör¶822B)­ªªš6m{»g4;;;ù Øö&“)33“ã8½^ÿöÛoóÏÖÖÖfggÇÅÅ=ú裗.]:xð`NNÇqO<ñDSSkH"¸Xª”R›ÍöÊ+¯ Žã¦OŸ~áÂ9¡&L˜022ÒÕÕUXXŸ““³k×.~7y „îînA…Ãn§Äv„9räˆZ­¾|ù²J¥úñÇ]÷ñµ×^«¨¨`k,X°mÛ6ùUòKpV­Zåue@fP|÷*¹7ZQQ¡Óé&OžüÒK/ êL)=~üxLLŒX2b­H7 &XØ?ü0==}Ò¤I/¾ø¢Ýng[,£Ñ˜œœœ––öꫯ{=è¡0¼„ÖßÛÛ}þüy¶¸eË–… R—ÃÉ,_¾¼§§çÞ½{{¸Ç___ßÐÐ0::ÚÞÞž——Ç ÁoßÞÞN9v쥴§§çܹsü³Ï<óLWW—Ýn/--ÍÈÈ(**âYnÒÁÅR¥”–••Í;·¹¹Ùét644ܼySf(JéâÅ‹/^|÷î]³ÙüÈ#¸þÁÁÁ)S¦Ô××ÿôÓOüú°Û)±a–/_^ZZJ)ÍËË㻋ÜÒÒ’šš:<<ÜÚÚš––vêÔ)ùUòKp9Á_¿~ýùçŸç»-ƒþÌþˆø«$P^^^XXØÛÛ{çÎ lܸQp\,KIII^^žX2[ñÚt€š`a—.]jµZoÞ¼™““³yófÖbaaaAAÕjmkkËÉÉÙºu«×ƒ ÃKhMð”ÒU«V½üòË”R§Ó™‘‘Q]]MÝ:ü•+WØÆò;¼«/¿ürÒ¤I®Ûß¾};22r÷îÝV«•ߌ={íÚ5¶øõ×_³Òó‹qqqîù ‚‹¥Úß߯R©N:%Q ±PwîÜ!„\¼x‘-VWW{ÜÍ7n¬]»Ö`0¨Tªùóç766†éNyÜJé­[·¢¢¢Ž=J)ݳgOBB‚à"??ÿàÁƒûÛß6nÜ(v24¸;ENðÇMJJÊÊÊúÓŸþÄÎ.ô÷`ö÷@Ä÷X%÷Fù6Ž9¢×ëùøZ­6!!!==Ýh4šÍf±d<¶âµé5ÁÂò¥Ø¿FF¥Ôjµ Ö ÷Jº¿«÷á%x?U+ÓsÏ=WVVöÖ[oú¨§§G§Ó¥¦¦>ôÐC‡£ªªÊuûeË–?~\«Õº~+UL@ƒƒôw¿tÅ—®’^¯'„\¼xÑjµZ­Ö»wï v\N2[ÃòW|)Z[[YqØû<×õ®ÿEIì  j5.ÃKÈ]ÁGFF–——ïÚµëôéÓ'NœÞ8%%…ríÚµéÓ§B CRR’ÉdúË_þÒÚÚʾ›@¹wïžÃá˜×Eéàb©Úl¶ÊÊJ½^ÏqÜŒ3Ø ™¡:::–,Y¢Ñhßz=wîœZ­¶Ûí]]]«W¯NKK‹‹‹KMM-..f÷¨Ân§ÄvdéÒ¥+V¬œ9?þøþð÷È‚]óZ¥û .M‘÷àÇü%;ýýþû{ â{¬’ ÑþþþÊÊÊôôtF“½sçN÷Jò<&㱯M¨ þ[ôz½>11ñ…^à›èîî.))IJJÒét6lò¸§®=†ýßO®‡½£WÞå €|ÅÅÅÿOþ<ú;„3gÎÌž={ppPpk?\¸/!wî&x ¹/ÙßÏþó Ý³\Á(&x @˜à<€ï[ô111Û·oWÞÚÏão­+ú;@]¸pA°&x¿dAƒè<€a‚P Lð „ @0Á(&x @˜à<€a‚P Lð „ @0Á(&x @˜à<€a‚P Lð „ @0Á(P”`¹¼¼Ün·K*p?Ö¯_?wîÜñÎÂmä{üñÇ×­[çÓK„üÐÐPMMÿR€`¨­­5›Íá5Ác´¯¸¸Ø×—à#z @˜à<€a‚P ¿MðçÏŸç8nhhÈ_™3gΨTªpÿ[¶‡#mñ"4K ódlB*£„@6ÁÍà>ùm‚ÏÍ͵ÙlÑÑÑ‚õaÔg‚ŸêÙ³g.\˜˜˜˜˜˜8kÖ¬C‡ñip. %‚Ò;cÈ$øôî§Ú¾–Èk2cxm„Qß 2Œ6aï¿&%%¥¨¨¨µµU‘Mûe„¿ýˆ~xx8 ñýÈ©Ê 544”ŸŸ¿hÑ¢ŽŽŽÎÎN“ɤÕjùg-‹í¿>ì¯ÜƉù÷|P‰Âè¤Watà‚?Ú„`|‹ÅÒßßߨØ8qâÄgŸ}6@­ŒcÓ!1ÂÓÿµjÕ**éÝwß9s&¿xãÆˆˆˆ–––Ó§OBÙƒ}ûöM:•2aÂBˆZ­V«Õï½÷¿{9[¡”VUUM›6½±2ül{“É”™™Éqœ^¯ûí·ùgkkk³³³ãââ}ôÑK—.þ<[ܲeËÂ… ©KÒìÁòåË{zzîÝ»ç±yìrõõõ £££íííyyy,~ûöövBȱcÇ(¥===çÎãŸ}æ™gºººìv{iiiFFFQQ¿Èr“.–*¥´¬¬lîܹÍÍÍN§³¡¡áæÍ›2CQJ/^¼xñâ»wïšÍæGyÄ½Ë N™2¥   ¾¾þ§Ÿ~â×û4Áó3¨{…¥K''Jiyyyaaaooï;w,X°qãF±ÊH§ç^dÁöwïÞU«Õ?üð[Ü´iÓ¯~õ+O' ÷uwwÛív£Ñøä“ORßOZJiaaaAAÕjmkkËÉÉÙºu«D|ùç¡ÇzJ‡•9„ò?88˜––¶téÒ“'O:N¶£MÐF›@Ä÷:°PÉží»Åb)))ÉËËKÆc+!Þ4ãëïU0&x¶ÍË/¿L)u:ÕÕÕÔ­Ë]¹r…m,¿Ë¹úòË/'MšäºýíÛ·###wïÞmµZùÍØ³×®]c‹_ý5!¤¥¥…_Œ‹‹sÏ_\,Õþþ~•JuêÔ)‰Rˆ…ºsç!äâÅ‹l±ººÚãnÞ¸qcíÚµƒA¥RÍŸ?¿±±‘¥u±yóf‰Òyà=–NN&¬üuÉ‘#Gôz½Xe¤Ós/²ûYþ»ßýníÚµ”R‡ÃñÀ|öÙgbÙJ—èúõël³'NÄÆÆ²Ç>´V«Õõðíß¿ß`0HÄ—yŠÕS:¬2&ø´´4B!$!!áÁ\¹råþóŒ6AmßëÀ"}ÂkµÚ„„„ôôt£Ñh6›Å’ñØJ(7íʧÞ«1LðÂߢ—ã¹çž+++{ë­·NžoÞ<ö?v¨ÕjÁâÀÀ€ÃáˆŠŠ’.–j[[¥4++K~ž|¨[·nB222Ø"ÿ@À`0|ðÁ„³Ù\QQQZZÊŽ=!¤££#&&FFÙ¼“(t&¬=öÛ†R:22ât:Å*#AÎù°víÚE‹ýãÿøê«¯ÇÒ¥K¥·+‘N§c8Žd'€O'-{“εÌÌL¶F,>[ôzŠÕS:¬|ß}÷]mm­¯¯ ‚ÑÑQ~w¬V«Õj½}ûö7ß|“››ëõµmü2Ú"¾×Eú„wï¿“ñØJ(7í*8#¼”1¼Gp8:®®®®´´”]rQñ+³³gϺ.666—Ûÿú׿!###===QQQ{÷îewJŽ=J<]žRJ·lÙ’ššJ½½Cçe¤ÊÞò32Cõöö—÷¼Ÿ|ò ñtéàêĉìnØu›XéiK\"»–NN&}}}„÷á+#–žØE• m&77÷ã?^¶l/À#_ïbPOZé+x™¢¸Ÿ‡bõ{¹Ç‰ ‹+x­V›••Å.ßN'F› 6/6°È<ᥓ‘n%›ãu„÷j Wðcù}dddyyù®]»êëëûÛßJoœ’’B¹ví[4 III&“itt´¹¹yÛ¶mlý½{÷ÇäÉ“ccc›››·nÝ*ˆÓÒÒòïÿ{```âĉ&*ʇϼ÷˜*Çqeee•••ìS¸ÆÆF³Ù,3Tbbb~~þæÍ›ûúúnݺµcÇ÷mZ[[ÿþ÷¿³à===UUUÒÿ L¬t‚´Ýy-X&Æh4®_¿¾³³“ÒÞÞþÅ_ˆUF,=1Ó~á…vìØqäÈ‘ßÿþ÷Ò/÷•O'­V«]²d ;|ííío¼ñÆš5kî?±zŠñzdÃEDDûH¦¾¾¾±±±¦¦fþüù*•JÎk1Úøe´ D|¯Uòé„KÆc+¡Ü4Ï×> ÆöáêÕ«„‡~˜_#qá¸aÆääd­Vk2™(¥GÍÎÎV«ÕsæÌÙ³gùï{¥wÞyG§Ó©ÕêÙ³g¿ÿþûäßK655Í›7/>>>>>~Μ9ß~û-•ýžÚkp±Tm6[ee¥^¯ç8nÆŒì=¬ÌPK–,Ñh4‚ïž;wN­VÛíö®®®Õ«W§¥¥ÅÅÅ¥¦¦³»A,”ÚŬY³XL±Ò¹¦í~ <–NN&”ÒþþþÊÊÊôôtF“½sçN¶Þce<¦'q[TPmJi__Çq ,>ýÄJ$}>øtÒvww—””$%%étº 6 IÄ—z¬§ÄËÝK$&”¯àÅ`´ Úhˆø^*ï„çyLÆc+!Ø´»1ŒðÒÆp¯¢”ºÎ÷ÅÅŸßw cB)ýÙÏ~öÚk¯ÆñÎ%̰»ï+W®ïD|€Ñ@¾1ôü=„O>ùdhh¨¨¨h¼{˜à!T$''ÿùÏþðÃ'NœÈÖ´µµqn^|ñÅñÍ€ÊÃÔXþL º»»kÒÓÓm6Û¸$ G(S¸‚P Lð „ @0Á(ðKvf³94Î$|ÿý÷ãð;Y÷£ @@ èæðáÃv»}¼²€1{ê©§’’’Æ; `´/++‹ý¯^ù„<(îÁ(&x @ÿtIÞuhmè¡IEND®B`‚vsmartcard-3.3/docs/_images/tikz-115ce7f91e19ed28b7af35a9f18aa096148209ea.svg0000644000175000017500000014545213546304763023730 0ustar philphil vsmartcard-3.3/docs/_images/tikz-f675fc9e85a93771428d0790db395907b3f662fe.svg0000644000175000017500000167503013546304763023546 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-2df37359f5f3e9e8ae5b3298a982b18985d97b0f.png.map0000644000175000017500000000032213546304763025745 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-9f3c7bc88811fee87e07a30133f7586cb9c7a2ee.png0000644000175000017500000001311513546304763025311 0ustar philphil‰PNG  IHDRgU•}%ŸbKGDÿÿÿ ½§“IDATxœíÝ}PT×ùðï ‚°wÁe‚°ÀÖÚT4FMDª)Ó¤U„‡Ã[bšHÛI3˜ÚX;N:LkL2qb¥Aék¦jÓˆÐ8L4Ij3“i¬F¥1Џ¼*°ì² /‹¼<¿?üív/ÞÝ{wYàŸÏÌάgï¹çyÎ9÷QîˆŒ1ÆÔ¤bÆtGÀcìv\œcL…¸83Ƙ qqfŒ1 ôçɪ««±k×.ÄÅÅùó´Œ1¦jŸ}öš››ýzN¿g»ÝŽ-[¶àûßÿ¾?OËcª–““ã÷sòm ÆS!.ÎŒ1¦B\œcL…¸83Ƙ ©º8Ÿ?‚ `hhhÊÆ<{ö,4 ìvû”©FŽy™îPˆ÷ÂWe¦cûËûBÕÅyéÒ¥èëëCpp°äë_•‹ÔµæøùçŸcÍš5ÐëõÐëõX¶lŽ= à1 ‚ zddd(:·TÎr{ÁqO5לü½Î]9þZ5QÛµæ×ÒM¥›7oNw“n*r¼yó&‚‚‚¼ê344„µk×¢¸¸Ç‡F£Á¹sçnÛÔ]]]˜5k–?Ã¥qO_æÝÓ±S•ÛWÝ´þËùí·ßÆ’%KDm&“ hllýMæx~àÀÌŸ?ÁÁÁX¹r% 22‚  ¬¬Lòo¿ñ?¢ÿîw¿Ã}÷݇°°0ÜsÏ=ÈËËCgg§dŒûöíƒÑh„N§C||<öìÙ#:ç‘#G””­V‹|_|ñŽ=Š… B§ÓaÕªU¸|ù²ó|žÆVš#ô÷÷cëÖ­øÚ×¾N‡Å‹£¦¦Æë1AÀÈÈÌf3233Ž… âßÿþ·Ûu3™L0›Íؼy3‚ƒƒ„””¤¥¥)ZwOkd±Xššªh]åÖÈ—¸ûûûñ“ŸüqqqˆŽŽÆüc Š^—šw¹}'5ïŸ}ö4 :::$sÞ·oî¿ÿ~Q  DSS“¢¹vÇOee%¾ùÍo:÷j]]€‰]›Ž=e±X——‡¨¨( üüç?Çðð°¢ñ}½¾<­Ÿ§1{zz$×`Z‘>|˜>¬øx«ÕJÁÁÁtþüygÛ+¯¼BkÖ¬!"¢3gÎt>ÏÊÊ"‹ÅBýýý¢×<µ QUUÕÖÖÒèè(µ¶¶Rjj*=ùä“·õomm%tâÄ ""²X,tîÜ9ÑqO<ñuvv’Ýn§üü|JHH ììlQ›#¥cËåHDTPP@)))ÔÐÐ@cccT[[KMMM>AD”žžNéééÔÓÓC---´dÉÑœ¹¤˜˜Z·nUUUÑõë×E¯»‹YéÉ­«Ò5ò6n"¢ÂÂBÊÈÈ «ÕJÝÝÝ”––F/¿ü²ì¼+ÍÉÝÚJõïéé!­VKÿùÏœmÛ·o§ï~÷»’ùÉͱÔëÙÙÙd6›Én·Snn.­^½šˆ&~meddкuëÈf³Qss3%%%QII‰¢ñ}½¾<­ŸÒ1ÝÍ™'ŽëËOkq&º•Ô‹/¾HDDccc”@$"é ðå—_:ûúZœÇûøã)""â¶þ×®]£€€*--%›Í&êã8®¾¾ÞÙvêÔ)@&“IÔê6©±år¼qãi4:}ú´Ûóz3Fww7 ššgÛÁƒ=ÎÙÕ«W©¨¨ˆŒF#i4z衇¨®®N4Fxx¸è±cÇ·9ùZœ=­‘·q;æõÒ¥KÎã;FƒAôºÔ¼+ÍÉÝÚº+ ?øÁ¨¨¨ˆˆˆFFFhîܹtäÈÙ<•®Á•+Wœ}Nžøßþö·°°0lذV«£££¢ãbbbPYY‰÷ßqqqHMMŧŸ~*:Æõ÷ˆhµZɶç-%cËåØÜÜ "Âüùó}ÎÏuŒ¶¶6@BB‚³Íõ¹£Ñˆýû÷ãêÕ«hjjBDDòóóEÇ´··Ãf³9¿úÕ¯<žÓJÖHiÜŽyMNNÆìÙ³1{öllܸ]]]“w%¼Ý¿EEEx÷Ýw100€cÇŽadd™™™ŠûË­All¬ó¹ tîÕ‰\›­­­Äû(11ÑÙ®d|À»ëKný”Ž©Ó^œ}ôQ£ººï¼ó6n܈·ÇϘ1Cò¹ƒN§ôõõ9Û\7„ÕjEVVžþy466¢··•••’øOaüqœ8qf³?ü0²³³½OÒ˱årŒ‡F£Á•+Wü2ÆÜ¹s@tÓ›_âb0°eË\¼xQÑñrk$•³'¾®Ñø¸  ¦¦ÆYÌzzz000€3fxœw¹œärs×¾|ùrÌ›7øãÿˆgžy3gÎT”ßDMäÚtP×=ÕØØ8©¿Mnýäx»ï&Û´G€ÂÂBìÝ»UUUxöÙg÷ŽŽÔ××;ÛŒF#"##QVV†ÑÑQ444`çÎÎ×ûûû122‚¨¨(„„„ ¡¡%%%’ç7™L8~ü8N‡À@ß?àâÍØžr(..†Éd¡®®--->¡×ë±víZìØ±½½½hkkÃîÝ»ÝßØØˆW_}Õ9¶ÅbAyy9RRR̓ÜIåìŽ7k$·N§Cnn.^zé%ttt¸U`?üðCžç].'9žrÞ¼y3vïÞcÇŽá¹çžS|ΉšÈµŽõë×;÷Tkk+^ýu<ýôÓ“¯ÜúÉñfßM…i/ÎÀ­Ÿþõ¯Áh4"99Yq¿ØØXlݺ<òfÏž}ûö!((‡Âßþö7„‡‡#//EEEÎ>ƒ{öìÁsÏ=AðÔSO¡  @òüÃÃÃØ¹s'bbb ×ëqäȼ÷Þ{>çéÍØžr€²²2$''cõêÕ CNNº»»}þüç?ƒˆ‡Ç{ Ï<óŒèu×/hµZ\¼x©©©‹-áÀ¢>Žw½xd×È]ÎRäÖÈÛ¸ËËËääd„……á±Ç}ÀݼËå$ÇSÎyyy0™LXµj•×·TÜ­R¾^›À­=¥Õj1oÞ<¤¤¤à{ßû¶oßîÕ9¼%·~žx³ï¦‚†¤~–÷QEEð¯ ëóæÍïýkäææNw8LBNN΄þá&ÿƒWÆÔîСCšÐûìÎsÇ~C±»Áœ9sˆ?ýéO¢oÝ577#))I²O~~>öïß?U!²IÂÅ™13›Í’íñññ¢O†°¯¾­Ác*ÄÅ™1ÆTˆ‹3cŒ©gÆS!.ÎŒ1¦B~ý´Æ¬Y³°k×.ç—Qcìnp῟ӯßdŒ1æü AÆS#.ÎŒ1¦B\œcL…¸83Ƙ qqfŒ1ââÌc*ÄÅ™1ÆTˆ‹3cŒ©gÆS!.ÎŒ1¦B\œcL…¸83Ƙ qqfŒ1ââÌc*ÄÅ™1ÆTˆ‹3cŒ©gÆS!.ÎŒ1¦B\œcL…¸83Ƙ qqfŒ1ââÌc*(ÕXXX»Ý>Õ±0ÆØ]ç[ßú¶lÙr[»dqÂáÇ'=(Æ»ÛåääH¶óm ÆS!.ÎŒ1¦B\œcL…¸83Ƙ qqfŒ1šôâ|þüy‚€¡¡¡ÉÊéìÙ³Ðh4wýÇó0222ݡa&#Ç·Þz 111§NòÛyï6wÂþ›ôâ¼téRôõõ!88Xòõ;a’&J­9~þùçX³f ôz=ôz=–-[†£Gø_Ì‚ ˆŠÎ-•³Ü^ð6ö¬¬,DFF",, ÷Þ{/¶mÛ‹Å2ásOÆz¹Î§N§CTT233Q__¯øV«?ûÙÏpôèQôõõ!--ÍoñM×}zÛþR«éº~§õ¶ÆÍ›7§sø)19ú2ÆÐÐÖ®]‹ï|ç;hooGGGÊÊÊ.:®«« }}}ÎGuuµ¿ÂöÙ©S§––†+VàâÅ‹èííÅ?þñh4œ9sfJbðu]»ººpãÆ Ô××C¯×#//OqßææfŒŽŽbñâÅ>=Ý×›ë>úä“O6›ÍÙÆÆ! O>ù¤T³¤ßþö·tÿý÷‹Ú®^½J3fÌ “ÉDgΜ!488è|þ—¿ü…¾þõ¯š9s& ­VKZ­–Þ~ûmQGÛðð0•——Ó¢E‹H§ÓQtt4åææRGG‡èXGÿ²²2JLL$AÈ`0Ð[o½%:®¢¢‚,X@¡¡¡ôÀÐÿû_zÿý÷)))‰A •+WÒ¥K—œ±([.G"¢¾¾>úéOJF£‘A ûî».\¸àõ3gΤááaêì줌Œ £¤¤$Ú»w¯hÎ\ÕÖÖ2›Í’ë*µr¯;Úººº($$Äãº*]#)‹-¢íÛ·»}ˆ¨««‹rssiΜ9GÛ¶m£›7oŠâJÇ–Ë‘ˆ¨  €RRR¨¡¡ÆÆÆ¨¶¶–ššš|ƒˆ(==ÒÓÓ©§§‡ZZZhÉ’%n‹óàà ÅÄÄкu먪ªŠ®_¿.z}"ÅyxxXv]•®Ñxmmm€¾øâ É×222hݺud³Ù¨¹¹™’’’¨¤¤DGvv6™Íf²Ûí”››K«W¯–Ímüœ+Gª8[,ÊÍÍ¥•+W:Ç(,,¤ŒŒ ²Z­ÔÝÝMiiiôòË/{œsO}ÜŬ¤»¹!ò¼oårŸ‹co*‰É›ëÔÑ'33“l6555QRRíØ±Cr.•ÖWJs•3iÅÙqü‹/¾HDDccc”@$"é úå—_:ûúZœÇûøã)""â¶þ×®]£€€*--%›Í&êã8®¾¾ÞÙvêÔ)@&“IÔê6©±år¼qãi4:}ú´Ûóz3Fww7 ššgÛÁƒ=ÎÙÕ«W©¨¨ˆŒF#i4z衇¨®®N4Fxx¸èáns»¶y[œ=­Ñx.\ dµZÝc³Ùn›‹ÑhÅqåÊçë'Ož¤ÙÜ\ç\é8®ù†‡‡“ €¨­­ˆþ·\B;vì ÉùSÒG*f¥}Üͧ}«$‡ñ¹ +ŽÉ›ëÔÑgüÚ$$$HÎåxîê‰/¹ÊqWœ%·†·6mÚ„‚‚¼ùæ›øä“O`³Ù°a÷Ç'&&NxÌ>ø¯½ö._¾ŒÁÁAúúú0::*:.&&•••(--ÅöíÛ±téRìÚµ «V­rç|®Õj%Û022‚ÀÀ@EcËåØÜÜ "Âüùó}ÎÏuŒ¶¶6@BB‚³Íõ¹£Ñˆýû÷ZZZð / ??_tß¶½½³fÍòxž‰R²F‘‘‘nå«×ë%Ï×ÚÚ @œbb¢³Ý!66Öù\ Ê~²ÅuΕŽãª½½ÁÁÁ8}ú4ÒÓÓQ^^Ž’’ç~HNNvKDÆØØf̸ýí!¹>R1+íãnn<í[_rð&&o®S‡ñksíÚ5ɔ֓‰æê ¿¼!øè£"88ÕÕÕxçw°qãF„„„¸Ô%p©$t:ˆÞ$pÝðV«YYYxþùçÑØØˆÞÞ^TVV¸5Aã=þøã8qâÌf3~øadgg{Ÿ¤—cËåFƒ+W®øeŒ¹sçšššœmÍÍÍŠó2 زe .^¼¨èx¹5òvs*]£ØØX,Z´ï¾û®Ûs9.X×¹hll]ÈžxŠÝõ5_ÇÑh4HIIÁk¯½†7Þxׯ_‡Á`ÔÔÔÀf³Áf³¡§§nãQÚÇõ¹/ã¸ò´o}=÷DcòdüÚ8®Wr×›T “³ƒ_΀ÂÂBìÝ»UUUxöÙg÷ŽŽÑGŠŒF#"##QVV†ÑÑQ444`çÎÎ×ûûû122‚¨¨(„„„ ¡¡%%%’ç7™L8~ü8N‡À@ß`ðflO9 ‚€‚‚Ãd2ˆPWW‡––ŸÆÐëõX»v-vìØÞÞ^´µµa÷îÝnollÄ«¯¾êÛb± ¼¼)))ŠæAn¤rvÇÛ5*--Eii)Þxã ttt¸õÃ/~ñ |ôÑGÇúõësÑÚÚŠ×_O?ý´¢Ü”Æ>Ñq6mÚƒÁ€7ß|:¹¹¹x饗D9}øá‡nûOUWžö­¯çžhLžüò—¿­Ô§cä®7©ý0™1;yqģ˗/Z¸p¡¨]îk"¢­[·Òœ9s(<<œÊÊʈˆè£>¢ V«¥+VÐïÿ{ÑýÓ={öPll,iµZZ¾|9íÛ·Oò~ç¥K—hÕªUFaaa´bÅ úôÓOo‹m|¼®÷iÇ·)[.Ǿ¾>*..&ƒÁ@‚ ÐâÅ‹÷È|£½½Ö¯_O:NòÓçÎ#­VKv»:;;é©§ž¢¸¸8 ¥{rrr¨¥¥E”³ãjÇcÙ²eÎñäÖh|Îîö‚§5·ÃÙ³g)33“"""H§ÓÑ7¾ñ Ú¶mY,""2›Í´qãFŠŒŒ¤ØØXÚºu+ )^wO±»R:Ž»þ‡"­VKf³™nܸAÅÅÅO:Ž,X@¿ùÍon‹qü½Ow}Üém©OV¸Û·r9¸;çDcßæúi ƒÁ@z½ž6oÞì<ÇøszºÞ¤öƒ7¹ÊqwÏYCtû}€œœ¼÷Þ{þû€1ƦÐÙ³g±|ùr Nú{&å¦ÞVðïÖ`Œ1ââÌc*ä—Ò1Ƙš<øàƒ’ŸÜº“ð¿œcL…¸83Ƙ qqfŒ1ââÌc*$ù†`KK ***¦:ÆcÿOòK(ÕÕÕªû_;cì«hþüùX²dÉøæ ÉâÌclZñ7cL¸83Ƙ qqfŒ1ú?%IFƒM³V IEND®B`‚vsmartcard-3.3/docs/_images/tikz-1281452b980f69540bc7520179e10f3ccc59fe36.svg0000644000175000017500001234504213546304763023426 0ustar philphil vsmartcard-3.3/docs/_images/tikz-b5a668553fb9bf21fb5abcc4cae46289d11490d1.svg0000644000175000017500000020102213546304763024037 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-d5ba565391cc5041a7ec6184d1e94238defbb78e.png.map0000644000175000017500000000067313546304763026053 0ustar philphil vsmartcard-3.3/docs/_images/tikz-30c9c7049675e5b06e8364c63b0718d51986e380.svg0000644000175000017500000304232513546304763023301 0ustar philphil vsmartcard-3.3/docs/_images/tikz-ce55fa00e38973c00fdf255926bb46304226f2dc.svg0000644000175000017500000137224713546304763023637 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-151a141442b8b2ad4b9ca6f670abcf103a9252a6.png.map0000644000175000017500000000037313546304763025722 0ustar philphil vsmartcard-3.3/docs/_images/tikz-f7010fa8209b3752026a52619d57bbebb8fa2bcd.svg0000644000175000017500000226020513546304763023756 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-9f3c7bc88811fee87e07a30133f7586cb9c7a2ee.png.map0000644000175000017500000000065213546304763026067 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-e1d6573d10e97f2502d55eaa993e54e501d1540a.png0000644000175000017500000000472513546304763025044 0ustar philphil‰PNG  IHDRü$ã*²bKGDÿÿÿ ½§“ ŠIDATxœíœmH“ßÇÏ,êž"3£æœR)3{°'C!-ˆ³–Ø,I¡AQ„Q{Ô - z°ŒèM„iFY™ ‘Ï¢­™s†iÎ9§N7wþ/Îÿwÿîî'§Û\¶ëójçöÜßó=׹Υ;›·cŒ€À È߀ùŠ>@E €€¢@,f´ãââ6mÚä+€_0™LçÎ;|ø°¿üŸW¯^EEEùÛü Ô××FúfÑOJJzöìÙ@áó¢ßÜÜ,•J'''}=ø(ÙD"‘Ýn÷®ì …Ï‹~RR’Íf aøöd~Ï鿈Åb‘HD5ݼÓcc£F£‰ˆˆËåñññ—.]ò÷¿*Ù×ýž0î3ÏVÿ„mÈÐá[D_[¸×»û=õûØ‹¡Žwæ‚í_êêêB‹…4ç,X[[›žžžœœÜÞÞnµZß¿/‰>}úä=ËËÔÔ”¿-¸‹­. Yÿùx}¿ûü;Z­ B*ÑÄĽép8È‹çÏŸÇÇÇK¥Ò”””ŽŽªCXXBH"‘H$’ÂÂBzóþýûc›ÍvæÌ…ByêÔ©ññq2DIIILLŒT*U*•·nݲX,ì{éØl¶óçÏÇÆÆJ¥Òõë×·´´`Œ>|˜˜˜(“ÉV¬X‘››ûóçONqJÓ _4‡‡þu:ç>rNQVVVVV6c·yÃ?÷îÝÛ¸q#Õ4 AAAÝÝÝTr’Ož6^ÙïŒ8ø"tØ%ÝËE?;;{ppÐn·çææ¦¥¥ÑûsÞHŸy~~~ff¦ÙlNOO¿xñ"ÆØd2!„ª««1ÆCCCMMMœ÷ÒÉËËÛ±cÇ·oß\.WGGGOOÆøÅ‹ÓÓÓ&“içÎdšœâ|N¢A’`ÎþûúúBŸ?æÂGÎ)üXô§¦¦òóó«««Nç¬ü˜ÍæææfÒ¼|ùòîÝ»1+Ù4ÍÐÐÐØØ˜pîÑ‘3ÚTÕ;؃4æËI¾±¥ƒ½:ÂaçÄwU…*sVæ+úÞ …Ï‹¾^¯'×kjjÂÂÂ8}sêŒŽŽŠD"êo¢ÊÊJ¥R‰1þñãÇ¢E‹Š‹‹- Ÿ:DçãÇS¨ªª ççs" ‡Ãá‰ÿ––„Ùlðìuç~,úV«522R.—ÇÆÆjµÚúúz÷ýhµÚ³gÏbŒ].—J¥*--Ŭdûòå éì~ѧCE›ê/°š_¿~%ÍÚÚZ„Pww7Õ‹Ålÿ q>«³Êg†Ôðð0B¨µµ•4KKKg,úž¤1g±Ü¯t3*ûb:úîwOоû¡ `—tæc%FS©T"„Z[[-‹Åb'}}Ê–ç ”={ö„„„¼zõêñãÇGŽ!‡¡ ¨¹3‚À—ÃѦ`‡ÝM„Åù¬Î6Ÿé «V­Bõôô&ã©[œÃy¸ …ƒÃvwRÔͰû¨ª°ñD™üV6 Ô½^ãfÝŸsþÇŒïLNNFDD\¹rÅétêõú­[·"þ7&ôëdÛÚÚHFcœ›››••Õßß1îíí}óæ ÆØ`0TVVŽMOO߸q#**Šó^:ùùù)))ƒœF’îDP¯×§¤¤oœâ|N8¡Ÿ x⿦¦F&“]¿~º]§Ó½}ûÖwÎ)èñÆX§Ó¥¥¥‰Åbêôƒï,‘p¾æ‹6¥ÆváÃ"ª9£8§U<›|fŸìÛ·/33sddÄd2mÞ¼±Žw¼¸ ùr’‚/ì ö"Ψì‹épâ­ý®ÑhöîÝk2™\.W{{»Z­¾zõ*»§'¡ ð™>ÆøÝ»wjµZ"‘$''?zôÈÍ¢1¾páÂòåË—,YRRRÂnŽŽŽDGGËd2µZ}çÎŒqgggjjª\.—ËåÉÉÉ>| úŒ{›šš$‰ÝnÇÛl¶‚‚¥R)•J7lØ@Î4oß¾­P($ɶmÛ«îç3[ª¿¿ÿþý2™Œñíz&{kòõ¡Åvº{ù”9ñQUa¯¦'Êf³ùôéÓ*•J&“ÅÇÇR ãÅPØ%]„÷š““V(È£•ÿœGÿi~`AÃ.éç/À }F£QÊâäÉ“þöµ0ðòW6|Mttô~ ‚¿¿ô(ú}€Š>@E €`~{§¹¹Y«ÕúÅ àL&“N§ó·‹ÿ -**"ÿ¢€‡‡øÒaþG.ðÇ;}€Š>@E €ø¹àb0¾ïIEND®B`‚vsmartcard-3.3/docs/_images/inheritance-8d7ae2bc5a5efc5bac682034d18967034c43784c.png0000644000175000017500000000565113546304763025216 0ustar philphil‰PNG  IHDRT$ÀG3–bKGDÿÿÿ ½§“ ^IDATxœí{H“ßÇÏL¿–ÛŒD‹šs†•hëbi–BZQ¦­0“QQD7Š(’dQQQZݯd]ˆ²"ˆîE"]¼tE²åuе\ºt¶éùþq~ßç÷ôÜœmsº}^íœçó|ž÷ùœÏs>óî= ?Àë€âxPü¯Ã—Õ5jÔøñãÝ"p ƒaÓ¦M .t·ÿq÷îÝÜÜÜÐÐPw ÀsxùòeMM ³‡]übbb®_¿Þƒ’7“ŸŸïn `±XzU1ÀX´h«¶=¯Šàu@ñ¼(~€×áòâWZZ*“ÉÚÛÛ]}!pQ²I$‹Åâ\·= …Ífs·>Hž1õ}×Í…Ë‹_LLŒÙlö÷÷gIwd$nÏHÙH$ºiçé¼ú‹‹‹5Mppp```dddvvvcc£ ´{2t²±úÝž0öÓÃR{þ6tEžÛ©„kF¿!`J$'Šéî¹}eÍéUs!l{þ æÿ(,,DQEší°   999>>þãÇÍÍÍOž<‘H$oÞ¼qždïå÷ïßî–`/N”Ú;GmOž÷NånÇ-kއÏþ“ŒŒ , ‰N[[³iµZÉ‹›7oFFFÊd²„„„²²2Ú ¡¡aÀ€!©T*•Jsrr˜Í“'ObŒÍfóúõë ÅàÁƒ×®]ÛÚÚJ.qêÔ©ððp™L¦T*>LQ÷\&f³yóæÍÇ—ÉdcÆŒyûö-ÆøìÙ³jµZ.—2D«Õ~ûö×9íW‰P4¬V«ƒúÕjµN§ã½„‹”ÓܸqãÆ]šõöè9qâĸqãèfEE…Oee%œäÅ¥K—FŒòóóc\(‡±@´™öܰ“£ùùùQQQ'N|ÿþý;w¢££Éðùógr!çBRqwò™éÊÏÏÏjµ~ÿþ=555000::úرcô0 ¼©èHóæ$¡|ང‹”Ó¸±ø=xð`Ë–-•••ÝÕc2™üýýKKKIsÇŽÓ§OÇœdÓh4¿~ýÏ=æ$òF›¶™ÍùóçÿþÝb±,^¼X¥R¥§§ÓM¢MܹTÜ|f¹Â§¤¤¤¤¤455ÕÖÖ’onb?n(°i,”“4"yÎRÞÔÔ$•J_¿~MŽêtºY³fÑfiiiEUWWGGGoÛ¶w©©©sæÌ¡(ª¦¦&::z×®]¼f¬å‹›!âSÏ‹ëV6–fG<{É\0qyñÓëõ¤ÿùóç à•Îë§¥¥E"‘Ðï‘ïß¿¯T*1Æõõõýúõ;~ü8EQB˜?¯^½Âãǃ‚‚„œ )‰†ÕjuDÿÛ·oB&“ID³Ó•Ó¸±øíر!¢V«÷îÝÛÐÐ`¿žŒŒŒ 6`Œ;;;U*Õ•+W0'Ù>}úDŒí/~LèhÓö"³ùåËÒ,((@ѽ   €«Ÿå\Hj·ò™åêçÏŸ¡wïÞ‘æ•+Wº,~ޤ1¯ ‘œk†»³àv9:W„TÄ¿ëÖOš &ÜÒÆþz3Q(ä…L&kkk³ÿ£e555ãI“&‘&ÆØjµvvv:ôÖ­[Ç×ét111¹¹¹‰‰‰]ú9r$«ÿÞ½{ûöí+//'15›Í¼Î…”øøˆ=uDpp0B¨®®nРA\Ï®VŽ*..7põõõ!£Ñh4·oß~ôèÑÐÐÐ)S¦$%%uyîòåË—,YrðàÁÂÂBŠ¢,XÀµ ï®$ÞhÓGEf“þ2R©TÊj¶¶¶Úl6___çBR»•Ï,WäݽJ¥"Mú…ޤq—6âyÎ ÂêÕ«g̘qèСgÏžÙl¶´´4ú=ððp’B,È_L3ÒC¶”­VkÿþýÉ!«ÕêããÓå bÏè„pÖÊæ\ÏÞ9,ºý¹\Ž¢´’‘Øu¥?GÅj*•J„лwï(Š¢(ª©©©µµ•ØÌ›7ïéÓ§F£qÚ´iéééÜs™„……I$½^Ïì4™LfåÊ•UUUÍÍÍ·nÝBaŒy‹(Áý …B­V_»vë¶”÷QfΜéïï÷îÝ‹/fff’ç,è±³‚ ”Ã"Ѧá†ÝNÄ Iín>3= 6 !T]]Mš¬oõ彜ƒ·¡xpDòœ+&..."""??ÿüùóË–-#k%QUU#K yçÁ4#=dA¯¨¨ -õz}xx¸k®S‹‹Öî(úî\tA—²hooÞµk—ÍfÓëõ±±±HøoUf?YbÞ¿O XMŒ±V«]°`Ùûª­­}ðàƸ¢¢âþýû¿~ýêèè8pà@hh(ï¹L–.]šPQQAž‘ÔÔÔÛž8Ôëõ D¯s!%¼0wÌÑÿüùs¹\¾ÿ~útN÷ðáC×)§é£ÛžcN—””@ï í±³.”ÃBѦ½ñ†]|•nvéœW*îN>s·’fÏžššÚÔÔd0&L˜€8ÛžN¼ …r’‰Pžón÷>}z̘1~~~åååÌ`j4òS­Voݺ•wsçÎ%'f;wî$ýfÖ¬Yƒ¡³³óãÇQQQ»wïæzà&’=£szHyqõšãIsÁÄ Ïü0Æ=ŠŠŠ’J¥ñññçγ³øaŒ³²²BBBxêÔ)n³¥¥eãÆaaar¹<**êèÑ£ãÏŸ?'&&ÆÇÇ¿xñ‚øg[RR"•J- ÆØl6oܸQ©TÊd²±cÇ’íæ#GŽ( ©Twúôi¢MÈ9¯ÖUXÃtP?Ƹ¨¨(---((H.—5Šüϳ”‹Ð?ðB(//G=šî*~˜pÞÆѦ½ñ†ÝÎâ×¥s!©öç3×UCCÃܹsår9ëÓžÌLvÖm(dúkxóœwÁmnn–ÉdÉÉɬùÍËËS*•ƒ Zµj} kF£133388X¡Pdeeµ··3“É´nÝ:•J%—Ë###srrè™bzà&’ÐèxqÑÊÆÍ(W¬964ÜÒ&Áîê,Z´~ÒÈ« ?iÔ{~B¨·éÜÆ8""bÏž=Z­–ôÅÅŵµµÑŠ€žÁæ‚[Ú<ó}«W¯¶··ÿýÀyxä\8ùÓžŽâëë{áÂ…þùÇÝZø!ÿµÆê\¼xñ™3gÜ¢Çuôþ¹ø; øÐë0ÜÎØØXÖc7æÈ·‹õ!zÿ\ü°í xPü¯Šàu@ñ¼(~€×Áþ´giiiFF†[¤nÁ`0èt:w«ø?ýû÷ÏÍÍ%ÿêàÈY0aà x<°í xPü¯Šàu@ñ¼Ž‰“ÏÈ©?IEND®B`‚vsmartcard-3.3/docs/_images/inheritance-2bbcd7895a62e5ec48d90ac42e0891ae2f9feca4.png0000644000175000017500000000352013546304763025513 0ustar philphil‰PNG  IHDR $óf“+bKGDÿÿÿ ½§“IDATxœíœmHS_ÇÏõ¡év·µ0šf)\fheRV/–¥K¤Uh/‚èEFÑ«’ì]V‹5¢$ŠpIf¬z@©ÔÒ1ͦÓiédf6uÎmçÿâÐeÝ=ÜÕZþÿ¿Ï«{Î=ûî÷½÷|ݹó(…1F&âO;àB@H€ƒ(V{ñâÅ+W®ü#¥Àß@CCCoo¯w;$™™™÷îÝ›Á’àïB¥R±z`¹@H€ p!Â’ææfš¦'''Ã%Hxûö-EQ‡#¼²3 qár¹þt!áä?iÊ/a Iff¦Ýnçñx¬þY4Ëg¾ÔwïÞåååI$‰D²jÕª„ý-fÆTp#Eݺu‹U•\.gzìv;MÓ~S7­â¡0½Ë-§Ó9­úa$Œ¥†(599©P(¶nÝ:00088¨V«Åbq¸jø¥Jþ¥Tp#G«Õfdd\»võB·ÛýæÍr\]]-•JgX~üˆZºt)ÓÃZny?)ž8qbþüùb±X­VcŒëëëÓÓÓAVV–V«E?>/^¼(•JÁÚµk¯^½JúµŽŽŽ 6ˆD"‘H”••õêÕ+ü++“àâJµÛíeee)))4M¯X±‚,ÇC”رc‡P(d}»ÕÔÔ$‡ÕjÝ»worr2ŸÏOLLT©T‹e6š d¤   ¨¨ˆ5sÖ­[wøða_e–5Ϋôoăã ÿ¼¤Q©T°Uø?ãØ»@H€ p! $À„8€à€ýËDøçtÀÿœ––²¡„XÀr 8€àBü7ŠãjÙvôÎIEND®B`‚vsmartcard-3.3/docs/_images/inheritance-647e4e3af2eb4356e4633a015c7851f55a66a0bd.png0000644000175000017500000001453513546304763025126 0ustar philphil‰PNG  IHDRØUeâb|bKGDÿÿÿ ½§“IDATxœíÝ}Lið·Al§¥„Z¾l„#ГÊŠJ@ÇåÜj 1!Y î‚Ñ;ýã6ÙlÖÁ¹"„Í¡ ­Ëy`–¯œ ÉáòQZ ´¥×D[:÷ÇÄIwÚN«¢U|~˜ÎÌÛ§O¶³/Óy8Ž#îãáîàKÜ 1¸4bp3Ow'ÀGÕÞÞ^^^âîDÀ—«¯¯offÆz4bðeY]]ýÃþ••åîDÀ—ëØ±c”=05nÜ 1¸4bp3hĸêÉ“'l6ûÕ«WëöñãÇ cuuu}Ã~dÄ»0›Íïð\²°£ï1®Š5ÞÞÞ”ýŸQûøDR¥¤á¨°N ¤¥¥ùûûs8œÈÈȳgÏj4ú§”••1ŒúúzJ2l6Ã0@™™955e½ŸÃáðx¼ØØØsçÎÍÏÏÛ} èý~A#ོ~ýÚÝ)¸jSýÞuggçþýûãããŸ={¦×ëüñGƒñïÿ›æ)‹¥¦¦F"‘H¥RÊ!µZm0FGG½¼¼rrr¬÷ëõzµZ]WW§T*cbb^¼x±îï1TW¯^ݱc¹999Éd2§¦¦È“ âACCCDD„··÷Þ½{Bþþþl6»ªªŠr®d}¢$•J·oßÎáprrr(/]]]†a˜P(¬¨¨ Ÿ~óæÍèèh‹7<<|ûöm±XŒaXBBÂÿû_â¹vƒÓ§ŠZ^^.-- Ç0,&&æéÓ§®„b³Ùf³yqq155•ËåŠÅâÞÞ^ÛJÚ-…F£IJJ¢©˜£RPÿéO @ …Âo¿ýöw¿ûÍOV&“©Õꦦ¦ÞÞÞgÏžÙàñxùùùƒƒƒ”ýL&S"‘Ô××K$’óçÏӼĻF UvvöèèèÐбYWW·ÿþÐÐPʰ¶¶¶þþþåååžž„Z­6………4‘ù|þ7t:ÝÀÀÀììlqq±õQ…BQXXxíÚ5ƒÁ044´oß>òPsssWW—V«ŠŠJIIillìììT«ÕáááNƒÓ¤ZPPÐÝÝÝÑÑ¡×ë[ZZx<ž+¡t:§§g^^žÅb‘Ëå2™ìúõë.–—Ëå>zôˆ¾b4¥ (•ÊgÏžegg»ø¢©Tšžž.‹ÿö·¿ÙÐh4R©t×®]vŸÎ`0rss;::ÞêE]‚ð%iiiiiiq:ìèÑ£§OŸÆqÜb±ˆD¢ÆÆFljÿí}ùò%ñ`dd„Lî§Ù4™L”—xðàŸŸŸõx¥RÉd2¯\¹¢ÓéÈaÄѱ±1b³³³!499InnÙ²Å6JpG© ƒÑßßOS G¡–––BOŸ>%6mߦ£R8ª})¬¿&µZ-Mæ …ÂÓÓS&“á8^SSãë뻲²B¾:—Ëõõõ …ÙÙÙr¹Ü6yBWW—‡‡‡Ý£Ž~жŽ=JÙgÄØ‘——×ÜÜl2™>|¨Óé222lÇØž#;u÷îÝÄÄD@Àáp222´ZíÚÚy400°µµõÖ­[!!!IIIÝÝÝä!òæ,‹²¹²²BÌ{Ðw”êÌÌ Žã®çI†R(!‘HDl’ÖM)þþþd.ª­­åóùDeee­®®þãÿ ªTª¥¥¥éé馦&š[‘LOOûùù!„6mÚ„2™Lä!“Éäááááñ.M1v$''{{{···×ÕÕ?~ÜÇÇÇv ù‘£|ö0 CFbsvv–x ÕjÓÒÒòó󧦦ôz}kk+Bÿù9GŽéèèX\\> €uÃd2sss+++ÛÚÚN:E?X  „ÆÆÆˆÍ°°0ÿªªªµµµ‰‰‰²²2bÿòò²ÙlÞºu«ÏÄÄÄ7ß|C‰399yïÞ½••/// Ã<=ßâž\NƒÛM•ÍfŸ8q¢¤¤„˜ë•Ëå.†âñx‡ºpá‚^¯W(—/_¶ã¨”4l¹RŠ+W®\¹rå»ï¾#.)›ýóŸÿ,“Éì¼ÿ¾\.ïéézãÎ;}}}ÃÃÃŽr°f±X†‡‡óòòž>}zñâE„—ËMKK;{ö¬B¡Àq|dd¤¼¼üäÉ“®D³Ãõ6çˆq'®F‹ÅäÛ©LòPii)ŸÏçr¹UUU8ŽËd²¨¨(‹_SSƒÞLVTT³X¬;wVWW£ŸO˜>þ\ü&ÛÒÒ’uŸU*•KKKÄ9ÁëׯuŸ%þuúÒ8ާ§§ÿå/áóùëòvøàÿÑÀGBÓjM&ÓÖ­[É&+‹ Æû¼"ƒÁP*•ë”>4bðÁýýïomm  úlppp\\\PP¯¯¯»Sà“|pyyyp“hÀuÄàfЈÀÍÖ­?yò„Íf¿zõj½쮳ýÙ±^Pým‘…Ý¥ØZ·Fk4½½½)û?£öñ‰¤JIÃQa]QVVÆ`0êëë)ÁÙl6†a 33sjjÊz?‡Ãáñx±±±çÎ#V ±M ½ß¯Ňšxýúõ¿ŽÖ1ÕOä][,–šš‰D"•J)‡ÔjµÁ`õòòÊÉɱޯ×ëÕju]]R©Œ‰‰±^ð¼u#¾zõêŽ;ÈÍÉÉI&“955Ež4"""¼½½÷îÝ‹ò÷÷g³ÙUUU”s+ë+©Tº}ûv‡““³°°@yéêêê°°0 ÄBaEEùô›7oFGG³X¬¸¸¸áááÛ·o‹Åb Ãȯ¯Ø NŸ*Bhyy¹´´4<<Ã0b9/WB±Ùl³Ù¼¸¸˜ššÊårÅbqoo¯m%í–B£Ñ$%%ÑTÌQ)lÉd2µZÝÔÔÔÛÛûìÙ3Û</??pp²ŸÉdJ$’úúz‰Drþüy»Áëè­qvvöèèèÐбYWW·ÿ~beikmmmýýýËËË===!µZm4 i"óùü7nètºÙÙÙââbë£ …¢°°ðÚµkƒahhhß¾}ä¡æææ®®.­V•’’ÒØØØÙÙ©V«ÃÃà œ§Iµ   »»»££C¯×·´´_œuJ§ÓyzzæååY,¹\.“É®_¿îby¹\î£Gè+FS kR©4==],'&&Ú]6\£ÑH¥Ò]»vÙ}:ƒÁÈÍÍíèèp1sÀ»sº¼¨Ý%HOŸ>ã¸Åb‰D¸Í·###Ö+¡RÖ u´$-éÁƒ~~~Öã•J%“ɼråŠN§#‡GÇÆÆˆÍÎÎN„±08±¹eËÛü)Á¥j0 F?M)…ZZZB ââ8ÞØØhû6•ÂQÅèKA¡P(<==e2Žã555¾¾¾+++d4.—ëëë+ ³³³år¹m2„®®.»Gýàl¹¾j2_¬w™#ÎËËknn6™L>Ôét¶clÏ‘º{÷nbb¢@ àp8Z­vmm<ØÚÚzëÖ­¤¤¤îînòy‹EÙ\YY!æ=h‚;JuffÇñˆˆ×ó$C) „H$"6É낦¤ÚÚZ>ŸðàA„PVVÖêêªõ-DT*ÕÒÒÒôôtSSÍío¦§§ýüüB›6mB™L&òÉdòðððð€ËXïòAJNNööönoo¯««;~ü¸¸o>¢”Ï*†a!rQ©ÙÙYâV«MKKËÏÏŸššÒëõ­­­!üç7$:räHGGÇâââ233]O˜>¸£T…B!ƒÁ‡PÄ-i¦§§‰Í™™Û¬••îF_ ‹ÅR[[«Ñh‚ƒƒ"##Íf³ÝÙ z ÉÉÉèÍ/ë?܇††B#`]¼Ë‰ÉdæææVVV¶µµ:uŠ~°@ @›aaaþþþUUUkkkeeeÄþååe³Ù¼uëVŸ‰‰ Û[wONNÞ»woeeÅËË Ã°·º¥¬ÓàvSe³Ù'Nœ())!æ:FGGår¹‹¡x<Þ¡C‡.\¸ ×ë ÅåË—mÇ8*% [NKqÿþ}¹\ÞÓÓ3ôÆ;wúúú†‡‡T !„ÅbÎËË{úôéÅ‹B\.7--íìÙ³ …Çñ‘‘‘òòò“'Oº àeªÂ•9blj«Äb1¹Çv*“>¾»»w6ãl½IÜQªF£±¤¤dÛ¶ml6›¸jÂõP*•êðáÆEGGWVV’™ ²X¬ÕÕUšRX§a[X»¥°Žœššš‘‘Aù‘íÙ³§¨¨Èî\0Y+‹…a—Ë•H$gΜQ©Tä­V[TT$‰0 ‹ŒŒ¼té’+Ä8Ìà¸1ø°\¼1_2˜ã7ƒF nÜ 1¸¬Ð>¸~øáÉ“' ((ˆÍf»;/>ЈÁ÷ûßÿþÀÄ‚¡ÿùÏþùÏÎÍÍßG™Íf>ŸÈãñÈš…Bá[]*îˆÙl^—8|Pðß(øà¼¼¼‚‚‚‚‚‚~ýë_Û`½ÀóÀÀÀ;w”J%qù—/_úøø <ÿ-ÛéëZ,@ð›ßü¦¼¼<<<œØ944téÒ¥u|w¼ƒ––ëMj#–ËåÄ…Ÿ¬‹¾¾¾Ý»wÓáñx<O,Û=úòåË¥¥%¢M¿xñâ§Ÿ~rñ„zaaaóæÍ---?ýôSXXØ÷ß¿{÷î±±±¬¬,¸®¸Ñ±cÇ({¨_èhoowû`ƒ9pà€¿¿ÿ ¾¶¶¶°° R©ææææçç•Jåüüüüü¼ÅbÑétƒƒƒZ­–Éãñ¶mÛöÕW_ýêW¿‚F ÜÈö{sÔ3â”””˜ï‹ÉdÆÆÆRÝ¿?==¶yófƒÁðã?ÆÄÄ|ô4 sÄ`Ã’Ëå›7o‰Daaa¿ýíoE"̼O4b°aeee}õÕWÁÁÁîN' ƒ Ë××××××ÝYà|³W=yò„Íf¿zõj}ÃÚ]ö³c½ðÛ" »1Jñ àªØØX£ÑèííMÙÿµO$UJŽ ë4›ÍÆ0lëÖ­©©©4k)X+++c0õõõvC ‚ÌÌÌ©©)ëý‡ÇãÅÆÆž;wn~~Þî[@ï÷«1ïåõë×îNÁUë˜ê'ò®ÕjµÁ`ãñx999NÇ[,–šš‰D"•Jí†õòò²¥V«õz½Z­®««S*•111Ök†­hÄP]½zuÇŽäæää$“Éœšš"O‚ˆ ÞÞÞ{÷îEùûû³Ù쪪*ʹ’õ‰’T*ݾ};‡Ã ÈÉÉYXX ¼tuuuXX†aB¡°¢¢‚|úÍ›7£££Y,V\\ÜðððíÛ·Åb1†a Är9ނӧŠZ^^.-- Ç0ŒX†Æ•Pl6Ûl6/..¦¦¦r¹\±XÜÛÛk[I»¥Ðh4III4sT G¸\.±²—ÓŸ¬L&S«ÕMMM½½½Ïž=³Àãñòóó)û™L¦D"©¯¯—H$çÏŸwúBo 1TÙÙÙ£££CCCÄf]]ÝþýûmWûnkkëïï_^^îééA©Õj£ÑXXXH™Ïç߸qC§Ó ÌÎÎ[U(………×®]3 CCCûöí#577wuuiµÚ¨¨¨”””ÆÆÆÎÎNµZ^PPà48MªÝÝÝz½¾¥¥…Çã¹J§ÓyzzæååY,¹\.“É®_¿îby¹\î£Gè+FS [Z­¶¦¦&..ÎéKK¥Òôôt±Xœ˜˜hw9]F#•JwíÚe÷é #77·££Ãé ½5w¯ÕÀGåâzG=}ú4Žã‹E$566â6 3ŽŒŒƒí®èh)EÒƒüüü¬Ç+•J&“yåÊNG#ŽŽ›!bA[bsË–-¶ùS‚;JÕ`00Œþþ~šR8 E|ËœXÈÇñÆÆF۷騎*F_ ÛÈ\.—¸ŸH$"V¶¥¡P(<==e2Žã555¾¾¾+++Ö¡|}}…Bavv¶\.·MžÐÕÕåááa÷¨£´-Û¥AáŒ;òòòš››M&ÓÇu:]FF†íÛsd§îÞ½›˜˜(8NFF†V«][[#¶¶¶Þºu+$$$))©»»›<B<`±X”Í••bÞƒ&¸£Tgffpˆˆp=O2”B¡@‰D"b“|°.hJaM¥RéõúÞÞ^ƒÁ`÷ ×Zmm-ŸÏ?xð B(++kuuÕú{Æ*•jiiizzº©©‰,¯­ééi???„ЦM›B&“‰ŸÏår«ªªp—ÉdQQQ,+>>¾¦¦½™:¬¨¨f±X;w®F?Ÿ0}þüyBB‡Ãáp8ñññÝÝݸ³gëMúàŽR5%%%Û¶mc³ÙÄU®‡R©T‡Æ0,::º²²’ÌdppÅb­®®Ò”Â: ÛÂÚ-…udÛdšššX,Öââ¢ÝŸfjjjFFeçž={ŠŠŠìΓµe±X†q¹\‰DræÌ•JEÐjµEEE"‘ðÈÈÈK—.¹2AŒÛ›#¦Þ€¸éܸ‘ím0ajÜ 1`㘙™aÛøúë¯Ý—p÷5ÀÆ! É‹4>#pF nÜ 1¸4bp3øcøâôõõ¹;ðE“Ëå”=ð…ðeQ«Õÿú׿Üø¢mÞ¼9%%Åz4bp3˜#7ƒF nÜìÿRikÅÛ×­IEND®B`‚vsmartcard-3.3/docs/_images/inheritance-66308f7843803aa5084df2fbf62c13b8b1f3a5d4.png.map0000644000175000017500000000111013546304763025665 0ustar philphil vsmartcard-3.3/docs/_images/acardemu-qrcode.png0000644000175000017500000001067513546304763020321 0ustar philphil‰PNG  IHDR   E3„IDATxœíÝMoGzÀñªáp$’CJ‘„Äo±vó ,âËêàƒ€½f±ÀÂ'È-ñð%¹ÉÑ@€½.‘OÞAŒ\„äæÀ—¬ ¯’61ÁÈÐ ©ɞʡ‡Íšê§kº¦ªº[æÿw°©éêêž™~¦ú©ªîÖÆ fÔ÷El2b€ŒØdÄ #6±Ȉ @6ö/ÖZw³þáyÿn8ë:…ƒþýëÕT•_̇T•ß0?œþ¤ÝdÄ #6±ÈVä⎄Úæ[þª‚rÄ üÒ¿4è³J˜mLjéóª*H_Gí #6±Ȉ @–‹;:‘M˜";‚òé¾’þ|™zPò$ßPwgGí #6±Ȉ @•‹w&ál¾©ãÙɘÂþÝH襸c í #6±Ȉ @6Ð\ꎗâAU1^!´¡¾®­æåãþuäâ@zÄ #6±ÈRÎQw仓¶7:»ívg)ËwS¼Î®½Î7‘Þ9ê@zÄ #6±ÈR>Ó,_B™OÂÁû|£È­w!f'®K»Ȉ @Fl2be¼º_gc®AW9ÇÈc¿ÒçôH·¾..÷£ÝdÄ #6±ÈÂîÝ6Ìqâ˜'y¿ÏDïl'cöÊ‘ï†zÍ Ýd)ûp/ˆò§HkýÑGEÖcÿæU¿p¡5;…ízŒ1åÒÙlvïÞ½O?ýôèè(fŸ/”°{ð óœ*Fû·pëÖ­Ï>ûÌ3Ìû­¤µ~ðàÁ»ï¾ûùçŸW/är˜³T‰VoáæÍ›_|ñÅ•+WÒn½cZ냃ƒ·ß~ûþýûå+ĆNJ|Ã,ÓËœ¥þu¥þª‚Öõ/õöo¨òá‡^½zµ}£‘$NžFc®_¿þÁx ´ÿºýü»»AKƒí¹x+·oßnúV’‡A› Å2-+yçw÷î‚"6Z¹qã†YN+öëÕ¯‘HÎZkúÎïœXaõßjœŸÆêŸ×®][¹PôSµTëå©…}üUeœÍYw–'e1xêµÙ¯8+zZ g‘³­ù|øî/(b#˜ÿ|Æþ£ zÉêE1ê<ÛS&[”È}ÞWe×myûÃ~ª )ç¨ÇdrùR· uŽ²ç¨‹³˜ìEzùê¥2×µ!máZëÍg¿ÖÅVJ›Ï~}2ýùù&ʼÜZQ•mÐr?¯Óz\¾|Y×®£Š¿ØÚ³4áÜ… c#_ÀÓnpfË:KWyË}¯K£ã§ÿ»õè´*”VZ—ÿïïõéÿÔKžÿ³63ÊÙ™ù|>›Íê—%ÖÛ"x졺ª#È~Ñ~½VliJˆ1çѱqúµ2'ÆœÕoN6N¿±Kª¥J胪ïÃ|>ñâ…³ÃN1øÐJéÚ+åÿµžoþ™Ò›‹Ak¥7ç›?TÕÑ_žEUK톲άªÆ¡ ¬oëûØhK¯K F,U¦¬¡Ãñ«³k£Ô¦6F©Í×ÿÖŒ_µÖ=/©•VÊèÚ•vÚS½RµÎÎçü¾W¢Æ7bÒ¯˜¡Ð íÆ “WKí9êkq§E9£'»ïžn½³qú»ùæÍøUϺåjb²!¶$óùüøøx2™TK=zôÚk¯µÙiÿçó-Ä|eA…c6ÄØ_[âçXï ²_·VVêì_|[µÊÌø•bs)*ÎKj«B«ó×HW,Õ#¤ vo ÄF[M¿@õ£Ó)oT­¯Éz¥©þzÉÅ ˜ÕÞ´ Œòz땈¶êøLíò:ÕÔ’ãÌ€RF©ù“½?^±Õùe¬mi©ÁYÞ%UK?ª“«“““ÍÍÍ5ÞûÅDl„i:“išôªµ¶G­2F¥ŠÇ‹ Ñ‹"ç=½K'PK+:ÑÑÔpÕVTEQˆe Zþ*(9ë«5Ú®øŽªqqO…õ˜YŠœE¡³Ž_/¬œcÝ-¬”¿aoªœc¥›g¡{^œÏç§§§Îl)ߨHgÇFÐ[ Ýhkå÷ç)°8ŽÏ¦D-.Tòf)J5ýç­ÌŠCÜD½ÛMˆŽ¸·M8ãïkª-rãÀß8¤é~ImÕSÞºEWR-/ÿÞxñÛ³rÊî¨Z>~—£hyÙÆì¿Ïª]|‹ÿ$<Ú#6‚UGX=ZêŸÖÚLÞPZ+c&Ï>1Ï>©WXï|ò½RÏäö&Ts›PoŽ–¢ž/î3ªšpÌ5ùˆ¬8-ö_-þؽ­®üL=þMÙä•6Öqnô¢‡·ªÀSÆRY…*ƒî,<´ÖÅîOç[·êû žžùßxÌ—âç/œðØÚ ªh7ÚZ;×z4ºù‹?Ͼ¶†µUãiU½*»àäó­[Jt­°ž‘Aø¹,”—nüäðð°ì?m:ˆ=?übcU²“Š :áÇ<ÜŽh­wvvÆã±ç×½iQS`hKû: ’–h7Ú 8,–ßÙÙ9:::==õw5ÍLqúÄ=\cEˆÂÆÅùÒë˜Ýð/ Újéþþþµkתî)eýM'9N%Õ‹ÛÛÛGGGžé¦v-k½¶zGY½°¿¤ÿý¶Y3†óíǬ´ÏœS¨‚A<ÉYÀ•ííí {‘SÒ^Å~ÑnÚ†SÒ®+mÕ¬æŽ)áàv loo—¹‡sÔŠéA}QSØØé‡¸:Ú#6ZyôèÑÊæ¸eäTK·¶¶ÊÖ£é(oªÓ)ß4뤩};88𿔈VîÞ½›üw· ñxì¼h_óí,ªÿSlœ Ç9ñ»{÷nÂwñ=6+3áñ‘0Á Êý×}þüù·ß~»»»{õêÕ•û¦®’õ˜ÍfvjÞ&$êÿ¬¿¯*fìÌäþýûEQ¼ùæ›âsƒ>œ„©¹7ú:Th7VÇ—.]zøðá7ß|s||ì/\M¬j_ÿåË—íÔÜ'â¢jONNN¾úê«ï¾ûnooÏi¬ â3Zm4M§ÓÙlöøñã/¿ür<F#¥ÔÇl{ï½÷ÖÞÄ;wìKŽÞÿ}{iµ¡òˆoÚP¹ôÎ;ö‹eUåõâÓéôÆÓé´ÜøqN嫹RųgÏž Sä ™×ä×׸˜¯›ëň @Fl2b å>êA»áßP„£¹Aï7á=Éó­TUÐ÷›ðíç›WO»Ȉ @Fl2b¥|¢ng£¹Í3Ù«|“ðûºÛK¾.HÐTù˜Ý ÝdÄ #6±È¢rñ„yO¾›Ä%Ld;›þíÈ5îù÷ í:òu Ðn2b€ŒØdÝ]/žðéãAëæ›Ãœ°ÿ ¯!ç|W ô•|æ™fÀ:ˆ @Fl2b…=Ó¬¯á »~VyÜcÂË ú¼Ï7jN»Ȉ @Fl2b…=Ó¬³û¯%Lìr×qGЭÍ~ì}Ý~ ]>ÜGH€ØdÄ #6YØõâùûíßPgÒAò „ç»sø@î¿$ß09ãâÀ:ˆ @Fl2b…ÍQ÷ë,­ï,ŸÎw—õ„Ò›ÒÙ¼Í Ñn2b€ŒØdasÔ êÈwuu¾°óô˜Ýæ|нùbzqh7±Ȉ @Fl²¹x¾Ñ\G_×1;bîÑÝÙt÷Î>¾‘óÁ&€§ÝdÄ #6±Èži–0 L8¥¹¯!v¿¾®­Ȇbä{h[Ð[ ÝdÄ #6±È¢ž/Þ×äð„OyTyÌ#¿ò]0={’wv7:?ÆÅôˆ @Fl2bEåâùø3¹˜QóÎF¾;{®yŒ¾î‚—ïžó ç=Ðn2b€ŒØdÍÅýŽ@÷u‡µ|ÉwÂèÎnºîïkIˆç‹ €ŒØdÄ {¦Y¾ëŇyCï¾Fsý†ù-tvë:ÿºŽ˜½¢ÝdÄ #6±ÈR>_ vsmartcard-3.3/docs/_images/inheritance-a86900bf11776a1a970033d4d69ace6796eff5e9.png0000644000175000017500000001703413546304763025152 0ustar philphil‰PNG  IHDR8J@ŸÓbKGDÿÿÿ ½§“ÑIDATxœíÝ{PSgúð/wlŠ\†¶‹“ˆU¬®£($¬’h-^f‡®8V »Emuíè2¨ívöçnk¥xm)Šãbí¶ÎhgÛiÝŽ¥.^`·ÂjÇíŒ "cq¤#·¤ y~8çô„œ“„€"õùÌt&œ¼ïó>ï%©ç=IŽcŒ1ÆcßáN€1ÆcŒ1vÿð cŒ1ÆcÿáN€1ƉîܹƒM›6!::z¸SaŒ1—üüüð‡?üAü›OcŒ1/ôôô`Ê”)X±bÅp§Âc.•””8üÍbŒ1Æcì!Â'Œ1ÆcŒ=Dø€1Æ»rsse—––8V\\Ü`ÓqÉ›œ”hµÚ!‰?:{öìN§ƒ^¯‡N§Ã_|1àö´Z-ˆ¥¥¥b¬”””——8–·;ÞÖ—«7c:ÐÜŠŠŠ0wî\ <öØcÇ)óV__ƒÁƒÁ€Q£F‰kkk‡´ÄcŒ±ëìì¤òòòADZÙlDD¤V«\×›:ž²ÙlƒŠ/ôK ÑhœÊÜË>WTTÐòåË©§§‡ˆˆººº¨ªªÊm=¹¼ËÊÊhåÊ•ÔÛÛKDD½½½tòäÉfî^ÿ¶'¹ÞÎcÿzžŒ©R> ˆENNjkk‘››‹ëׯÃ`0Àd2á½÷ÞCCC€»;Ð7nÄÁƒÑÞÞŽ7ÞxÙÙÙb;Û¶mÑ#G0vìXèt:lݺ V«‘™™‰S§N!??µµµ8þ< ¬OÈëí·ßF@@ 4 Ñ×ׇ   |ùå—¨¨¨!Ô¯¬¬Dll,FF»Ýî0>åååbŸŸ|òI\½z?ýô|}}±k×.hµZ§¾ÅÄÄ8Œ“Íf“í;”••áèÑ£Œ=z½Þ«¼8€cÇŽÁßÿî?›üýý‘šš hnnÆË/¿ì”»Z­†ÉdBuu5V­Z…gžyF¶\ÿ1OIIAWW—˜›tœâããÑØØ»ÝŽ€€ìÝ»W¼ $]O'Ož„ŸŸŸÓ8›L&,Y²Ä)cÇŽ9cÿz6lPÓþíÏœ9sçÎÅÂ… a±X’’‚o¿ýqqq0™Løßÿþ‡žž$%%¹íÛ¦M›ÐÒÒƒÁ€={ö(Žù­[·ð§?ý Ÿ}ö<ˆºº:|ûí·#nÞrùy:OðicŒ1ÆÜ^¨¯¯§E‹Qee%ÑÏ»utá±¼tOúX£ÑÅb!"¢¶¶6š>}ºC¹‰'Rss39îDFDDPSSuwwSpp0]»vº»»iòäÉŠñúç%äa4éÔ©SDDÔ××GD¤C¨o4éìÙ³DDtæÌ w#!~vv6ÕÕÕQSSeddÉöM:6J}'rÜ5–ò&oi¬#GŽ^¯§3f¸Ì]:þ Šå¤m»šg"¢ ÐéÓ§‰ˆèܹsd4bÈ‘Ž™\JãØgYiLû·ùòeÊÎÎ&"¢ýû÷ÓÿýßÿQxx¸Sþžô­ÿëAi,ß|óMÊÏϧ¹sçÒ;wFä¼¹zMx:Orø cŒ1v$&&¢¥¥8tèvîÜéð|HH¦L™â6áøñãØ½{7üüüÐÚÚêðüP\\Œžž,[¶ F£Š &Ƈ˜˜@__ŸËxry]¾|))) î,+Åê744`öìÙ€¤¤$¨T*Å>^¼x¯¼òŠø·ÕjuÙ7w}€¨¨(ܸqÃé> Þ䉛7o"** K—.ÅÒ¥KÅ]`¥Ü¥ão³ÙËIÛþðÃç1gÎÀ¬Y³ÐÔÔäù<ܳ@iLû·«ÕŠÖÖVAqq1¬V+ÊÊʰoß¾÷M®'NDhh(òóóƒüü||øá‡#vÞ¼§‚‚·±À‡ˆÈ£’Œ1Æuuuá“O>á;3&Ãjµbîܹ¨©©?6'~¹Ý_%%%)â+Œ1Æc¿·nÝÂóÏ?ïp,;;ëÖ­»¯yÔ××£°°k×®ÿñÏ,|ÀcŒ1ö 0vìXTUU w˜6mª««ŽóîÿƒƒïÌcŒyàöíÛÃcŒ ¾ÀcŒy 33‹ øÍo~ƒ_ÿú×ÃcŒyÅáàæÍ›0›ÍÕ óBPPžxâ‰ai»··---ÃÒ6cŒ€&Nœèuýžž˜Ífttt »»f³‹èêê‚ÙlíÄjµ¢¦¦555øøã¡V«±hÑ"\¹re{ÄcC¯ÿL‡€;wŠ·tf#ÃW_}…mÛ¶ KÛçÏŸGmm-&Mš4,í3ÆØÑ£G‘““³Ù,þwûömñçö„¼÷õõÁÏϾ¾w?ùÚÛÛ ___<òÈ#P©T AHH¨T*Œ3Flë›o¾Á¸qã0cÆ ¬^½z½'OžäÆØï™gžqøÛá <<óæÍ»¯ ±Áùî»ï†­m"ÂÌ™3Å;&2ÆØýV__¨¨(ÄÆÆ",, *• ÷¤­?þñˆÅرcÅcüÿLÆØHÄß`Œ16bùûûcêÔ©÷¥-þÌ?cì—‚ˆ1ÆcŒ±‡È=;ÈÍÍ”––ŠÇ¤=åMoÔ××Ã`0À`0`Ô¨QâãÚÚZêKóܳgt:ôz=t:¾øâ‹{•öˆ$¬ )oç9..n°é¸4”ëO«ÕIüÔе¨ÕjAD(--c¥¤¤ ¼¼|À±¼5ØyÊqÖÜ7ß|ƒääd Ìž=»wïFqq1’““¡ÓéP\\ ›Í¸té’øž’””„ððpÀßÿþwÌœ93gÎÄÇ 8|ø0´Z­XF`³Ù°yófÌŸ?ƒeee#bNóÞz¿Þÿcì¡C;vì ¡¦V«e{Sÿ~Lž´|ùrêéé!"¢®®.ªªªÒü¤îÅœyêìÙ³töìÙADZÙl^Ïó½Z6›mÐñ…FãTæ^¾&¼]‹ry—••ÑÊ•+©··—ˆˆz{{éäÉ“Ì|`íJyÚg¥C9ÎÂñÄÄDºqã†xüõ×_§ßÿþ÷âßkÖ¬¡Ý»w;Õÿè£(??Ÿˆˆ&MšDÔÕÕE“'O&"¢›7oÒ;wœÚßµk½ÿþûâß#qN:ž”Î÷@Æ©t@ºÛ*ÝÍT«ÕX³f ¦OŸŽ½{÷ŠeËËËqýúu hµZñqaa!233‘––†yóæáûï¿lÛ¶ Ó¦MCZZ¶nÝêPÿ­·ÞÛkhhÀ¼yó`0°`Á@EERSS1mÚ4|úé§²ñ ¹¹Y¶m9Je]å¹|ùrlÛ¶ €Ñ£GC¯×Ëæ'k ùÝo_ý5:;;=.¿~ýz±¯·o߯´iÓ@Dâ:ŠÅ† àçç‡k×®9Ìsÿµ¦4~€ü<w×åÚµkñÔSOaß¾}X±b¦M›†}ûö)ÆrJMMÅûï¿/Îk~~¾GkNãW¿ú’““ñôÓO£°°v»Ý!o麑{MÈõKZ'<<\¶ß‚²²2§µØÔÔ¤8Ž®ò>pàþüç?Ãßÿî׆üýý‘šš @ùuÒÿ}A©œtÌËËËò“öyÕªUHKKƒÁ`ÀÓO?-ÞURCØu—ç·ÞzK6Oß{¤F…'N «« ðùçŸ;ÌÖ-[pèÐ!§zûÛßð /"##Å_®‰ŒŒ9Õ;|ø0®_¿Žôôt,Y²o¾ù戜oÞW•æ€1Ƙ—¤gîvR¤»1ÒÝ̈ˆjjj¢îînJHHp(+w ;;›êêꈈ¨©©‰222ˆˆhâĉÔÜÜLD®w`F#:uŠˆˆúúúˆˆÈb±Q[[MŸ>]1žRÛrýô&Ïøøx™‘“ÏO.–'ùIÝÏݯ9sæÐc=FóæÍ£={öPUU•Ë+õõõ´hÑ"""ª¬¬¤ââb"úy¬"""èÂ… Çý×šÒø©ÕjÙùâ ë288˜®]»FÝÝÝ4yòdÅxÒœ¤yxºæ¤1ŒF£8>gΜ¡ððp§1rµÖ”ú%ÔQz^ ·•rv—·4Ö‘#GH¯×ÓŒ3sâIß\•ÆÜÕ<-X°€NŸ>MDDçÎ#£ÑèCŽt=y:Öî®\½z• H£ÑÐìÙ³©ßÛ)iµZ‡¿üñGŠ'»ÝNDw¯¢7ŽÆGgΜQÌ™ˆè‰'ž ãÇÑ?þñ‡öFÊœ¨ÕêA¿ÿ÷ÇWclà¼þ "‡††b„ à´û&çâÅ‹xå•WÄ¿­V+àÀ(..FOO–-[£Ñ([ÿòåËHIIøùùŽ?ŽÝ»wÃÏÏ­­­Šñ”Úª<£¢¢pãÆ DGG;Ä’ËO.Ö@ò€ÖÖVüå/qYf(µ¶¶¢µµ.\Àĉ±cÇŲ‰‰‰hiiAGG:„;w:<‚)S¦¸m“ˆÇPžéº7nbbb}}}Šñ”ròtÍIc444ˆ?‘š””•J¥ØG¹yw÷zp÷¼ÜZt5Ž®òŽŒŒÄÍ›7…¥K—béÒ¥âU@¥5Ûÿ}A©œtÌ]å˜3g`Ö¬YhjjrŠáŽ7c-güøñâÏóçÏcÆŒhkkwòÛÛÛñè£:Ôù裰xñbøøøÖ­[‡êêjøúúbÉ’%8}ú´b{?þ8²³³&“ Fäœ öýŸ1ÆØž ¸ÛIÑjµÔÙÙI---)—»2 ‹‹‹ŸgffÒ¥K—ÄãV«•ˆˆÌf3uvvRll¬S}Ñh¤êêj"rÜ)joo§¶¶6ŠŽŽVŒ§Ô¶”»7yVTTP^^žø¹k³ÙLUUU²ùÉÅò$?©û¹û•œœLiiiôúë¯Ó?þèÑw¶oßN[·n%N'“»:Ôžû¯5¥ñS«Õ²óÑ?¾ôŠ•F£qOJÈËÓ5'‘‘‘A555Dtwg4""Âi|\½&”ú%ÔQz^ ·Èæì.ï²²2Z±b…Ëf³‰W”Ölÿñ÷¤œÒ˜ }ž?¾Ãn³°{ìn§Xº¾<k¹÷i[ß}÷xì‡~ ´zõjñØ«¯¾J;wît¨;g·¶¥ßxòÉ'eÛ¬_¿žÎ;GDDÿùÏÀˆ›µZ=è÷ÿþø cŒ Ü€®B§Ó!--ÍádffÂd2!++K|ÿüsèt:§ç…øyyy0›Ík111Ñm¿åò~ñÅa±XššŠÀÀ@øúúbõêÕ”_'ýyRNiL…>Oš4 EEEâ]^…xw¤ëK.¹±–{G¼óÎ;¸xñ"T*ìv;¾þúkœ8qÉÉÉðõõErr2~÷»ß‰å¯\¹«ÕêpçìÍ›7#-- >>>(**œ8qýë_ñÃ?`Þ¼yxíµ×0þ|¡  mmm°Ûí¸téNœ81âæÄÛ÷Õ‚‚æš1Ƙ{>D?–§¤¤ÄáÒ,{ð çœ;wøNÀŒ±aÃÿßbŒ±ã;3Æ~1nݺ…çŸÞáXvv6Ö­[7L1Æc>`ŒýbŒ;UUUÃcŒ1ö@»gwfŒ1ÆcŒ=xø cŒ±ë§Ÿ~Â;A§§þþþðóóƒÍfC__BCC¡R© R©‚1cÆà‘GJ¥Bhh(BCCÅŸøõÔÆqõêU¼ú꫘5k, vïÞíð3ÙŒ16¢££‘——§ø¼Ã €ÅbÁûï¿Ï“bCçÖ­[ÃÖ¶J¥ÂÑ£GqáÂ…aË1öpkmmuºÇˆœ;wîÀb± ³³f³‹?üð:::`±X`±XÐÓÓƒ¾¾>ÂÇǽ½½”O,Ο?þóŸøì³ÏN‡Ù³g#''ç^w›1Æ\*))qù¼Ã €ð3tŒybÊ”)ß|‰1ƆSpp0‚ƒƒ>d1O:___DDD ,, wîÜñèf˜Œ16Üø#@Œ1ƘÒÒÒðÜsÏ!''*• MMM|E”16"ð—€cŒ1/bÙ²eP©TƒŠ“››+{¼´´tÀ±âââ•‹;Þä¤D«ÕIüÔÙ³gt:ôz=t:¾øâ‹·§ÕjAD(--c¥¤¤ ¼¼|À±¼5ØyŠq®¯¯‡Á`€Á`À¨Q£ÄǵµµŽápBamDGG#55³fÍÂ7ß|#>ÿÒK/Á`08Äã¹ a»1cŒ1ö råÊ:vìØ ãØl6""R«Õ®ëMOÙl¶AÅú%Ðh4NeîeŸ+**hùòåÔÓÓCDD]]]TUUå¶ž\Þeee´råJêíí%"¢ÞÞ^:yòä3w¯Û‚Œ“\Œ¡çÁÆ›0aMŸ>ºººˆèçµ!”¹zõ*%%%‘Õj¥¤¤$zöÙg©¹¹™ˆxnåìØ±Ãe]þcŒ1v¬_¿z½ÙÙÙ¸}û6’’’PWW‡øøx444 66999¨­­Enn.®_¿ƒÁ“É„÷Þ{ îîRnܸD{{;Þxã dgg‹ílÛ¶ GŽÁرc¡Óé°uëV€Z­Fff&N:…üü|ÔÖÖâüùó(((@pp°bCff&4 >Œ7òÜðÌðÆcl(¸»P__O‹-""¢ÊÊJ*..&¢Ÿwü"""èÂ… byéN ô±F£!‹ÅBDDmmm4}út‡r'NwF¥;„ÔÔÔDÝÝÝL×®]£îînš—ñäòº|ù2RRR@Ü}TŠ!ÔohhÀìÙ³III.¿;qñâE¼òÊ+âßV«ÕeßÜ=QQQ¸q㢣£Ž{“wdd$nÞ¼‰¨¨(,]ºK—.wx•r—Ž¿ÍfS,'mûÃ?TœhllÄœ9s³fÍBSS“S wäòp7–‰¸Ÿ  /¼€>ø@ vsmartcard-3.3/docs/_images/inheritance-2bbcd7895a62e5ec48d90ac42e0891ae2f9feca4.png.map0000644000175000017500000000035213546304763026267 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-bdd1c7794f65b715aa64065713cf57e55a7f9ece.png.map0000644000175000017500000000321313546304763026060 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-d42052fb29a3802f517ea5fd6564e26a29987320.png0000644000175000017500000002231113546304763024706 0ustar philphil‰PNG  IHDR`%ÿ‚bKGDÿÿÿ ½§“ IDATxœíÝ{PSWþðs å5èò‹¤’ ®U1͸¶Š Š®ÖÇjZEÐYÝh]¨FÍlç7ºi;«vÙµÂØZÇ`iÕ‡(*Êΰ“:²Zë UHA@@©" ÜÜß§{÷zo’HšïçrÏ9ßï½ç›Ã!¯E!Oâå7þÏíÛ·«««Ý› p/³Ù<{öìÈÈHW N’dqq±···+#Ê«¯¾úú믻hð³gÏ>zôÈEƒƒnÔ¨Q)))îμ8~ý…d0RSSÝ› p¯ÖÖÖ7n¸hÔÓÓôöÛo»bp0¢;vÌu û÷ïÃJ屎;æîÀ ^€Ç <Ž ¥R‰o˜Íf™Lf»ñ  ,²gdÜŒåøÃ“'OB?üðÃÖ­[Í– ˆŒŒ µZ}üøq‡ž3gŽ=ÍpÂÌ4òòòœˆèD¸ÆÆÆ5kÖ¼ÿþû«W¯nllt.îðxN Ù1/2™lf=}Y¬éÍ›7U*•J¥š8qâÞ½{ÓÒÒ”JåÞ½{B¿üòKFFÆ”)SBwîÜY¿~½Z­>{öìóXEȾyq.ŠÓ|{Ú;×…‹;ÈòåË5Í´iÓ¶¡¡!==}ãÆJ¥²¶¶Ö¹pöD|ŽJ ¼x¬¾)U¥Ríܹ“Ï秦¦"„nß¾-‹åryPPÑh$¢µµ544T&“UTTèõúŠŠŠîîî3f¤¥¥!„Ö¬Y3fÌ@ V«%Irrò£GI’ܳg«=säÙ³gûûûO:U¥RÕÕÕq›µ···´´…Âîînœí²eËJJJV­ZõÅ_¬_¿Þ‰lóòòéÓg%¬p[·nݵkWtt´ÑhܺukCC3®{±jŒ5e¹¹¹ÅÅÅ7oÞDÉd²íÛ·³® bÔØ¡C‡ì/0SæP¡§çÅv¶¶gÜbÂvθńY×G ‘šš:þüýû÷ÿç?ÿ3fÌ·ß~«×ëBóæÍûóŸÿÌçó¿øâ ü›,'''&&¦½½=""âùª"äȼ ›+Õ?ðËËË|X.—+•ÊÇ‹ÅâU«V566&%% £Ñ(‘HBBBÂÂÂRSS¯\¹’––f0Bz½þÔ©Sf³9==½­­­¥¥E$ ­V‹Òh4:.::!d2™ð±Âá;qݰ0V¸ùóç_¾|™Žh-Ü7FliEQE=z”zÚùóç÷íÛwîܹüü||T*‹Åf³ß–J¥ôýEUTTdfffgg¿ùæ›øÎ9sæœ8q¢³³“¢¨3fP5}útkí™#'%%õõõáÁ-6KHH0™L&“iÊ”)¸Yooï²eËúúú–.]êD¶*•jÕªUeee¸+aV{:<°Åf2™Œ•-EQßÿ=3¢sá,^V¸„„:hBB+.Ó½{÷ÊËË©!õ§?ýiÙ²ehoo?}ú4ë(«ÆXSFÿKYº&ø]ce}Ê*0êéy±­í·–‰=3n1aêéÇ`bb¢ÉdêëëKLLÄGß{ï½;wîœ;wnæÌ™ÉÉÉß}÷³#ùáÇ>œ7ožýUDYZLžÑ¶mÛ-Zôé§Ÿvuu ºR9:/£Š(×?ð*ûì³þþ~©TŠ?fÉJ˜{vxp:O|Ãb3oooV¶8¢D"¡#:Îâõa… khhˆŠŠjhh cÅeMzMMMGG‡µ’pBkkëÉ“'ËÊÊòóó333YG¹5Æ*///ôßYã^Ĩ1G Y™2‡ ==/¶³µ=ãÖ2±gÆ-&̺>ô¡žžž{÷î½úê« …¢²²!ôÖ[o-X°€Ù7&&&((!Ô××çPýüóÏ'Nœ@C§±±ñôéÓgÏžýâ‹/222XGm¬TŽVw¥ò¾µ.ç‘™³/B$ݽ{·¦¦?IO’$Þå“$‰8k)‹ÉdÒh4øâtttðx<’$qèÐÐP<㸥7+¢sá*-†–Õ ——ׄ š››ù|>÷hLLÌ Ell,~°Éd²ìì쀀___„PÿæÍ›}}}'Ožlq|V{æÈƒaáÂ…qqqk×®µØL­VgeeEFFQUUU]]½aÆ?þñsçÎmllt"ÛK—.©Õê®®.kŸ°µ‘­F£Y½zµB¡ˆˆˆ?~¼Ùj4šÞÞ^kí gñú0Ã!„t:Ý_þò>ŸßÑÑ¡ÓélÇMJJ²xœóÃ?DEE)•Êèè芊 ÖQ5†ÏT,kµZ>ŸO’$÷L™5†_ø`ò)³]`ƒfkûÊ[KØž·–0óú,Z´H¡P „²²²BEEEï¼óBhÁ‚ …Â××—Þý¨TªÚÚZ•J•™™¹aÆÞÞÞÌÌÌ©S§Ú_E&LËåÏÑ9 ÁÁÁkÖ¬™9s&÷ƒÐCXEÜÐC^E[¶l±³ 31Üî»víÚ˜˜Ü%))©­­ oò|||vìØQ__ÿ؈‰‰©¬¬\¸paXXžw&­V›‘‘1nÜ8©TZ__¿råÊðð𜜜E‹UWWët:­V;zô謬,‘HÄ ÇŠxúôi'Â9´@0ÄðAðÔ"pÅK`´ÎÎNîK`à…äÒÅV*¦Ë—/Ëårú52úžá 7 Y`öÁЂoæ€çR|||||<ý#÷IV—††ˆ¸|<l€àq~} Œ¢¨ºº:÷¦Üëþýû.¿µµjÌà¯q‘ÎÎN¨"ÕÙÙéîÀ … ( !ÔÑÑQ__ïîd€›ÅÆÆºè+È(Šºzõª+F#͸qã"""\4xmmíãÇ]48áF% Ýxqüºðð xØÀãÀ6@ð8°€Ç <l€àq` xØÀãx?c½^ÿóÏ?I*`¨Lš4)>>Þ½9ìÞ½;((Ƚ9€B(&$$¸; xʳn€?55µ°°ðöíÛ!±X,—˃‚‚ŒF#A­­­¡¡¡2™lûöíÝÝÝ3fÌHKKÃ#¬Y³f̘1@­VK$’äääG’$¹gϽ^Ïì"‹'MšTYY™››+‰JKKÃÃÃU*U]]«™ŸŸ_]]ݺu뺻»él‹ŠŠôz}`` þÑžpô‰Ìž=ÛßßêÔ©ÃÉåòööö––¡PØÝÝÍ tèСœœœ'N¬^½!~ãÆ „Ð?þÎMlÐö#AgggPP——å]µµÂ §¯¸¸øæÍ›¡A ãСCöO³0ASS“iÂÊËË|X.—³Â%%% £Ñ(‘HBBBÂÂÂXáB̈mmmt¸3gΔ””Ô×ׇÇá6“Éd&“Éd2M™2…Îöûï¿W©T«V­*++³?>j;œÙlNHH #2õöö®\¹Òd2-[¶Œ>ëþóŸ'NœØ·oŽëh{Û“2D†CÓD1 cÐi 84³ÌĸÝqûÚÚÚ?üðË/¿üî»ï(ŠŠ‹‹#I’$Éäädœabb¢ÉdêëëKLL¤Ó–J¥‰‰‰999ÙÙÙ»wïÆªÕêeË– àX×Y,ߺuËZ8zX‹áp&̈t¸ç± À†¡H&“\¿~}×®]ôÁÁÁA „‚À7(ŠêîîÎÉÉ)//'I²¤¤„n\VVvñâŹsçVUUùûû#„FEeuÁ#ã1ñøÖšy{{óx<„þ“H$‰¤¿¿_*•¦¤¤ØŽd#A<ŽÈ ôÞ{ïµµµ©ÕêŸ~ú©¶¶V$!„V¬XwíÚµ¢¢"Vbö´gjllŸÏ=sàÀ…BK’¤L&ËÎÎðõõÅ úûû7oÞìëë;yòd‹ãs»àa5ÍêÕ« EDDÄÚµk¹ÍÔjuVVVdd$^ú«ªªª««FcoooWW—µÏl[ ‡# †… ÆÅÅY ÇŠ¨Ñhè@%%%ß~û­¿¿ÿõë×?ÿüó>ú!rçΗ^z©ªªjß¾}ÌÄl·çæüÊ+¯Èår«3ä2ýýý‰$##ÃßߟûÉg…§O,kµZ>Ÿ?haà—ϘlL³0Æo{špUlÙ²ÅF!±º0ãv§»$%%µµµáMžÏŽ;êëë333OŸ>­ÑhV¬X¡P(BYYYÌüµZmFFƸqã¤RéâÅ‹?ýôÓ•+W†‡‡çää,Z´¨ººZ§ÓiµÚÑ£G deeὈpøšTVV.\¸0,,ŒŽ±¾¾žG’¤Ó #AQÔ³ô?vì|ÝËH3&e$ä0rTVVæåå}þùçÁÁÁ!™LVQQñ„`úg€,ñññÌïævõvd˜ÃÀó¾6@ð8ÏúØ£GÜò#`ÃÀÀ€»S@W®\÷쯯ÏÝ)Û³¾ à¹/ÀãÀ6@ð8°€Ç <l€àq` xØÀãÀ6@ð8výÏP«««oܸáçççêl€Kµ··/^¼822Ò݉üêÀ/¿ü²»³Îëé鉋‹›6mš»A!’$ÿö·¿ w'œwçέ[·áê@gΜéîîvu02=ú­·ÞBvn€îß¿?oÞ¼ßüæ7.Î ¸Ö÷ßßÓÓãî,þ' @.—»; à¼æææÚÚZwgñ+³Ù, ¢žkÇž@>LMMžX`¤9vì¾/ÀãÀgÈ6@J¥ß0›Í2™ÌvãAXdÏȸ+J^^^FF†Z­vèùUçÂM™2E¥R©Tª¥K—"§ÎÔÑ.̈Î]Ø‹.*„М9sl7vúÜÃÍŒâ\]9îÙgÙ¡^S§NU«Õ›6mR(ÍÍÍtô8zäðØe =]QÿLÅÆÆæçç#„öïß;ò+йø¸®ZZ ŠÂ]¯ì ÁeqåË—k4šAßÿ×ÐОž¾qãF¥RÉ|¹ÜáX5†un­Ììz—J¥Ú¹s'ŸÏOMM-,,Dݾ}[,Ëåò   £ÑHDkkkhh¨L&«¨¨ÐëõÝÝÝ3fÌHKKC­Y³f̘1@­VK$’äääG’$¹gÏV{æÈ³gÏö÷÷Ÿ:uªJ¥ª««ã6koooii …ô{ÜŠŠŠôz}`` þÑ¥áÆŒ³ÿ~z/]º´aóٜžž>kÖ,úÄÿþ÷¿ÿüóÏcÇŽU*•‡¦¯FBB‚ÑhÌÍÍ8qbUUÝ‘›3=¬ˆz½þÔ©S̈#JMMÏ«¯¾jñ(«®nß¾‹Å“&Mª¬¬ÌÍÍ-..¾yó&BH&“mß¾UTÈf]Í›7Õž9²H$*-- MMM¬f~~~uuuëÖ­c¾qÒ‰ºâ†³XWÜp¶g™>뺺ºÍ›7[««7Þx#22rìØ±ƒUHHH^^ž¯¬¬,:útéÒ¥3føûû[<Ê­(æ£Û¡Š:tèý놊rÅ2åh³Ê Y©(Ö2E_îînG—©ððð7n „~üñÇððp„ÐðWÔÇkjjfΜiñ¨µÅÇâ/5GŸgY ,VKyyùÁƒíœnfb̾*•J(âEEE¥¥¥ô\‹ÅâU«V566†……á¹ŽŠŠºpáA©©©W®\IKK3 ÌÊikkkii‰DƒA«Õ"„4N§‹ŽŽF™L&ú’º"·Æ]¸œÜ½óÎ;ÅÅÅB¡011‘¾“ ˆmÛ¶QRRJòóóëëëãóùŸ}öž$£ÑøöÛo§¤¤ „x<žN§‹ÅW¯^ÅHV{æÈÞÞÞ¥¥¥>>>¡ææfn³¤¤$½^:yò$޾wïÞÍ›7?~ü8===%%Å¥áñ´´´üüü‰'®X±‚y5‚ƒƒ£££sss“’’âããéŽÜœi¬ˆü1³#kâš››y<žs“>$>ÿüó‚‚‚)S¦H¥Rü¨`²VWGŽijjÊÍÍ­¨¨ ïç²YWK–,aµgŽœœœ|æÌŸK—.ÕÕÕ±šùúú666"FQ!§êŠYª+n8Û³LŸõ½{÷lÔÇ{íµ×ì)*Zlllkk+ý£>b5xðàA]]½ÓïÛ·ooll”H$‹/¦w4nE1ÝUÔ‘#Gì_7lT”+–)G ˜»LY¬(Ö2ż·nÝrh™BMš4髯¾úíoûÃ?ب¨úúz'ÊÀ×®]{÷Ýw'Ož<{ölîß`ýRstñáv±5°X-:Îþéf&ÆìË<ÇåË—3皢¨ÌÌL„PJJ ý+©¬¬Œ¢¨ùóçŸ?>::zÉ’%{÷îeVNffæ¦M›.\¸PTT„okk£×yÑ¥á˜5†uÎ-3ÌÉ L&+((¸~ýú®]»è;ƒƒƒñÇ ‚À7(ŠÂ;Мœœòòr’$KJJpã²²²‹/Î;·ªª ÿõ6jÔ(z(V{æÈô¿Öšñx<ü;žþM/‘H$I¿T*MIIqi8îŸV& €Ž…Oü½÷Þ›4iRMM ~þŒy5p8“ÉÄìÈ͙ƊÈêÈÒÕÕõË/¿X<4<úûûûûûI’ìééyòä 먺—ÅËË ý·®¸E…lÖ·=sdô߉¶ØÌÛÛ›UTÈÙºb…³ØŒÎö,3ÏúîÝ»ÖêÊþ¢¢ÕÔÔDDDPeí©žž÷V”——×ÀÀ€Ùlþå—_¸eÏ­(Ö£ÛþŠrtÝ@V*ÊEË”µpÈREq—)‹ÅZ¦˜W+ŠCµbÅŠ¸¸¸k×®ÙøÓüáÇEY<ôŒ?~L’¤Ùl~òäIWWë¨C¿Ô]|Ð3¬«92ÝÌÄXáèB¡¹tà EQI’Ü$™˜5@QTGGÇ#I‡ mhhˆŠŠÂ-}||\ŽYcÈuÏyyyM˜0¡¹¹™ÏçsÆÄÄ8p@¡PÄÆÆ’$‰’ÉdÙÙÙ¾¾¾¡þþþÍ›7ûúúNž<Ùâø¬öÌ‘ ÃÂ… ãââÖ®]k±™Z­ÎÊÊŠŒŒ$¢ªªªººÚh4ööövuuYûÜãP…³8xFFƸqã¤RéâÅ‹™'žÐÖÖæååź111F¡P0;r‡Å§¶aÃÖýZ­ÖFG‘H$ -æ9<‚x÷Ýwßxã Äø,"ÍF]áË"‹µZ-ŸÏ'I’;¶ëÊÆ,k4šÕ«W+ŠˆˆˆñãÇÛST6lÐh4NÔ+œÅº´¨˜³üûßÿžyÖIIIÖêêßÿþ÷‚ ¦OŸ>hQuttàgË{{{wïÞM?ÀõÊ+¯¼þúëÖŽƒM›6%&&Ž;¶¿¿Ÿùü6„…_aÚŠz–eÊ¡p·VQô2źA8ºL…„„ܹs祗^²˜múôé.ú ¨¨¨âââ¥K—zyy9´ø Î/5Gô «²T-[¶l±sº™‰±ú®]»6&&†îE/!Ÿ;vÔ××gffž>}Z£Ñ¬X±B¡P „²²²˜çŬœúúú•+W†‡‡çää,Z´¨ººZ§ÓiµÚÑ£G dee‰D"…ûë_ÿŠì®±ÿ¡ìpöìÙ¶¶6{Z;]¾|Y.—wvvgPƒÁP[[;œm;zô¨»SxÑ s]555]¼xqxb Êd2»;‹Êð/SÇŽÃϸ,>,¬¹–J¥/R8zö|<£øøøøøxwg^4PW`A9yÖ\3ß÷„³¾6@ð8v½|ôèQk,Ï‹{÷îedd¸;‹ÿijj*((pwÀy]]]R©ÔÝYüÊËËË`0¸÷#iàýôÓO6Þq?„¼½½aññXøA¹æ‡#¼ xØÀãÀ6@ð8°€Ç <l€àq` xØÀã°ÿg¨ùùù!!!nI¸KooïêÕ«]4øÎ;E"‘‹#VÿË/¿¼`Áw'–±7@ÁÁÁr¹Ü-©w9vì˜ëPQ¨···¬¬ÌÝY€Uð<l€àqÞ)•Jú¶Ùl–Éd¶ÛÚÀ¢9sæØÓÌl6³Bäååedd¨ÕêãÇ#„¦L™¢R©T*Uee¥Å¬”J¥Å YãØÏl6[“ÉZbL¬KíPÖ87.Å<ÍAçݹüí)Tº¥CQèyq¢ wåË—k4šiÓ¦ :lCCCzzúÆ•Jemm­ëÂÙù€Žý .•JµsçN>ŸŸššZXXxûöm„X,–ËåAAAF£‘ ˆÖÖÖÐÐP™L¶}ûöŠŠŠîîî3f¤¥¥áÖ¬Y3fÌ@ V«%Irrò£GI’ܳg^¯gv‹Å“&Mª¬¬ÌÍ͉D¥¥¥ááá*•ª®®ŽÕÌÏϯ®®nݺuÝÝÝt¶EEEz½>00ÿ8f̘ýû÷#„d2YEE¾ñüÃh4ææænذŸ+IÖ8z½þÔ©Sf³9==½··÷àÁƒ8¥µk×ÒcVTTàk2sæÌ“'OåææþôÓOüñرc•JåáÇ™W•N !ôú믯\¹²­­í“O>¹ÿ>÷RûûûÆÄÄÄÔÔÔùóç3»„……?~œ{Ié„gÍšE7noo§O<44ÔÙš\qq±Ï¢E‹¼¼,ì°­U=ïÅÅÅ7oÞÄÖÑŠš7o«NèBeV”@ hjjbk±¢ÊËËééæV \.ooooii …¸ «Š˜Ý…B¡X,®®®>|ø°\.Ç%!‹W­ZÕØØ˜””$ŒF£D" KMM ¼råJZZšÁ``Íé7ß|ÓÒÒ"‰ ƒV«Ei4N2™LøŒœ‡ž.û¶¶6:Ü™3g,>Äàù2øèwÞ).. …‰‰‰ôAlÛ¶ ˆ’’’èèhú·©ŸŸ___ŸÏÿì³Ïè_WF£ñí·ßNIIAñxþøãøøxŠ¢ Cii Òh5rIDAT) }M^{í5„ÞåççOœ8qÅŠ¬Ætbëׯ'âƒ> â“O>±x©}}}F#EQóçÏÇ ºKBB÷’2ž5k³1÷ÄBwïÞ=qâ„Õ pÜW_}õõ×_OžŸ{4&&æÀ …"66–$I™L–àëë‹ô÷÷oÞ¼Ù××wòäÉÇçvÁÃj4šÕ«W+Šˆˆˆµk×r›©Õꬬ¬ÈÈH¼‚WUUUWWÆÞÞÞ®®®ÔÔTÄx¢ÅËËK«Õòù|¼ôãñ?øàn’Üq&Nœ˜‘‘1nÜ8©TºeË:¥ùóç3Çd]<~RRR[[÷• :±¥K—z©ßÿ}…BÊÊʲ1S4­VK'¼xñb‹‰………Ù3”sþïÿþoìØ±øyîgìmTNO,ÓÖÑŠ²XNˆSQãÇç6cV.æt[™Ù…[EÌî111¸ ³$|||vìØQ__Ÿ˜‰‰‰©¬¬\¸paXXk®Ysúé§Ÿ®\¹2<<<''gÑ¢EÕÕÕ:N«ÕŽ=z`` ++‹þî%ç±"Ö××ÓáH’´ø[ºt)ýÔ<¨§=z”CäòåËr¹¼³³Ó݉ Â¥“ÅÄ* ©Tú"…cêééùú믇-8jðg€€ÓâãããããBOž<ÑétøÎ™3gΛ7Ï­y·¡Kc¾ÛéÏØ ???î[à.ðEˆð8ìg€üýý Ü’ p—‰'ºnð‡BEy ³Ùü»ßýÎÝY€UEQîÎ`XÁK`ð8ÿ¡q¶FðÑ6ðIEND®B`‚vsmartcard-3.3/docs/_images/inheritance-6bbe035741f5d2dcb113ca7864c78d0280548c16.png0000644000175000017500000000557313546304763025046 0ustar philphil‰PNG  IHDR„$ŸV¼ßbKGDÿÿÿ ½§“ 0IDATxœíÝkPLïðç${)%Ķ]5%—Ü"†Ü^„H“¢ÉmŒq‹afߘa$†÷Hc†¦2Œ‘ÂÐ4cF)‘LJŠv£‹j˪ÍÖ>¿ÏßùçÖÖîvÄ÷óªçtÎ÷|ŸË>O=gÛ(Œ1€t¤Nø×Áb H c@b°sd•ýüü¦L™"I*@:nïÞ½«W¯–:‘ÿ¹ÿ~RR’§§§Ô‰€½¼xñ¢¦¦†y„½gddôcJ@b·nÝ’:…߯?ꇰ¹ØØXÖئ$‹1 1XŒ‰Áb HÌî‹qqq±B¡èìì´÷°Ó`+,,¤(Êh4Ú6l?#µèêê’:‘ ðïóGõ©Ýãàà`ƒÁàääĚѬ™à$Ÿ¿Èd2Š¢è¢…—óæ_TTéîîîìììïïðàÁ¦¦&;äþ7£ë¸äÆrýœj?¿ ‹ŠŠ.\èêêêêê:uêÔ{÷îõá¾6ϪÄ+’˜˜HQÔõë×YYÒG ƒB¡Y ìÔ56Ÿ» Oé#=ö©8ئî Ã/yyy!½^OŠ}˜››RZZÚÖÖöøñcŠ¢^¾|i»”ÿ]?þ”:KÙ0Õ?°Öááá‹/®«««¯¯ONNvqq±í-ú§Å+b6›SSS'Ož|åÊÖ…ÝÝÝô‹:33S¥RÙ*[ËÙvî‚>µeŸâßÅÄÄ`QäÆÌ¢Éd"_ܾ}Ûßß_¡P„††–••Ñ'ÔÕÕ :!$—Ëårù±cǘŋ/bŒ CBB‚J¥9räöíÛÛÛÛÉ-’““}|| …Z­>}ú´^¯ç^Ëd0öíÛçëë«P(&NœøúõkŒqJJJPPR©5jT\\\}}=op:o&B­a2™¬Ì?((H£ÑðÞÂN™ÓnÞ¼yóæÍOë7–äsáÂ…É“'ÓŪª*‡êêjzp’/ÒÒÒÆ‡~üh6›ËÊÊ>þŒ1¾sçNYYYww·N§›7o©&op¡LDZƒ4}Ÿó¯­­EÑ}Ìb§Ìi.ÆZ­vóæÍ½Í§¹¹ÙÉÉ©¸¸˜:´páBÌl‘‘‘MMM?~ü{ÌNämmú|‘Þ\µjUCCƒÑhŒ÷ööŽŽŽ¦‹$7ñàB©âÞŒgV(Œñ²eË–-[ÖÚÚªÕjÉ'뱦 ¾ …Æ$­££côèÑK—.½sçÎׯ_Y9  ª1ž7o=M“ÈÕÕÕ?þüôé“§§g~~¾ÈÄm¿’ßʹ ú´W}Êd÷Ÿ²²’öìÙСC±Å‹ñ÷ïß)Š¢\ÊÊÊR«Õã/_¾ 4èüùóz½^(&'??_¤ =rss .”‰Hk˜L&kòýú5B¨¹¹Y$g›gN“p1.((P*•...cǎݱcÙJ±0Ÿ˜˜˜Ý»wcŒÍf³··wzz:æ ¶wïÞ‘“-_Œ™èÖ¦ÏéÍ>bnn.y‰ÒE™LÆÍŸ\(Õ^gV¨––„Л7oH1==½ÇÅØšaÌ{KUUÕÖ­[}}})Šš;wîû÷ïhòVc\[[ëè蘓“ƒ1NMM6lù-“Î*<<üîÝ»GŽ9pà€ÐÀ©ˆõ3$ë+ç.¡¦€>Éà.µìô½c®P(:::,Ž]SSƒ1ž9s&)bŒM&“Ùl=ztffæùóç5MpppRRÒœ9szŒ3~üxÖñ?~¼¢¢‚ô¨Á`èîîæ .”‰ƒƒØóukòwwwGÕÖÖºººr#Û;s„лwïÄO°“úúzGGÇ–––ÖÖÖää䌌ŒáÇr?(ŽkÓ¦MëÖ­;uêT^^ž^¯ŠŠâžãããÓÛ”x[›þ®HoÒ¦-—ËYÅööö®®.GGG‘àB©öj<³B‘oooR¤¿aÍ0¶ä__ßË—/#„´ZmBBB||<ý¼m`5 PE®^½:bĈE‹!„V¯^½k×®ŒŒŒ7Ònذ!--­¤¤äÞ½{ííí¼9‹TÄúÒæ‘¡Oûܧ,½~—R©DÑüÉV†Ewú}I`Õj5BèÍ›7z½^¯×·¶¶¶··“sV®\ùäÉ“ÆÆÆ DGGs¯eòòò¢(ª²²’y°¹¹922rË–-Ÿ>}jkkËÌÌDaŒyƒ‹d"šüU*UPPÐ7¸aû!ójÉ’%NNN÷ïß¿víÚš5kÈ£,ºî¬FÃ"­Mã6»…ă ¥ÚÛñÌŒ0fÌ„ÐçÏŸI‘õ©ô¼·³òehyã¨Õê½{÷–––ŠœÃòg6 ³"f³ùêÕ«MMM*•ÊÃÃÃßß¿««+%%…yþÊ•+Ÿ>}êââÂ|./;ͼU°IdèÓû´=þîÌÒÙÙéîî~øðá®®®ÊÊÊéÓ§#Æ6µÐö5ý¼­¤¤„œÀ*bŒãâ⢢¢êêê0ÆZ­öáÇ㪪ª¬¬¬?~twwŸe²Á3cŒqNNN@@€\. IMMµp1Æïß¿Ĉ...ÉÉÉÜâ÷ïß÷ìÙãåå¥T*Ξ=‹1.//Ÿ3g޳³³³³sHHÈóçÏI|Öµ¯^½’ËåF£cl0öìÙ£V« ŤI“Èã3gΨT*¹\>cÆŒK—.‘Ü„‚ófº «šVæ1.,,\±b…›››R©ôóó#gl«ÌE Ä7p¡ &ÐG„cÌipÞ1ŒZ›ŽÆÛìÎ;=JÕòñÌ UWW·|ùr¥RÉz75s$Ûêe(t}¯†††µk×zzzÊd2ØØX­V;P¨"+V¬ˆŠŠbÒÙ³gïܹ“÷!n·fHîÝûú´·}Jã.µþ}.66þ…â?…ü Å?ç_þiù€Íq—Ú¿ó"0€Àb ’©©©QplÛ¶Mê¼@³ñŸ6°œ———5Ÿ¤ þð›1 1XŒ‰Áb H c@b°c¿›º¸¸8&&F’T€$t:F£‘:‹ÿ2dHRRùèø+‘ÖÇÄþ.ô3ئ$‹1 1XŒ‰Áb Hì?‹m ž7IEND®B`‚vsmartcard-3.3/docs/_images/inheritance-6200e2d9c7f43138ee8cae247df739aec4d9e742.png0000644000175000017500000002576413546304763025320 0ustar philphil‰PNG  IHDRlÝ_Õ2bKGDÿÿÿ ½§“ IDATxœíÝ{LTiš?ð¯Ò Ú"tÀ+JᢲJAÛ B[Åm”ˆì:^&½LœH†Å™ 8±ãNPÿùE[Ô¼{D]—i7;»®f’‰®ÙV£(^YY7tƒ"¨=^pª-„z~ôVMQuêJAqù~“ªÃ9ÏyÞ÷=ïk½çT3LDDDDDD4$ ÷uDDDDDÔw8 """"B>°|óûßÿ<ðU.DƒRdd$V­Zåë4ˆˆˆˆXM=z„-[¶ø*¢AiÏž=¾NˆˆˆÈŒ_"""""B8 """"B¼2ÈÉÉQ\^VVæQ¼¨¨¨ž¤ã”§yÙ3sæLÅå—.]Brr2´Z-P^^îµ}öVÂÃáÕj¡Õj±víZsÛöf›x»,áááHIIÁ'Ÿ|‚¯¾úÊ«±­Ùk{"""¢þêç«8WYYÙí½ÑhÄðáÃQVV† 6xc^c4{œ—©|Îâܹs ¼|ùÒã}Zï»'ep”PP.^¼Øƒ Ýçíã$((_ý5ôz=ñÙgŸy-¶«mODDDÔ_¹õIfÓ¦M8{ö,àíÛ·P«ÕóÙáÈÈHlÞ¼)))8räž>} ­V‹ââângMgM?Ž””¨Õjs\“]»vA­V#55;vì0/W©T(,,D\\ÊËË‘›› µZm>»n/¦)7???477›ójhh@zz:´Z-/^ìRŒÉ“'#99(((€ÑhT¬¯Q£FáüùóÐét€ço]·ùùùn矒’‚ºº:h4§e°l·¦¦&dee!55éé騫«Sl«-[¶àôéÓ€¶¶6ÄÇÇCDÛôèÑ£æ²(ÆwVgöèõzøûûÛÍ[©í¿ýö[¤¦¦B«Õ"## µ=Q¿%Š‹‹Å‘ššY¹r¥ˆˆTVVJQQ‘ˆˆ¨T* •{÷î™×7-·~-""mmm""òüùs‰ï¶îôéÓ¥©©IDDºººÌ •ÆÆFÑëõ ÍÍÍ¢×ë%&&ÆaLËÜ,sÉÌ̔˗/‹ˆHgg§K1233åÚµk""RUU%!!!ŠõõèÑ#Y·nDGGKBB‚ܼyÓ+ù[–Á“üMÛ)•!,,L4h49tèy?*•J²³³åîÝ»""ÒØØ(K–,±i«úúzÉÎÎ‘ŠŠ Ù¹s§âzÖe±ßYY3•aܸqòÇ?þÑn\¥º[¼x±\½zUDD®_¿.™™™ÝêÎÕ¶·ä¬_õ%·¾‹Çãõë×8yò$öïßßíïAAA˜3gŽ+“À™3gpðàAøùù¡¥¥¥Û:ÇŽCQQ:::°fÍdffÆŽ‹iÓ¦¦NŠ)S¦:;;Æ´—[}}=>ýôS€ŸŸŸK1HLLD`` b9#""pøðaÀ;w——×/ò`· Ö_Ú»w¯ùumm-6nÜh~o0(·•Á`@KK Nœ8S§NÙ]Ï’½øÎêÌš© UUUøâ‹/ìÆUª»`áÂ…€  ±±±[ݹÚöDDDDý•Û¿X½z5JKKÑÞÞnóÃPÓ‡(“aÆ™_1::­­­€¢¢"ܺu 6nçÍ›FN‡¸¸8óÊ,cZ¾6±Ó27Ëíf̘«W¯"))Éüýng1T*nܸùó磺ºíííŠuuÿþ}ÄÄÄ&L˜àµü-·õ$wÊ`)&&»wïÆ¬Y³”Û*77[·nEpp0ÂÃÃí®gY{ñÕ™= .„^¯‡ŸŸ>lW©î"##QUU…… ¢ººÚ<ñp·í‰ˆˆˆú+·'999ˆˆˆ@ii©Óu³²²°téR,[¶ X´hRSS1nÜ8ÀŠ+––Fƒ   nÛ®Zµ mmm0 ný@ÔQL¥¼ÊÊÊŸŸ®®.øûûãܹsNc””” //#GŽDll,‚ƒƒ»ÕéGÑûöíCmm-a4QRR‚µk×ö8Ë2Ìž=Û¶ms+ge°çÀ(,,„^¯‡Ñh„V«ÅöíÛÛjùòåX¿~=***ÌÛÛkSSYæÎ‹­[·ÚÄw…e½[úùÏŽßýîwŠq•Ú¾´´¿øÅ/`4ñÁ˜¯àô¤Þˆˆˆˆú“abú>~xbéçŸîË|h0 HJJBuuµÍÕ‹¡†ýŠˆˆˆúÞϼ®¦¦iii(,,òþ‰ˆˆˆú¯<€È’Z­Æ•+W|)à""""¢!„""""¢!„_"äZ[[qáÂ_§AÔ/Œ7¾NcÀ©ªªÂÓ§O}Q¿°páBLš4É×iôH· €N§Ã‘#G|• Ñ ôæÍŸîÿöíÛ=z´ù9DCÙ?ýÓ?qà .à§?ý©¯Ó ò¹Ç£ºº?þñ}Jt›üÃ?üÞ¾}ë«\ˆ¥Ñ£Gû:Lš4 ‘‘‘¾NƒÈç=_…ì=z4Ç¢ÿóòåK_§ÐcÝ&ðU.DDDDDÔËø#`""""¢!„"²+''ÇfYYY™G±¢¢¢zšŽSžæfÏÌ™3m–]ºt ÉÉÉÐjµHHH@yy¹×ö×[ù‡‡‡C«ÕB«ÕbíÚµþÒ¶½Õ.Þ.‹© ÉÉÉHJJBii©Íß,ËGýƒÒôßqd !@ß#m €>ú¿úÕ¯Ìïýë_ã£>0Ç!¢Aí?ÿó?åîÝ»^‰ÕÕÕ%*•Ê£m=ÝÎ]]]=Þ‡)†¥èèh›e±±±òìÙ3óû/^x¼Oëý÷´Ž¬Ë`ÊßQÜÞjoǵŒ÷æÍùì³Ïä·¿ý­Ûû*..öj^C…·ê­§}µ·Ç‘Þꃖzs é½qÐ^Ü2†˜b¦§§‹Ñh‘ôôt—ÆIK<û·ózn}Wˆ†¸M›6áìÙ³€·oßB­VCDüåÌNdd$6oÞ ???477C«Õ¢¸¸¸Û™ÓY¢ãÇ#%%jµÚ×d×®]P«ÕHMMÅŽ;ÌËU* ‡òòräææB­V›ÏŒÙ‹iÊ+%%GŽÁÓ§O¡Õj‘ŸŸôôthµZ,^¼ØåuuuÐh4ÈÈÈ@AAŒF£M}5 çÏŸ‡N§„„„xœ¿½ºu'Ë“'OFrr²ÃüM,Û®©© YYYHMMEzz:êêêÛjË–-8}ú4 ­­ ñññعs§ÍzG5·EAAMlWÛÝžÀÀ@”””àØ±c×#Ï455áÏþ³[ÛØG¬Ç뾪4Ž8:ÖÏÆwû`qq1ºõCoõA¥1ÄYþ@ÿçcˆR[)!"b³žåR\\l7¾'cÈÂ… QUU…k×®aÁ‚v×ô|<!¢^æì @MM¬\¹RDD*++¥¨¨Èü7Ó‘ÐÐP¹wï^·eÖ¯MgQÚÚÚDDäùóçßmÝéÓ§KSS“ˆt?Ó*¢×ë% @š››E¯×KLLŒÃ˜–yYæ“™™)—/_‘ÎÎN—cdffʵk×DD¤ªªJBBBlêëÑ£G²nÝ:‰ŽŽ–„„¹yó¦ÇùÛ«[wò·Œa/ÿ°°0Ñh4¢ÑhäСCÝö¥R©$;;Û|Œ466Ê’%KÛª¾¾^²³³ED¤¢¢BvîÜi·MMñ•b[æí¨Þ,)›9s¦ÝòÙÃ+ÎåææJxx¸üèG?’/¿üRÞ¾}ë´Þì#Jcˆårë×ÑÑÑuOÇwû ˆm?ìI´¤4†8Ë_Ä÷ã u?s6†ˆˆM[)!JëY·…½øîŒ!¦˜ÿû¿ÿ+6l 6Hmm­ùÿ.WÇ‘Ár€#âbccñøñc¼~ý'OžÄþýûmÖ Âœ9sÆ‘ÿ»jpæÌh:–•ÆÞ(C_Ž#JcÈöíÛÛÊz ”ÛÔ²-ìÅw…åømòÙgŸ¹´í`6LL×í‰hPºpáBCC¡V«} ƒIII¨®®¶9ó8ìÙ³Ÿþ¹¯ÓpXoä-} yøð!jjjðãÿØ×©ôïDDD.©©©AZZ äÜDä[Cú~ˆˆˆ\¢V«qåÊ_§ADÇþƒWˆ‘/^ )) ¸zõêÿ‘Ùâ¢AàåË—xõêž>}ŠææfTUUáèÑ£˜0a"""ðÿø¾N‘ˆˆˆú ·&hkkë­\ˆ¤Ñ£GÃßßß+±Þ¼ycþ0ÿâÅ ók{·a3Ýö,88!!!?~<0räHDGGcÙ²eX°`A·Ût e–·!%×½ÿžcàöS²û+·î´wï^L:µ7ó!Pºººðý÷ߣ°°Ðæo­­­øî»ïÐÚÚÚíß»wïÌëÞ½{£ÑˆÑ£G#88Øæßĉ]ÎiÕªUøÉO~‚+V`ذaxñâ¾þúëž–h?~<ÒÒÒ|Æ€sùòe|ÿý÷¾Nƒ¨_HNNîö ‡È­ oFÔÝû÷ï‘››‹ØØØnËýýý1~üxóYù„††âÃ?ôQ¦DDDD?àoˆzhÞ¼yŠWˆˆˆˆú#Þˆˆˆˆˆhé“ @NNŽâò²²2âEEEõ$—xš›=3gδYvéÒ%$''C«Õ"!!ååå^Û_oå­V ­V‹µkך۶7ÛÄÛeñEˆˆˆˆú‹>ù Peee·÷F£ÇGYY6lØÐ)¸Ì¹™b8SXXˆsçÎ!,, À·rì©ÞÎ?((/^ìA†îóöqâ‹2õ^½°iÓ&œ={ðöí[¨ÕjˆˆùÌjdd$6oÞŒ””9rOŸ>…V«Eqqq·³¯¦³ÍÇGJJ Ôjµ9®É®]» V«‘ššŠ;v˜—«T*"..åååÈÍÍ…Z­6Ÿ]·Ó^nùùùHOO‡V«ÅâÅ‹]ŽQWWFƒŒŒ Àh4ÚÔרQ£pþüyèt:@HHÈ€Êè~Ö¼©© YYYHMMEzz:êêêì¶Õ–-[púôi@[[âãã±sçN›õŽ=j.KAAb|WÚÝWÊ@DDD4hˆŠ‹‹þ½¦¦FV®\)""•••RTT$""*•JDDBCCåÞ½{æõMË­_GGG‹ˆH[[›ˆˆ<þ\âãã»­;}útijj‘®®.óßBCC¥±±Qôz½Hss³èõz‰‰‰qÓ^n™™™rùòeéììt9Fff¦\»vMDDªªª$$$Ħ¾=z$ëÖ­“èèhIHH›7oöûüÃÂÂD£ÑˆF£‘C‡™÷£R©$;;[îÞ½+""²dÉŶª¯¯—ììl©¨¨;wÚmSÓ>ìÅ7åî¨Þ,yR{:::¤¤¤Äá:DDDDý‰W¿‹Çãõë×8yò$öïßßíïAAA˜3gŽ+“À™3gpðàAøùù¡¥¥¥Û:ÇŽCQQ:::°fÍdffÆŽ‹iÓ¦¦NŠ)S¦:;;Æ´—[}}=>ýôS€ŸŸŸË1HLLD`` M숈>|pçÎäååõûü­¿>³wï^óëÚÚZlܸÑüÞ`0Pn«¨¨( ´´´àĉ8uêÛÔY|Ày»[ò¤ DDDDƒ…×°zõj”––¢½½ÝæG•¦ &¦§˜Àˆ# Óéº=±´¨¨·nÝBgg§Í‡ÛyóæA£Ñ@§Ó!..<°‰iùÚÄ^L{¹Í˜1W¯^ERR’ù»ñ®ÄP©T¸qãæÏŸêêjÅ'¹Þ¿111`~ Ä@ÊßZLL vïÞY³føË7íµUnn.¶nÝŠàà`„‡‡c̘1ÛÔ^|WêÍUŽöADDD4x}““ƒˆˆ”––:]7++ K—.ŲeËPPP€E‹!55ãÆ¬X±iiiÐh4 ê¶íªU«ÐÖÖƒÁàÖDÅTÊmöìÙØ¶mºººàïïsç飤¤yyy9r$bcc à‡ú1ý(zß¾}¨­­E`` ŒF#JJJ°víÚ~¿#@aa!ôz=ŒF#´Z-¶oßn·­–/_Žõë×£¢¢€ý65•eîܹغu«M|WXÖ»'e """,ø$`òƒÁ€¤¤$TWWÛ\Á(Þ¿C‡ñA`DDD4`ðA`ä555HKKCaaá€ýðODDD4õÉsˆ¬©Õj\¹rÅ×i 9¼@DDDD4„ð Qݾ}{öì1¿ÀøñãŒñãÇw{íÊ¢‰ˆˆˆz'D=ôñÇwûð»wïðêÕ+´¶¶¢µµuuuæ×ïÞ½³çýû÷3f ‚ƒƒmþMœ8Ñå|¾øâ ¼|ù¿þõ¯1~üx?Ü>ÖÑ]£ˆ†‚wïÞaþüù6Ï鯚ššPRR‚ððp_§BDýÁ`À¶mÛ<ÚÖ­ @BBŽ9âÑŽˆ#Áüùó»- ÀĉÝúÐnŠeš8¼zõ ¯^½ÂãÇñêÕ+¼}ûÖá¶£G6_m¸~ý:þã?þÿò/ÿ‚9sæ`ûöíøðÃy/òž={† .ø: —éõz,^¼K–,ñu*DÔY~ûÀ]nM’““‘œœìñΈȾaÆ!$$!!!noÛÖÖfž8˜®2/^ìít‰ˆˆh€â’‰ÀÀ@Lž<sçÎÅ„ ““ƒßýîw¸ÿ>îܹãѤ‚ˆˆˆ'Nˆ™ŠŠ üó?ÿ3~ò“Ÿ 00°G±rrr——••y/**ª'é8åi^öÌœ9ÓfÙ¥K—œœ ­V‹„„”——{m½™xx8´Z-´Z-Ö®]knÛÞjo—è^­V‹o¾ùƦ\ô¥¾Û_û-À¾km0õÝððp¤¤¤à“O>ÁW_}åÕØJLug¯½½Q>oÄPϬ—÷ê˜&D4è{%NWW—ˆˆ¨T*¶÷t;Wtuuõ8¾©|&ÑÑÑ6ëÄÆÆÊ³gÏÌï_¼xÑ£}Zî»7ó·»·Ú¤7â*Åtg?---ròäIo¦Ô«jkkåü£Wbõäøêí~ÛÓ}X÷"ì»=áí¸¦x:Nbbb¼ÛQÛÛko¥ò)ÅqÄ:²ÛíÚ“ÿÛy€ˆ°iÓ&œ={ðöí[¨Õjˆˆù Sdd$6oÞŒ””9rOŸ>…V«Eqqq·³P3gÎÄñãÇ‘’’µZmŽii×®]P«ÕHMMÅŽ;ÌËU* ‡òòräææB­V£¼¼ÜaLSn~~~hnn6çÕÐЀôôthµZ,^¼Ø¥“'OFrr2222PPP£Ñh“ÿ¨Q£pþüyèt:0½ÊQþìîßÕü]‰áJþ&–íÖÔÔ„¬¬,¤¦¦"==uuuŠí´eËœ>}À¿;‰‡ˆØ¬{ôèÑnLjR|Wꌳ×oØô]ëãËrÀyßõ¤ßÎYë1%??ßíã>%%uuuÐh4n÷]OówT·½5ö˜x«ïîܹÓf=˾[PP Øo]iw%z½þþþvóVó¾ýö[¤¦¦B«Õ"## .·½R{[M–qºººlú„RNÖ1¬·±nÛÈÈHdff*Ö£Oy<  ´¶¶¢««Ëá6Žú-`ÿøÜ뻞ô[ÀµãÞr[OŽ{Àó¾ëiþÖûGIOúî˜1c¶©½~ëJ½)Y¸p!ôz=êêêcÿíßþ­MÛGFF¢ªª .DuuµyÒáJÛ»2V[‡Ö}bÞ¼y69YÇ°ÞÆ:¶£zô%NˆÀw ‰ˆˆ@ii©Óu³²²°téR,[¶ X´hRSS1nÜ8,_¾iiiÐh4ŠO^µjÚÚÚ`0°a×r[±b…ØJy•••!??]]]ð÷÷w)FII òòò0räHÄÆÆ"88Øü·œœTVVbß¾}¨­­E`` ŒF#JJJ¼VGùŸ;wÎi Gù;ràÀB¯×Ãh4B«Õ¢ººZ±–/_Žõë×£¢¢Â¼L©M-Ë¢ûöí.åfªwxóæM·3â»wïv)†¥éÓ§#==ÝííúÂoû[üò—¿Ä† ÿùŸÿÁá—« IDAT“'Onãi¿]·n[}ד~ ¸ßwgÏžmÛ¶¹uÜö}ËãG©ï:»ËJ{éIߵצ¦²Ì;[·nõ¨ßÝëÞäç?ÿ9öï߯˜·Ò˜WZZŠ_üâ0øàƒÌgô]©;{cµe[Y³îJ9YÇ°ÞÆ•6Ú¾}»âxfý`ÑÞ4L,¯WÑ ´gÏ> ˜¼Â`0 )) ÕÕÕ.]ïOLOþéOêëT\bšðIÀä ¹ï’²žüßλ‘Kjjj––†ÂÂB~€ @ØwÉ¿DDD.Q«Õ¸råŠ¯Ó "7±ï’5^ """"B8 """"B8 """"Bø¢!àûï¿Ç_|áë4ˆºyòä 1vìX#88cÆŒéµýµ··ã“O>éµøÞ6zôhüáÀÿ÷û:"ê‡ÚÚÚ<Þ–·%""ŸjmmÅÇñðáC¢‡ˆz'DDD>dyá»ï¾Ã»wïÌ3 Á„ 0qâDÌœ9>Ì–ˆNˆˆˆú±ÖÖV|÷ÝwhiiÁÇÑÚÚ æ¯ LŸ>‘‘‘ˆŠŠÂ‡~èËt‰hà€ˆˆh{÷î¾ûî;óU„·oßš—ÀðáÃ1mÚ4DFFš¯$ÑÐÆ Ñ ÖÑÑ'Ož˜¯"XÍèƒ>ÀG}„‰'òV§DC'DDDCœ;w2š:u*¨L4Àq@DDDYNž?Ž÷ïß›¯"˜~¨lúŠÑ´iÓœþPY¯×ãÒ¥KÈÊÊê‹ô‰È 'DDDÔ#ö~¨lÉtaÆŒ¨­­EFFæÌ™ƒÂÂBüÝßý²&º8 ""ê#"‚ÿú¯ÿ²yÀ`×ÞÞŽ?ýéOxöì¾ÿþ{Ü¿_ý5Àßß“&MB^^æÍ›çãL‰§I“&aÖ¬Yæ÷üQyûö-.\¸€•+Wú:•>ŒI“&™ßïÙ³“&MBXXÂÃáV«ññÇ#88؇Y ^ÿþïÿŽßüæ7æ÷œõ¡)S¦àã?öu>U^^ŽQ£FaäÈ‘¾N…hH0]q3ဈˆˆúVFä[¼Ñ/Ñ Ñ““c³¬¬¬ÌãxQQQ=IÇ©žä¦dæÌ™6Ë.]º„äädhµZ$$$ ¼¼ÜkûëÍüÃÃáÕj¡Õj±víZsÛöV›x³,555æÜGe~}ãÆ ¯í£/XÖ‰½ãÈõæ–Ç‹V«Å7ß|c³|íÚµnÅä]€ˆˆˆúH{{;Ž?Ž_þò—=Že4ñWõWhhhðhû¨¨(·u¦§¹™bX>‘xæÌ™¨««ë¶ŽZ­Æ¹sçxùò%BBB<Þ§å¾{3{uß[mÒ—q­ËÝWÜݯeîöŽ#o”ÏÕºw×ÇËž={ðù矛ßó Q?±iÓ&œ={Àw R«Õæ[†šÎGFFbóæÍðóóCss3´Z-Š‹‹»­üðóøñãHIIZ­6ǵ´k×.¨Õj¤¦¦bÇŽ•J…ÂÂBÄÅÅ¡¼¼¹¹¹P«Õæ³¢Žb*å–ŸŸôôthµZ,^¼Øå“'OFrr2222PPP£Ñh“ÿ¨Q£pþüyèt:0øwTwó/..FCCC·2x+ËvkjjBVVRSS‘žžŽºº:ÅvÚ²e NŸ> hkkC||>ÞfÝéÓ§KSS“ˆˆtuu™ã766Š^¯—€€inn½^/111æ2Ø‹©”[ff¦\¾|YDD:;;]Ž‘™™)×®]‘ªª* ±©¯Gɺuë$::ZäæÍ›NËànþJeèiþaaa¢ÑhD£ÑÈ¡C‡ÌûR©T’-wïÞ‘ÆÆFY²d‰b;Õ××Kvv¶ˆˆTTTÈÎ;׳.‹R|gufe\S¹íÕeüÙ³g‹ˆØÍ7$$D®^½*""ׯ_Fã´¾])—i¿Ö¹Û;Ž”Êg½<::ZD”sëu•¶³Œk¯ –Ç‹F£½^o³üСCâHqqq·÷¼ Q?‹Çãõë×8yò$öïßo³NPPæÌ™ã4–ˆàÌ™38xð üüüÐÒÒb³Î±cÇPTT„ŽŽ¬Y³™™™;v,¦M›˜:u*¦L™èìì‡1•r«¯¯Ç§Ÿ~ ðóós9FCC‰‰‰ ´É?""Â|V÷Î;ÈËËÃíÛ·–ÁÝü•ÊÐÓüƒ‚‚pñâEóû½{÷š_×ÖÖbãÆæ÷ƒA±¢¢¢`0ÐÒÒ‚'NàÔ©SHLL´YÏšR|NÛÝS¹¿úê+ź±ŒßÕÕ@ùø€€€,\¸°`ÁówôÕ·+å2íך½ãHi?Öäÿ®Ð)玘¶³Œk¯ ÖÇ‹eNJË]Á Q?²zõj”––¢½½]ñG¡–.† Öío#FŒ€N§ƒN§Ckk+ŠŠŠpëÖ-tvv*~x™7o4 t:âââðàÁƒn1­ãpS)·3fàêÕ«HJJ2ÏÙ•*• 7nÜÀüùóQ]]ööv›\îß¿˜˜À„ ó¶.ƒ»ù+•Á[ù+‰‰‰ÁîÝ»ÍOmíèèÀû÷ïmÚ rss±uëV#<<cÆŒQ\ϲ,JñÕ™+Lå¶W7J1•Ž?x÷î®_¿Ž„„ܺu ð‡?üÁa}»R.K–Ë]9Ž, ë~(çÖ1”¶³Œk¯ ½""¢~$''(--uºnVV–.]ŠeË–aݺu(((À¢E‹ššŠqãÆaùòåHKKƒF£APPÍö«V­B[[ 6lØàR~+V¬pÓ:·Ù³gcÛ¶mèêê‚¿¿?Î;çRŒ’’äååaäÈ‘ˆ5?%8''•••€}ûö¡¶¶0())ñzþË–-CYYòóóÍeèIþÎ8p………Ðëõ0Ðjµ¨®®Vl§åË—cýúõ¨¨¨`¿=-Ë¢ûöí.åfY÷ö¸Z¿ŽòýðÃñûßÿEEE0 ø›¿ù§1Ý-—eܼySñ8²\Ç’u?`sŒœ;wÎ&†Òv®”áÍ›7ÐjµæõvïÞùóç;¬[gx ""¢>âÍ» $%%¡ººÚ¥¯ ½y‡ª¡Šw""""àjjj––†ÂÂÂAõáŸú¿DDDD4À¨Õj\¹rÅ×iô žýï}¼@DDDD4„p@DDDD4„ð+@DDD}¨½½Ý| @"¢¾`ý$jNˆˆˆúH@@‚ƒƒñ¯ÿú¯¾N…ˆ†ÓCÊLxP""""¢!„¿ """"B>pÛ×IQßøÿ#ZÞ·Ò IEND®B`‚vsmartcard-3.3/docs/_images/inheritance-66308f7843803aa5084df2fbf62c13b8b1f3a5d4.png0000644000175000017500000001161213546304763025121 0ustar philphil‰PNG  IHDR¼U$  wbKGDÿÿÿ ½§“?IDATxœíÝiLSYðS@º`™"" t¢ã€àŠ5Qp‰(.åÃãDø;¨³h4  8—Qa4F Ž#hbâ¸Û„‚l²ˆZ œ÷ÃÉ{ßNKÛ‹BYÞÿïÓ]NŸ>çáöøØ[Š€RJ̱êí @Ó¼ i^Ð4/6]}Àš5kZ[[{"øh 55µ·³€®ËMƒZ­¾xñbO¤-,,¬·S€·'€4 À šàMðb¹¦!77W$i4šî ûäÉ@ V«»7¬…±Y´µµñbš†zôË5 'NT©T¶¶¶zÇûÑÂjáTCBB¢¢¢ôΞ={Ó¦M(fvvöœ9s¤R©T*4iÒÕ«W?=¦žÿŸzêÅÉÎÎ •Éd‰d̘1Û¶m«««3{  ×õòí‰>ônüucªsæL– 7¾¼¼œrûömJi]]]NNwvÉ’%555jµ:""ÂÃÃcùòåÜ.ËÍtpc©RJ###ýýý EGGG^^^ii)ÏP”Ò… .\¸ðÝ»wJ¥r„ †ÿÈQJ÷íÛçëë˶5““Ó©S§,PÌÖÖV—   ôôôÊÊJ.ÔóãêÉmTTTB^¼xaøÂ1qŠ4 `Ýß4°1›7o¦”vttxxxœ;wŽ, ¯^½bƒù¯Ëºnݺåèè¨;þÍ›7ÖÖÖ Ü0v¶¨¨ˆífeeBJJJ¸]{{{Ãüõ‚Kõýû÷àáÇ&Ja,TCC!äÙ³gl÷ܹsN³¢¢ÂÆÆæÁƒ”Ò . :´¥¥ÅŤ”GGGËår@0}úôüü|Ôó£ëÉm<}ú”R__o85§ø@ÓÐ#ŸiX·nÝo¿ý¦ÕjïÜ¹ÓØØ¸téRÃ1žžž] {ýúõ3f8;;K$’¥K—Ö××···sg]\\ÒÒÒ®\¹âææ6sæÌû÷ïs§ÜÜÜØ†P(ÔÛmiiaŸ±7ÜXªeee”ÒÑ£GóÏ“ Åþ[éááÁv¹ =#FŒNII!„¤¤¤DDDØÙÙëöbBärù‰'Š‹‹KKK#""¸S¨§!³õdd2—-ÿS}D4 óæÍ³µµ½víÚéÓ§W®\Ùéºlee¥·ÁˆÅbBˆJ¥b»ì¦!¤¾¾>44tÆ ¯_¿njjJKK#„PJurûöíÚÚÚÙ³g/_¾œ¦ƒKuäÈ‘àŸþùˆP#FŒ „”––²Ý²²2c¹mܸ155577733ÓØGöz¢˜ww÷o¾ùæåË—Æ24„z#õtuuõññùý÷ß»t  è‘¦ÁÚÚ:***>>>==}ýúõ¦;;;BŠŠŠØ®\.—Éd‰‰‰ííí …bÿþýìxsss[[Û°aÃììì ÅÞ½{õâ”””ܼy³¥¥eðàÁb±ØÆ¦ ‹ËlðNS‰D‘‘‘[¶laïÏççç+•Jž¡¤Ri``àŽ;ššš***>l,·ùóçËd²eË–M:ÕÇÇÇôDº«˜¯_¿>pà›W]]]rr²¿¿¿é§Ö…zšˆ™ðã?VWWBÊËË¿ýöÛŒŒ Ó§ú„®ÞÏàyë´°°2vìXîH§Ÿ$gbbbœœœ)¥^^^B¡ÐÏÏïäɓ俷=êêê* §L™’””ÄŽsÑ $‰D"ñóó»ÿ>5wZw×tpc©ªTª-[¶¸»»‹D¢qãÆ±{ê}ÚbŬ©©Yµj•›››½½ýðáÃÔJ%êùÑõÔ ûäɓŋ;::ŠÅâ/¾ø‚}ƒÙS¦á3 `jäMicÂÂÂRSS?¦=€ƒ&Xþöð‚¦xAÓ¼ i^Ð4/h€4 À šà¥ ßµÌ 2dÅŠ=‘ |´Nÿ @÷êò7BÀÿ'Üž^Ð4/h€4 À šàMð‚¦xAÓ¼ i^Ð4/h€4 À šàMð‚¦xAÓ¼ i^Ð4/h€4 À šàMðb£·¥V«{%èQ/^ìíþ')))33³·³3ôÖ ý¦A£Ñô©•ºEXXXo§ð/YYYXjú8Ãu·'€4 À šàMð‚¦x鶦!77W$i4šî È|ø 7}…B!²³³)¥ùùù„·oß²S™™™vvv†O§›ƒ\.¿zõ*5`™u£ËMC}}½­­mnn.Ûݵkל9s¨ÁÅZWW×ÜÜÜéÕÖéÅ—žžž——×ÞÞ^^^>sæL– 7¾¼¼œrûömJi]]]NNwvÉ’%555jµ:""ÂÃÃcùòåÜ.ËÍtpc©RJ###ýýý EGGG^^^ii)ÏP”Ò… .\¸ðÝ»wJ¥r„ †W¥tß¾}¾¾¾l[£Ñ899:uÊÅlmmuqq JOO¯¬¬äòé×õ0“R*•„W¯^éÎ.55U&“™˜¦Y½Ø4ìÙ³G,{yyíÙ³§¢¢‚g>Xj°ÔôÍzš¾T(¥‹- jll,++óööÞ»w¯Þ#66vòäÉl»­­mÊ”){÷îU«Õ áááëÖ­3|:.vóbÿþýr¹ÜÅÅeíÚµõõõ”R‹­]nؘ͛7SJ;::<<<Î;G .>.uþŸ®[·n9::êŽóæµµuBBBcc#7Œ-**b»YYY„’’n×ÞÞÞ0½àÆR}ÿþ½@ xøð¡‰R ÕÐÐ@yöìÛ=wî\§Ó¬¨¨°±±yðà¥ôÂ… C‡mii±@1)¥ÅÅÅÑÑÑr¹\ LŸ>=??Ôs`L*77—ÒÐРäÞ½{ÀÄ4ÍêݦB±²²1b„¯¯o\\\HHˆÙb©1 KåëiúRa·¸gÏž•Ëåº×jµÃ‡ONNæŽ(•ʱcÇZ[[BæÎ«ÛýPƒj³õaÍš5MMM•••Üq ¬ú{‚uëÖEFF:tèÞ½{K—.5ãééÙհׯ_ÿþûï YÉT*U{{;wÖÅÅ%---!!!66vâĉ `§ÜÜÜØ†P(ÔÛmiiikk³±±1ÜXªeee”ÒÑ£GóÏ“ UQQAñðð`»Ü†ž#F§¤¤øùù¥¤¤DDDØÙÙëöbBärù‰'!J¥rÓ¦MìÒ$ý¹žcR2™ŒòæÍ›¡C‡r+++?ûì3³Ó4mݺuÍÍÍ|Fv/î3\oÞ¼©®®>pà›¦iXj°ÔôÍz2^*ìíîžžžìçÚµk*•Š} òáÇyóæ­X±"66V­Výõ׫W¯NKK3ö¤"‘ˆ'‹ÅbñöíÛW¯^MzrÝÐg¶­0ÔÖÖæêêš––Íêu¬\¯”­»ËîßpwVþøãBˆV«­««³±±ùõ×_Yÿ›‘‘Á޾ïÔÚÚºk×®áÇSsý/·Ë3¸^ª¬]}ôè‘îÜy†ª¯¯':ÍæùóçIg9¥ôÆB¡0''G ¼xñÂÂÅd233‡ 20ê90&5f̘ݻwëÆ\ºtéÊ•+MLÓ¬^§ÁÊÊÊÅÅÅËË+..®ªª K –š~ZOÓ—ŠÙw,X°aÃnWïÓ†¯h½âhµZ±X\^^ÎvoÞ¼)•JÙ¶eÖùí kk먨¨øøøôôôõë×›ìììL)**b»r¹\&“%&&¶··+Šýû÷³ãÍÍÍmmmÆ ³³³S({÷îÕ‹SRRróæÍ–––Áƒ‹Åb›.¼Gb6x§©ŠD¢ÈÈÈ-[¶°7Íòóó•J%ÏPR©400pÇŽMMM‡6–Ûüùóe2Ù²e˦Nêããcz"ÝUÌׯ_8p€Í«®®.99ÙßßßôSëê›õH“úé§Ÿ:ôóÏ?«TªúúúÝ»wß¹sgß¾}Ÿ>Í^!‘H>ÿüóØØØ‡þý÷ßÛ·oge4 K –š>[ObäRqppfÊËËøá‡5kÖp)++»uëÖÆ¹#IIIZ­öýû÷¿üò˸q㸳jµšýN‡F£a¿äicc³víÚ;w¶´´ÔÖÖ}ÚbŬ©©Yµj•›››½½ýðáÃÔJe¯ç@šûÉN›6M(J$’ààà—/_²ãƦiV/¾ÓÐ),5Xjúi=M_*”ÒÚÚÚ•+WÊd2WWט˜FÃßµk×ĉõ.ò¬¬¬©S§:888::éþªQ§ÿ^·¶¶~õÕWR©ÔÉÉiýúõïÞ½ãÆ[`Ý襖ššÊ¿ç€~¡¯½´ûZ>`ÈðuŠ¿=¼ i^Ð4/h€4 À šàMð¢ÿegJ¥òÒ¥K½’ ôöGðú,5}œáº¡ÿåN×®]cßU É!C-ZÔÛYüÏÓ§O¹ïý€¾ÉpÝÐo:…Ï4/h€4 ÀËe­-oõrIEND®B`‚vsmartcard-3.3/docs/_images/remote-reader-qrcode.png0000644000175000017500000001143213546304763021263 0ustar philphil‰PNG  IHDR   E3áIDATxœíÝ_ˆ$I^ð_dfuuWwÏööÌîÎÎè«ì1+÷r²r{pëÉ ² °ë€(ˆ(úrè*¢¾‰®ø ‚"¢œ‹(Ç=ìÃáÀâò¢ÎÝxÌÃÂÌq³zÝ×Û\Wwן¬Ê ²&;;â—QY5×ßÌÐU•™U•¿ŠüEDF )%€&Zô,)ıÀClð<ıÀClð¼Äü²¢ý0wÏ›wCYWYتãß¼®UÉ?ºpoм!óº?sQá˜wõ±ÀClð¼9¹¸Âã€vù–¹(«Ñ*¿4¿ê’Œšyl·pY×êcw±¨£õ±ÀClð<»\\a•Ù¸dTSd…U>í’}º”lfU²KË„Ë^µÖôbÞ +¨7xˆ b€‡Øà9åâ­ñØëqtt¸ì.ä1Vü‰˜1õ±ÀClð¼%ÍÅ=–¶ÚKzn¯¬6äñâòÖ®D_N¨7xˆ b€‡Øà9åâá,—”Ñ<*Ûj]«ôÚj¬¸Kš.ùöøö]vìµ´õ±ÀClð<»\¼µ ®—³»ÚªdI°Ëv[+ÙÊ¢f¤·‚z€‡Øà!6xˆ Þœ\|I†·6ã˜Yki½YkM.S×yÜÞà!6xˆ b€'ûááa¯×ÓKfŸ±]@Y¦áÇ¢TGVæþþþ•+Wš,éÒíñ:u™ºÕÂ8§ZFsãÙð£–ðçTNÎÒÌ:ý¾üÞŸÒñ)-Â'Ç´¬>1­ÿ$=÷%‘œjx­Û®r’f·oPذ£pÕ#µšŽ×£¹|pƒ†ß"""Y‡Ù¤>GD4º—ÝŸüZwªÛÒ[Ãô`¨ß˜çTêtz»Öì…áYÆÜCTžú#c°;Ë2¥yJoÈÒÛ¯ôÿ¡ §ëÅ]>èp_’K£M]ö¹»»{ñâÅêbz{€ü’ÓƒâLõpê)¡þ!ò㣣$I”ªCoûªÛ—/Ôã0놫 qNÕT“v˜FOÊ“‚¤$ÊS©rA!ŸqI)©<6¤”ExÄq\-ynN¥Î±±B&ÏeñÕ“ÇÄÖ#DDÑô‘˜îTOÂŽ××׋ð€pAÌËzeºö…ÁS_*&íÌ¡|¸úƒ·»_œZ• ·MòläâV‹[P†lœµ’5™tÍ+¤ ©mm042ˆäûÌÚ«7×­BŠYˬR(gY%)DÙV¥÷láÑξŸ+ˆ¶5AqxSÍ@C½“QVê']¼åµ•Sý@¯Ö TT0²®—èqD ‡Ã¹á¼ÜŠÓu™\¸‘ÆVë²{U£.¸QLÕ—ªÿ— œ¬Ò»>¾øñàßH$z!úœ„‰9—‚ ‡Ãµµµb‘r»Õ.þØÞÞî÷û›››†Ï¡É‡£—m·Ö` @ÿ†å nÞ÷|*Év÷Êoôû¿$óÔ\þ©‡Ú÷[·d5<ô®Û=`!6,è¹AÝ`S?ÕÃoRÿ=Jž¦Õ“kŸŠ¢ .ê§@Õªætiüž(£¤Š‡£ÑhuuUŸ„ T¶á ¾‘ïüÙìÇ?êÑÆgÅÓ¯on|þðh˜ç¹¡scÖA!˜zƒêξŒáVMùœ¤3(Q~Lý¯SÿëÔ}qýÙß=Ž~ŠÒ«nšŠ¶-¦yWY¥,m<w»]Œ¹rá36¬ŽÉ™Çƒº’•1êVäÆ«Ç—þRd;Iz7½eß'"1¾}÷×z›??ØúC½y»×(ÝTÞK“ðð˜^{Ìg<6̸ìê¦Øï@i•RžŸýÝýÑî3—ŽŽR"AY2ú÷nÿoâñm!eÒÿÚúøþàÙ¿–ñ%2)÷¡ åúœ;MÓn·‹,ülpJÚ”àÖQ]}¾´²²²±±!„ ‘L×>{üì—GÿDF$(Jïöv~UäýúÀ`:@”MskÍŒÇc©]M 6šÒ¦ô6\},“”R~üOù·>•|çõÞÑߊéGD’D”®ÿÜñó_ÉãË$eœ~¸¶÷;$3¾¼h§ª\[n%ÅŽïÇè5?Ća¼ö•I£… ™Òôcyü_ÿbóvmÿ…<$¢,ùÄàò?Èø"‘L†ïwßQ*:©¤r­^WÔÕ ÅÃ4M¶æÄ†>À³J?‘0`ÏIê8½'›íš.Þu¿ß/'§šôN™²|mæÉ3$"IDr²røÏÿ÷ ñô;BˆORDÙÇÉø?ˆHv>)“+R’”E9åÈöYùÕ“¥¹¹¸òpó†Öªi·~Z¯,,„ £÷ó7äýÏõè^Ç2Þoÿ‘D$Wú³“¨lýsRHI2ý·‚„ÈW^$!gF„$Ñ¡•k'e*›˜—‹³+‚ÙœØPÒ «\Í%±³Ê™Z+ªüL”?ˆKN- ‰Æèá/wÅn’$ÓµŸ–É5’¿9k³ê^'ŠHŠ(ýölÎ'f#E¤ Š¦Û¿%ãg¨&0Ê/ŸÔã„ sšë’‡ûö]¾P«w„~ñ¦Îœ‹¯‘$ʲ½L.ÿ>M×>Ó™<¤<ÒóÕOËä9=’ÇÑäQ±F¶ùEÙù""ÉîKY÷:i±§l×üj“·UˆPNN´â­|åÇgOæÅ0'Ñût>þ"rBDDI¾ú”íÓãÊ!ï¾”w_ÒKÓoY ®†äÆ•@ï¡ì±¨pR°%×ýùØ’RƒêmÄ„Ýnw:–i±á×½áKÍW¼ÿþË/¿\·«†]>v3߾ˆÈÅ›’6ªËQ¯×+'x.^ÇI’Ô ’­~gÊ߆¯SyµùŠÀršGÝlQ…ËnÔ­»»»»½½]<,Ïaª'3s7Ñëõ”Ú£8¹"­QUj÷¼ÔK+÷dn]Q·¤ùý6yÕã±aæòí+ëZí3ê e0°gÿs¿Â^¯×étªk¥iª×ÕÂëòì²Õ…]±nÉ347gˆ¦ô«î8cîâáÚÚZ¥4M;Ž2o§²–þR]Øè­“ÊêÐb£‘ýýý¹Õq“È)Â#I’ê«EíEz™JT°-QJT_ÚÛÛ›ónˆ ݼyÓ×ïnJEQž\ ãX)ý![-Tó"å%)åÍ›7½¼‘zv7dpÉkSs‰;»îp8ÜÙÙÙÜÜÜÚÚ2¬[–/¹«du£Ñh:–Ë !:N–eÊPÙ&¢?O•à©f&÷îÝ{íµ×vwwç¾]¸¦UE¸/ÔªdÔó%IÒív?ú裇¦)3çZUÙ€;·ØÕÕÕ¢a·ü™ŸL&qWçÎiºj.^ü1™LnݺõÆoœ-0Î!Ô¦½*dY6 ööö†Ãa‘Ñ;ï¼S]ìÆÕ‡M^•RV[u q¿ùæ›lQÅΛ7ÄJÓôîÝ»|ðÁÜØ68oõbôW¥,ËŽŽŽúý~ÑGQœö\¿~½ºÌ;wª­^Ux,Ê£óOÕHÇ+++i𖱡¸|ù²¡ó«áŠ‚3sª7«—ÝpÙUÉÊéP’xû¡ÑO´šoȰîÜiÃõ„ûí÷¸°õÆÙ…›QÓ¥dÌóé Ú©xˆ b€0ßh­ÉÏczm.¹y×ÛÜuÍÌŸU¸æ“p-"‹Êò]¾Ô<ıÀClð|Î3⢵Ýw¼KQV 63sù 3oÈê b€‡Øà!6xǨ›×m-eôhQmfá˜7dÖÚ4ŠáÞ>ê b€‡Øà!6xsƨ·v!ï’t²ZeráÆÆ‡[7\sB¸&ó†Â5ê Þà!6xˆ b€çtO3—¼'ÜpwÅ’Œ7(Ýj]—í*uýBkGê b€‡Øà!6xçnkí–VÂíFk÷ YÔ%ïæ¬wQ“˜¹ ƒ@½ÀClð<ÄÏiî¶E wÙºËvÃíFkƒÿ[+ÙjCVë*‹ø‡Øà!6xˆ žÓÜmËyoòÖ.\6ï†â‡`†µp}ùKÒ@¢@½ÀClð<ÄÏiŒz¸{W›…+nµ]I¸† —¢¬¾A“˜K¶Z×\úÅαÀClð<»1êfáº3Í ×åì±s·µ;­™-ɽØ[»€yÔüClð<ÄÏnŒzk5G·Ç.XEkð‹ºæ[®oÛÌ¥Ùõ±ÀClð<§û‹{´¨!Í‹º¸\á2a»G÷pëšyü~Qoð<ıÀ³»^<Üðoó†\.kVÖ w‘wkwwÙn¸¼Öã•­ÝÂÎ õ±ÀClð¼€s·)<&gáÒk« ¹ô"‡ î²°ÇÝðxÓ6èð±ÀClð<§\<s&çÒÜÚäçwï7Ü´wK²Ï¿_Ô<ıÀClð–47óØíñÊìp©¹©j¸qË9ɼõ±ÀClð<§\|Q“ˆ)\ú\Ã¥ÈK’‡ë®7ßœËýã=B½ÀClð<ÄÏçýÅ]´6y™y»Oâ­Ê[”¾$l¸é¨7xˆ b€‡Øà-éýÅõ±ÀClð<ıÀClð<ÄïÿZõ(¨ŸâpIEND®B`‚vsmartcard-3.3/docs/_images/inheritance-87c02cb0f500902e28e2583f9a1dc09e571332ee.png0000644000175000017500000000605513546304763025042 0ustar philphil‰PNG  IHDRÛ$X+öMbKGDÿÿÿ ½§“ âIDATxœíÝLÔõð× ¹;~XX)ÈV–&–aGåÙ&9&ÆÀÖÅÚX³ÕÚ\Ë­V«­Z¦E¥[9ç¨K[4›Íbk³iž:Û%ò#ÐŽ8¹Ãžß?Ø}¾Üñ¹ŸpÜÏÇÆv¼ïóù¼Þï×ësïÏîs !""""¢©V?/Ö= """"𭏨&""""Š.¶‰ˆˆˆˆ¢„‹m""""¢(IPk\ºt©¬ZµjºûBD4#œ9sF¬Vk¬»±^xAœNg¬»AD4«h41™LÚUÛùùùª‘Hyyy¬»0).—KêêêbÝ "¢YÅßµ·‘E ÛDDDDDQÂÅ6Q”p±MDDDD%Q_l›ÍfÑëõ244íPŠsçΉF£—Ë5m1ã‘'ÃÃÃíÏÚÅÖdë7›17ñƒóDìÄúuëøáß_žCáaî&'ê‹íüü|q8’””¤úü\(Z<ޱ¤¤DvìØ¡ú܆ ¤¦¦&.j÷çŸÊÆeÁ‚²`ÁY½zµ?~+UUUb³Ù¤¥¥EV®\)………ÒÒÒ""ñ‘³¹†sü̉ÏñãÍíÛ·Åáp(_""b·Û•6R7ݹ‹›kTlÛ¶M­YÕçŸއ~Ø«­µµóæÍC[[Ξ= ÓéT:t÷ÝwD‰‰‰èt:èt:|ñÅ^ûxxÚÜn7à믿ÆC=„””ÜsÏ=¨¨¨ÀÍ›7½¶õì_[[‹%K–@¯×Ã`0àÓO?õÚ®¾¾yyyÐjµxä‘GpéÒ%|ÿý÷X¾|9ôz=ŒF#®\¹¢ô%”ØÁƇ¯¿þ:rss¡×ë±bÅ \¸p!쉉‰p»ÝèêêBqq1RSS±|ùrìÝ»×+g㌌ ;;{÷îõjã7°víÚ yŒEí, DÝÝݪçÞ\®sã›xo¿ýö„<”––¢¢¢"¤œ…#œ92qŽŸ¯_Óß_|©Õ?ÒsàÈ‘#X¶l™RG‹Å¢/P}ûàp8PSSƒÌÌLÜ}÷Ýxå•W0880þúèXþòd·Û‘œœ¬z1w‘ç.N® u“^l÷öö")) f³YiÛ½{76nÜ@}ÁVZZŠžžܺu+à¤h">vì, FFFÐÑѧžzJé÷øý;:: "8uê §§çÏŸ÷Úî¹çžCWW\.*++‘““ƒ²²2¯6ÏxBlŒPUU…µk×¢¥¥£££°X,¸víZD1`Ë–-زe úûûÑÞÞŽU«Vœˆß}÷]¬X±Bù~hh .Ä·ß~µs:X´hžyæ;v 7nÜðêÿ\®sóÿÜ´··CDð×_MÈ“ÉdBFFFH9 ÇLXlòÉ'سgzzz&<Ç9~ö½ÔLgü@uðê‚1”>–••¡»».— X·nr¼@ýõíÃŽ;P\\ŒÞÞ^ôõõaýúõxóÍ7æÃ_¿+”óÕ7/Ì]d¹‹£kÃäÛží_}õUÀèè(rrrpøðaêñøG:ûúùçŸqçwNØÿúõë¸ãŽ;°oß>Øív¯}<Û]½zUiûõ×_!"hkkójÓjµ~ǯ;Ø ÑhðÇø=n81úúú "¸xñ¢Òvøðá€9ëììDBBΜ9øî»ïžž>á'ÒXÕû Zuu5rss¡ÑhðÄOàï¿ÿöÚv®Ö¹ËÙl†ˆ ¯¯o±¡Ñh”ïå,3a±ýøã#11™™™(((À7ß|£\è8ÇϾׯ鎨¾<ÇOKKóúÒëõaŸÍÍÍÊó§OŸFrrrHý_3O®Æ¿»ÑÐЃÁà7jãq»ÝAÊùÊb›¹ ž»8º6Ô©þ»öp½øâ‹RUU%ü±466ŠÝn—­[·úÝ~É’%“Žùã?ʇ~(MMMât:€8ñÚnÑ¢ErôèQÙ·oŸìÚµKòóóåƒ>ÂÂBe›¬¬,å±N§Sm”ááaIHH)v°1Z­V ÷ßÄ㣳³SDDrrr”¶ñÕ,^¼XŠŠŠdÿþýRPP û÷ï—ÊÊJINNö»ÏtÖND$77W¾úê+ioo—šš©¬¬”³gÏ*ÛÌÕú17c222DDäúõë’žžîëÆr×]w)߇’³P¸\.©¯¯kŸéæp8ÄívKgg§tvvŠÙl–·ÞzK–.]*óæ…÷qÎññÿ:ˆuüPêàËf³Éüùó•ïÏ;'kÖ¬ «™™™Êc½^/N§S†‡‡ÃÊ—'W=ö˜Ò@Ün·ŒŽŽªæÃŸ`ÇŠ$Oj˜»à¹‹ÅµÁŸ)ù€äÓO?-IIIòÃ?ÈÁƒeûöílã'zµI?%%EDÄëFùŽŽåqoo¯”––ÊK/½$ÿüóü÷ßrôèQ+Œ¯’’9uê”twwˆ ¤¬¬,üA†;س³³E£ÑHssó”ÄX¼x±ˆˆ\»vMi³Z­AÇóòË/‹Éd³Ù,§OŸúÁÈé®ÝxƒA^{í5¹|ùrÐqù3Ûêç1—s“••%Ë–-“ººº ñL&“lÚ´Iu¼S‘³¹‚s|ü¿â!~,êàO8ù2 ""rñâE±Ûíb·Û¥¿¿_ƒÖ9’cùËS¸?ûÃ܉«kC¿h×®]X·n´Z­×ÛVjo1Žÿ5¿çœK—.)mCCCÈÈÈÀ;#ááa477ãÑGUÞj°Z­üôÓO€ææfFÕ·8Z[[ÑÐЀ[·nadd}ô²²²&ôÍ·¿þnà'v 1c÷&F´¶¶*÷ÓY­ÖˆbÀæÍ›Q\\Œþþ~ttt`õêÕßVÆ>(™““ƒÜÜ\F¯çb]»¶¶6¼ÿþûJ~þý÷_lß¾ëׯŸóõcn¼ssâÄ èt:8pèééÁîÝ»‘žžŽ¦¦¦r޹v À9~&¼|Mgü@uðÊ}Ç‘ôÑ·¶úë»EE¶nÝ ›Í`ì~_Oì`·wøÆ t¬@yòw1w‘ç.N® SsÏ6455ADðàƒzµ›ˆ±¿€±páB¤¥¥¡¶¶pòäIäååA§Ó¡  ð*Èž={™™ N‡5kÖàË/¿T=®\¹‚ÂÂB¤¦¦"55øý÷ß'ôÍ·¿>-jì`ct8عs' ôz=V®\©Ü#I ›Í†¢¢"¤¤¤¨~RüüùóÐétp¹\^û½÷Þ{ éÁ9>þ_¾sütÆTß¾…²`Œ¤¾ûê¯ïþعs'²³³‘’’‚¼¼<|öÙg~Ï£@ýt¬`yR;˜»ÈsÄŵ¡NL|O¡¼¼\L&“o3ÉÌŸ#gzÿ‰ˆâ‘Ÿ¹µ>¦ÿÔ†ˆˆˆˆh6ãb›ˆˆˆˆ(J¸Ø&""""Š.¶‰ˆˆˆˆ¢„‹m""""¢(áb›ˆˆˆˆ(J¸Ø&""""Š.¶‰ˆˆˆˆ¢$A­Ñl6˶mÛ¦»/DD3Â… bÝ…I™?>çx"¢)–œœ¬Ú®ú$‰ˆˆˆˆhÒø$‰ˆˆˆˆ¢…‹m""""¢(áb›ˆˆˆˆ(J¸Ø&""""Š’ÿúJ›BåKÙIEND®B`‚vsmartcard-3.3/docs/_images/tikz-2debc244e414ed09dc8909102139ca8f37bae82b.svg0000644000175000017500000011573313546304763023772 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-87c02cb0f500902e28e2583f9a1dc09e571332ee.png.map0000644000175000017500000000072713546304763025616 0ustar philphil vsmartcard-3.3/docs/_images/tikz-c523bba45f9fcaa801dd4f6284c7efa1f320c9b1.svg0000644000175000017500000014511313546304763024177 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-bdd1c7794f65b715aa64065713cf57e55a7f9ece.png0000644000175000017500000002435413546304763025315 0ustar philphil‰PNG  IHDRŒDyYçbKGDÿÿÿ ½§“ IDATxœíÝkPWÚðP˜ R*¨É 0AÁ(.µ%l•aÍV€­¬šÝd“*_I‚‰•/Mˆ¦$ ˆ‚ÆMXS/µQ ƒ˜D)5ˆ¨DÐ(Š\8ôvº{š˜þÿ>u÷œóôsºÏiN÷\B()q°uƒ  œâ/B COOÏàd`s!!!¶MàâÅ‹mmm¶ÍÀr:N&“ ξ.\¸ÐÙÙ98û‚!í™gž5j½,ÿ PSSÓ;ï¼3(‰ØØ¾}ûöíÛ7hWmA)))qqq6LÀr_|ñEAA³³óàìîùçŸ_¸páàì †®sçÎ-^¼X§ÓÑ«½<¢(*88X¯×pVvá‡~°u ÔSO=…C]]]Ý`îÎÏÏ£z5räHö*>’ƒ HŽ•'@œ-™™™}Šàêêj½tú™ƒ wwwfyΜ9ß|ó ³úÁüóŸÿ¤¬×ü³gφ……i4š€€€üüüþ'ݯ±›OÙw†{öì zæ™g‚‚‚JJJèÖMØ®Øá Ãˆ³0Åq柣åË—kµZ­VëçççááAQÔ×_¬Õju:}ÓÓÓŸ|òIÎÛééé~~~Ï<óÌÇLoÆCI £fã( ºãEDD Š¢JKKe2ÙÅ‹ù…årù¢E‹8»33‚5»%uëÖ­mÛ¶‰—'—ËûTÞÅÅÅ’ÝñÆþÅ4ìU777f977÷oû³vâÄ «ìš.¯R©Î;Géì쬫«ëSËs`*²WÙÍ·ç ËË˵ZíÍ›7 !·nÝ >~ü¸ù §§§÷ôôô#+Z½zµ%ÕûÝë¬#n F\?bæää¼øâ‹„‰'þðÄ‹/Nš4‰ræÌ™7n°cîÙ³ç/ù Ã/¿üB,Jï¾ûnGGG_sî7Œ§Ûô;T?â0ù÷ÜsË—/¯®®~ôèç·ƒMEèSó•J¥R©LIIñõõÍË˳·æÛm†çΛ3g½zöìÙÀÀ@Á„«wuumܸq0qäÈ‘£Fº|ùòåË—>ìáá1}útS…-q”é^‡g‡ý™sšL+..þä“OèåÓ§Oùå—E%$$¼üòË‚å}||é2ÿú׿(‹‡R[[[vvöˆý‰1¥µµµ­­­ªªªªªjß¾}cÇŽ7ož©ÂRþ;ÕkñP"ÍÁÁù=Ý:GGGú“ËEݽ{·¼¼¼¶¶V&“uwwËd²¬¬,þuuþüùYYY………L&½F°°[r™š(ÑÄŸ]¸p!<<\©T655±§uì//¯‡Ò˦¢¢‚RXXȼaQ__OÙ²e ½…©HÏë[ZZÆGLÜË2Ë"q89¤¤¤° ŠWÔëõyyy„üü|þ§¹5 û΃y_Yp׿7ÿСCôsˆS§NÛaóí6Ã#GŽߺu‹ÒÔÔ¤ÓéŽ;&˜° ›<òõõuppðõõ?þ¾}ûV­Zeª$ÄÑ^ÇïrÄô¹Àˆ#öן9-%¼ÓÄTÉËËKLL¤ËüðÃS¦LaêΘ1ã믿&„>|xÆŒü˜„U«V:tˆRVV6kÖ,bñPè'@2™ÌÅÅE¥Réõú³gÏŠ<²|ÔðÏ"£¦×8ìPü8œÖ±ñ[ÊÞ’››»lÙ2f5**Šó­¦ðÙ³g'Nœ8zôh3#XØ-­ù!„þð¿UÌš5küýýév•••ùûû¯]»–>d{öìyúé§Ù[˜Š³fÍR©TüÏñ;–HNÍÍÍ .¤Ÿ?~\¼"ýá²   ×_~•ýBú¦ê§Ÿ~â4ßÔ®Ío~RR’R©Ôh4áááôÓ~{k¾ÝfHùì³Ï¦NH?ÕLXM&@ñññEEEÌ_ ñï³pFíuü.GLŸ Œ8;ìÏLóM]éA«T*ö‡ W­ZõöÛo3a¿ÿþû°°0µZ=}úôï¿ÿž’––æãã#“É|||ÒÒÒ!÷îÝ‹‹‹S©Tááá.\ +Z2”tôÓO?-X°àäɓ̖5ü³F†È¨é5;?§uD¨C¡ гÏ>KϹi~øá?þñSÕÍŒ@,ë–œ Pïÿ ì‹/¾0õÔ`˜Y³fMzzºmÿXzzúÚµkm˜€åÞ{ï½ÔÔÔAû_`5`ŽÒÒÒÉ“'3ÿ ¿ ’ƒ H&@ 9˜€ä`’ƒ HN/?Ó9zôè+W®0ÿÖ`x£rÔ¶9899aÄÁPg4èg Mí£zõøñãÔÔTfµ—ß~ðH&@ 9˜€ä`’ƒ H&@ 9˜€ä`’ƒ H&@ 9˜€ä`’ƒ H&@ 9˜€ä`’3bðw¹uëÖÆÆÆÁß/ ?¾¾¾K–,±uv¤­­íÍ7ßtuuµu"0äµ··¿üòËþþþ¶N` Ø`ÔÜܼaÆÁß/ ?ééé¶NÁ¾•·îà"6¾3“ÿÁƒÈP?·zusÆWŸ×áÇÿûßÿš“0Àe_O€ÒÒÒ¶mÛF/¯Y³&;;›úíÓÕÕuåÊ•Z­6**ª½½]«Õ.X°€úý (}¯öÙgŸMŸ>]§ÓEDDÔÔÔ0¯nݺÕÏÏO£Ñ¼õÖ[tÅÌÌ̧Ÿ~ú«¯¾ÊÈÈ õóó+++ b*–––„„µZ­ÑhŽ?.Rñøñã 3gÎ zýõ×9mojjš0aEQNNNJ¥Ò~2ä'öðáÃ3gÎlÛ¶mïÞ½ì&<ÿüó%%%E•””,^¼¸×ö/ôÈà¢~ë2™¬£££ƒ‹²ûñeaNëØ\]]7lØâïïäÈöK111—/_6ÕÏ­RaæøÂàøŸÁŸs‰ÜÇTWWGEEÑË ä·û!ggçÂÂBú%ö "{™¾›iii¡Wkjj"##™2cÇŽmnn&„Ü¿Ÿ"—ËwìØA©ªª5jÔ®]»èeµZ-ÄTÉÉÉ™™™„îîî{÷î‰WÔëõ¹¹¹„ÜÜ\έvFF†››ÛÂ… é{P;ÉŸXQQÑÒ¥K !³fͪ¬¬döØØØHß°†……544pn.­‡ O€Ö¬Yóâ‹/ÖÔÔЫ"O€Daõþ .b÷ãËÂ8œÖ±Éåò‚‚BHEEÝ:&ÿ¢¢¢¹sç öskUg˜3¾ú4¸ð†=ûšB¦NzãÆ ƒÁ0sæLz }9Ëåíííì-üez0WUUÅÄÄi4¦L\\\llìž={è8 …¢³³“®(—Ë™çÞîîî‚AL%àííÝÚÚʬŠW?~|[[!¤½½]¡PpÚ^WW—““ºdɻʓXlllYY!$''gÅŠì=Λ7¯´´tΜ9Dè½kÅa`”˜˜HQ”‡‡GHHȲeËΜ9#ò˜©ÁEX} ƒ‹Øýø²0§ul …¢««‹Ý:¹\®Ñh´Zm||ü•+Wû¹µª³õ:¾ú4¸0‚aÏ?„(N¯×ïß¿¿©©‰óxÖÑÑQ.—óË;88Bd2™Ñh4E%%%mß¾=22²££c̘1LÉÒÒÒòòòÝ»wïܹ³¬¬ÌÁÁÁÉɉ~ÉÙÙÙÑÑ‘^&„1•G¿+R¥T*•JeJJН¯o^^žýdÈNlãÆåååµµµ2™¬»»[&“eeeÉd2&øßÿþ÷¬¬¬øyóæÆ{mò0vûömŠ¢~ýõ×ÚÚÚ_ýõöíÛsçÎ5UØÔà¢Lôó5Æ—%q8­c¿äàà0räHvëé/Su÷î]‘~nyu¶^ÇÓvsÀð7øs.ñ»ö .„‡‡+•ʦ¦&z }×¾)ôòòzøð!½¬Ñh***!………ôÃjooïúúzBÈ–-[è-tÝ«W¯BZZZÆG„înÙ˦‚ðHIIa?Z¯¨×ëóòò!ùùùœGô‡êéé!„œ:u*88Ø~2ä$–››»lÙ2¦|TTÔ‰'˜  ¦Ü¹s'::š½åèÑ£žžž¶Ê`èÂ`Èðôôd¾#–À[` 9˜€äØà-°–––O>ùdð÷ ÃÏ£Gl‚}‘Éd§OŸæ¯ ¯~üñGúwƆ+| þÎ;÷ïßä°4fÌúŸt£¾¾¾§§ÇÖYÀpðä“O2?á 0üØ``[ø H&@ 9˜€ä`’ƒ H&@ 9˜€ä`’ƒ H&@ 9˜€ä`’ƒ H&@ 9˜€äŒèSék×®uwwP*6áààðÔSOÙ:‹ÑÐÐ`4m %'Ntrr²uƒAF1³hGGÇ_ÿú×?ýéOšÀ ;|øð_|aë,¬ïñãÇz½~þüù¶N†ŒªªªW_}5((ÈÖ‰ †><"„L›6mÙ²e— Àà»qㆭS„ÐÐP X0ß¾}ûlÀàÁg€@r0ÉÀ PDDcff¦ù\]]­—N0ÅÝݽzöìÙ°°0FŸŸOQ”B¡Ðþfݺu½fB«^ÛËß‘…˜sÔ§ÃbNëDö5ø¬rÒ‡=Ë,5cv ì`ÆaKDD„Á` (ª´´T&“]¼xqàª÷ïŠ 9Äl=ÊÌÌ4¿<ŸÑhtqq1¿|Ÿ DìŠìU777öªJ¥:wî!¤³³³®®Ž˜—9¿L¯µø;²Ó®Á?/œC: Ä^½zõ e2˜:;;322,‰ÐñbÝ1;@v0ã0ù¤ Ì!Õëõü8½žk~óùˆdžÝ¸qãáÇ̪È °L1;°Æ15<‰P÷cò/**š;wnQQÑÒ¥K !³fͪ¬¬´nu†9W$Ax’bµ·À¦NzãÆ ƒÁ@ÿ"¬¡+—ËÛÛÛ9ù×Óªªª˜˜˜   FãááÁ.»gÏ:ŽB¡èììd‚3©ÝÝÝã&@ñöönmmeVÅ+Ž?¾­­ÒÞÞ®P(8ͯ««ËÉÉ ]²d ú‹Û§ §½";òñña®k¾¾¾üF îši—àé˜7o^uuõ×_½hÑ""„ß:…BÑÕÕE/ÓgÁT0uH½½½㈟k~óùf6 ¤¤¤É“'Ï›7o×®]âo Ä€eŠÙù€µ0ŽÈðäw?zæ¡Õjããã¯\¹VFÉÉÉY±b…u«³õzE„ HJß~ Z„^¯ß¿SSÓâÅ‹9/9::ÊårÎFBˆL&3ôÕ&%%mß¾=22²££c̘1ìÂ¥¥¥ååå»wïÞ¹sgYY™ƒƒó[¥ÎÎÎŽŽŽÌÓ,Á8‚ ðõ»"EQJ¥R©T¦¤¤øúúæååñ ðÛ+‚Ó^‘õôôœxð`òäÉãÆ)öÊ+¯„„„,X° ;;;99Y§ÓÕ××;;;S•­ÓéZ[[é-ŒäädµZ={öìM›6õš‰HvtÉÊÊJ•J¥Óé ƒxÅìììO?ýT¥R]ºt‰~•ùÚpqq±¿¿¿V«MMM¥o¶º»»™/._¾œ®Îi/;N{Ev´yóæêêjµZ°ÿ~~£w-r^(Šrrrš3gNbb"s§ÎÁoŸ9ýaóæÍ%%%jµº¤¤äý÷ß7UL¿ù‚Dõp¢R©^xá…£GÖÔÔøûû‹–ò€µ0¿ufþÄCqq1».Z´¨¸¸Øòê‚%{½"@þX{{û|°råÊMl®§§G§Ó}þùçùþHzzúÚµkm…õuuumÚ´iÕªU¶N†Œ}ûöàDà— áw~üñG__ßèèh‰Ì~@š¬ö!h®^½Ê¬Þ¹s'::š]àèÑ£žžžƒžpaxX ãééÉ| ì †'€%ðH&@ 9˜€äôá3@#GŽlllLKK¸lßãÇm€ptt¼uë,˜¯­­-**ÊÖY ’>üÀð€·À@r0ÉÁ$ L€@r0ÉÁ$ L€@r0ÉÁ$ L€@r0ÉÁ$ œÌRSSSVVÖÈ‘#m˜ €êììLOOwww·u"ÿsëÖ­ììlŒV|ÝÝ݉‰‰Ó¦M³u"–úßèæÍ›‘‘‘ñññ6ÌÀåææ¶µµÙÕèæÍ›QQQÏ=÷œ­Éùé§Ÿ &@0 à-0L€@r0Ééÿ(""‚³%33³O\]]û½wSúšƒ Χ=Ξ=¦Ñhòóó)ŠR(Ú߬[·®×LèceN{ÿýïëtº   ­Vûÿ÷===æ$l~«é˜üÃÃë««K¾óÎ;¯½öš™‘-‘••EçãèèH/lذÁ˜¦Ž¶UzÈ#Ñ:˜q˜qa0(Š*--•Éd/^¸êœ2fŽþ……sˆ1`ïÈoªªª¾üòKb¹\Þ§ò...–ìŽÏh4ö/¦Ñhd¯º¹¹±WU*Õ¹sç!uuuļÌùez­uâĉàààëׯÓ)mß¾½³³ÓŒô…#sÅ.É”/++›>}º`Lsö.¸—~³ñ¿•IDATb—0ª»Ø¾}{cc£ÅYSeeeii©%†ëhÌ8Lþ #„$&&ÆÆÆ®^½zછ*#r0/,¦.½ž”üqÏž=âe†³&@o¾ùæÖ­[éåôôô¬¬,Â'...iiiôtJ£ÑÄÇÇ“ß"úÊRXX8mÚ´àààððpƒÁÀ.óÑG)•JµZ½råJzû{ï½§Óé¦L™ràÀuëÖ…„„(•Êo¿ýÖTœ´´4FáààÀäÐÜܼhÑ"•J¥V«;&RñÈ‘#×®]‹ˆˆ LMMå\ ½¼¼8ÿÄ'7nnnï¼ó;δƒÓ^FLḺcÇ8‘¯_¿M_Â\\\Ö¯_¯ÓéüüüÊÊÊøûb%X—‰Ñhôðð Õ‚ BBBf̘a0-ZDÇ,,,ä¿ÊÙ‹à«ì ùç‚_…scŠô —7Þx#000""âÚµkL(ÎIç+Sip ­ ÄG«…qLM"Ô«™còøñcOOÏLž<¹¾¾Þßߟ^,¬N)#2q¼°ð/½Æ¡aÆY êêꨨ(z9  ¡¡°Æ‰³³3ýg’=rø—Ô––zµ¦¦&22’]fìØ±ÍÍÍ„û÷ïBärùŽ;è”Fµk×.zY­V Æaàì799933“ÒÝÝ}ïÞ=ñŠz½>77—’››Ë¹9ÎÈÈpss[¸paaa!}×(—Ë5¿á·n/ÿh˜j/ÃÛÛûÁƒœƒŸÀ$¦×ëé½B***ècÂÞ»QüºœLöíÛ7cÆ BHJJÊÑ£G !çÏŸŸ9s&'&ÿUö^ø¯ò3äœ ~ÎéŒ)Ò+är¹`KEzà^ÙÃhïÞ½/½ôÒ¥K—èU‘ ÄG«…qLM":îŠŠŠæÎ[TT´téRBȬY³*++­[)iªŒÈÄEð¿ô‡†  æ¾6uêÔ7n æï3Näry{{;éí’ZUU¤Ñhè¦L\\\llìž={è8 …‚yóE.—3OªÝÝÝã0 pöëííÝÚÚÊn HÅñãÇ·µµBÚÛÛ §ùuuu999¡¡¡K–,!B׈>M€8íe'Ì¿N±óöö¦OWWû˜°÷eªQt]º$=›4i’““ýîž3¥óõõåÄä¿ÊÞ ÿU~†œsÁ¯Â9Œ‚1Ez…\.gZ:aÂ&”H¯IƒÃ&@o¼ñEQcÆŒ YºtéDÞ“òhµ0Ž©±I„z5=Ž´Zm||ü•+WbccéG;999+V¬°nušH™¾N€ø^ãÐ0‚ac„Éýž^¯ß¿SSÓâÅ‹9/9::ÊårÎFBˆL&3F£‘¢¨¤¤¤íÛ·GFFvttŒ3†]¸´´´¼¼|÷îÝ;wî,++sppprr¢_rvvvttd>®$G0¾~W¤(J©T*•Ê””__ß¼¼<~~{EpÚËl ¬ªªš={¶xuæ'€écÂfN£ COOOjjjFFÆþóŸžžž“'O>ñÄ‚åù¯²÷ÂUù¤³³“I,///11Qðøð÷Åi§.S¦££còäÉIIIô±"„ÔÔÔpâXò*!ç\ð«p’7'&{Y.—3§ÝRþIg+SipØÉ 3f¤§§ß¾}[üCÐR­Æ156[ÊÞ’››»lÙ2f5**êĉV¬Þk‘'7‚þE ×84<‚aÃܯÁÒŸ¿7nœ©2¯¼òJHHÈ‚ (ŠÊÎÎNNNÖétõõõÎÎÎô–èèhN×ÚÚJoa$''«ÕêÙ³goÚ´©×LDâðs¨¬¬T©T:Î`0ˆWÌÎÎþôÓOU*Õ¥K—èW™oûûûkµÚÔÔTúñOww7ó5øåË— ¶— §½ÌŽž}öÙ7Þx#... 00ðÒ¥K#FŒØ¼ysII‰Z­.))yÿý÷{=òl½Öuvv^»ví»ï¾»yóæêêjµZ°ÿ~~œ~¿Ê^ö¹èµŠ91Ù/_¾¬R©vìØ‘••ÅÞ/礳U_÷bC/½ô’Á`øî»ïÖ¬Yãåå%^XÊ£ÕÂ8üÖñA@Pqq1{.Z´¨¸¸Øòê}-#Hð¼Ê\Ì 0œÈÈoï TWW744àÁPäêêúðáà ž››çãã3@ñû¡ªªª±±ÿ ý¿Àžþy['`)ü4H޹‚°g÷øÀ&îܹÍÞrôèQOOϨ M˜ØOOOæ;b] @šðH&@ 9¿{ ìôéÓ?¶U*ö©ºº:..ÎÖYp>}º««ËÖY€äܸqCäç†ÿ} þñãÇçÏŸ·m6vH&“iµZ;z\ÚÕÕU[[kë,@¢üüüFmë,,õ¿ €DØÑM-ÀàÀ$çÿà‚iS¶W;IEND®B`‚vsmartcard-3.3/docs/_images/inheritance-647e4e3af2eb4356e4633a015c7851f55a66a0bd.png.map0000644000175000017500000000071613546304763025676 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-d5ba565391cc5041a7ec6184d1e94238defbb78e.png0000644000175000017500000000542613546304763025300 0ustar philphil‰PNG  IHDR‰$j¨7obKGDÿÿÿ ½§“ ËIDATxœíÝiLOð©€(»åPð@J%ž¨ xAŠc”Sƒ¢Pc´1!Þ1iŒ&g<ÿ¢`//oèС4M‹D¢#GŽ0G‹‹‹###ýüü&MšôîÝ»ëׯ3†¦i‰DòéÓ'Ò‘àÝ¥Š1Öét›7oŽˆˆ i:**êÍ›7ö„òññ1 )))þþþcÆŒ9~ü83L†Éd ?~ü8³gË–-qqqæ£vR1É»¼¦¦&ÖÉuëzzÒ F½}ûvóQ¤§§K¥RÃìQS›cp©álj8)¾e•̱êÿàÁƒÞ½{3Éäææ2dÀ€k×®moogµ·šX^^^tt4¿ªªÊËËëóçÏÜwçŒéYTTTTTd¾ç׿ææf___…BA6wìØ1{öll±œ¤§§k4šŸ?Z!V'LIIIyy¹ÉdR©T3fÌ ™0íU*BèþýûcFóúõkæè‚ ;;;³²²ÄbqFF³Ir³¼»T1ÆÙÙÙqqqÕÕÕ]]]ååå_¾|±3Æ8)))))©µµU©T’¯Z³œ0»v튊Š"¯õz}HHÈùóç9(fGGÇàÁƒçÏŸ_RRÒÐÐÀäãÖõô˜A)•J„ЇÌGWXXlc˜=ráÚ\RR²mÛ¶ººº?Ê.5¼Ô8<¾Õ*™3£F£‘J¥‰„ÊÉÉIIIinnnii™5kÖÖ­[Yí­&ÖÚÚJQÔóçÏI¹\>wî\î»sÒôtÀÚLÚ¬[·cÜÕÕ%‹/]º„-& “ºýÆÜ½{÷úõëgÞþëׯ^^^'NœÐjµL3r´²²’l>|ø!T[[ËlúùùYæÏ Þ]ªmmmàÙ³g6JÑ]¨––„ÐÛ·oÉæ¥K—¬³¾¾ÞÛÛûéÓ§ã+W®²ÞÓ9©˜ãšš™L!¦M›öñãG¨§g J¡P „ZZZ̃<~üX Øf\¸6¯_¿^  4(**jÿþýä¯ ¸Ôp65œßj•Ì‘84M#„Äbq}}=“ s›¡´´T$YÖÄ21ŒñªU«d2ÆØh4†††^½z•ûîœ4=-×föwvÚcåÊ•ÙÙÙ‡züø±V«]¸p¡e›¡C‡þiØÛ·oïÛ·¯¢¢‚ÔK§Ó™L&æèàÁƒ¯]»vâÄ ¹\³wïÞøøxr(,,Œ¼ (еÙÞÞn4½½½mï.Uò6ĈöçÉ„ª¯¯G‰Åb²É¼` MNN.((ˆ-((ÈÊÊêÛ·¯e3‡!qúôi„R©ÌÍÍÍÊÊ"¿¬Èëéƒ F}ýú500 ØÐÐпÿ‡iCGG‡å÷rC£Ñ`ŒÕjµZ­–ËåG‰D½zõü° \j25œßF•Ì©Õj__ßgÏž%%%åççïܹ“$3uêTÒcl0ºººzLÌËËK&“%&&>|¸¬¬Ìh4¦¦¦rß“¦§¥¿ylΜ9¾¾¾·nݺpáÂ’%K¬.'ÌÄcÍ@¡PˆÒétd“ÜA577§§§¯^½úóçÏ?~ü¸víBclþ³iii÷ïßojjJHHÈÈȰ?aÛÁ»K5<<\ TUUýE¨ÐÐP„З/_Ȧÿ1°fÍšÂÂB…BñàÁƒîžsF1"‘hãÆïß¿ï.CK|®§ *,,lÔ¨Q¬ïš.,,LLLü÷aº¸Ô8dj8)¾Uqqqûöí;pà@CCƒH$B½}ûV«ÕjµÚÖÖÖöövó‚ØHlÊ”)Æ +..>{öìŠ+ÈÇöwÇÝôdýemç/¹\>sæL???æ> ëFs¯€L‰wïÞ‘M½^¼sçN£ÑXUU5yòd„Á` §üÎ;㪪*‰DBö3ÑjjjJKKþüi2™<†{ºmÅlöÜjª㜜‰DRSSC>¤©««³3ÆxÞ¼y)))­­­*•jâĉÈÚý4Œ±Éd‹Å̧#³¶¶vÏž=d\ß¿_²dɬY³Ü½žž4¨›7oRuæÌ™¶¶6F³cÇŽÀÀÀŠŠ Ãì‘;ÞÓÆp©qÐ¥Æáñ­VÉ+ŽÁ`1bĦM›0ÆR©táÂ…jµc¬T*ILûî#qN:åããC¦ƒKºsÆôtÌçÍ㊊ „ÐØ±c-Kcyj·lÙ——‡1¾{÷ndd$EQ±±±gΜa qôèÑ!C†P5eÊ”S§N±~Q>}úïïïïïïûäÉËóÑÝ„é1xw©êtº 6ˆD"𦣣£É‡.v†R«ÕÉÉÉB¡õpãëׯ)ŠêììdZîÞ½!táÂÎŠÙØØ¸téÒ°°0??¿Aƒeff*•Jw¯§' ŠœY‰DBQ”¿¿rròû÷ïÉþî†Ù#·{Œ€KC.5oµJæZƹ|ù2EQMMMmmm6l …‘‘‘ÇŽcUØjb$È?hšf<Ž»c8|zZ®ÍüûÍœÌÌLø‘x¾Mm¾åÜÆxذa»wï–J¥žÔyÄüÿ7Ã÷ip—/_Öëõô€ugîožÓ8âíí}îܹ޽{{^w,°6pMMMÜ ÜÓøÖf€_`møÖf€_`mø…ýœ¶B¡X¼x±KR8Ï›7o\Âoúôé—•J%—ËÍ÷°¿ ®÷´~µàX›~µà—ÿŠ¢g|=õHIEND®B`‚vsmartcard-3.3/docs/_images/inheritance-151a141442b8b2ad4b9ca6f670abcf103a9252a6.png0000644000175000017500000000406313546304763025146 0ustar philphil‰PNG  IHDRP$PNõíbKGDÿÿÿ ½§“èIDATxœíkHßÇÏziÑ™YQV¥ÖuJÑÕJÂŒ¤² å5•%7 zDHIbD`](*·ŒèM”QJ]¼@"E^Ë0o­—5Rsu]Wwõü_þÃ6{qÔ­ø5ÏçÕœ™ÇïyÎwøîά³*Á#Ä×ßn€?DDD„oµqãÆ¿Ò žåýû÷ö{øOHHxüøñl €ßE^^o\Ò€ˆ€À€ˆ€À€ˆ€À€ˆðXà[ZZhšžõ” ¡±±Q"‘X,ÏÊþaÈ*l6Û?0Ë‘»ä±À'$$˜L&©TÊÛÿJì_iµ©©)++K.—Ëd²èèèâââ±±1(·µµåææ†††Ò4­R©233kjj<¢¼$<â*¸ä)~ï%ýÜÜÜoÕ÷ lU¸T}}}JJJRRR{{ûäädmm­D"ùøñãÊgihhضm›Z­njjšššjoo×jµUUU[*ž=Ñ<5pÉ“jøWrss±[nÞ¼¹aÃnøíÛ7///½^ONÀÌÌ Ù¸ÿþÚµkB¾¾¾!Š¢(ŠºuëWF~œ ­V+ÆøÎ;qqq Ɔj4šááa®€Ô———GDDÐ4­T*¯]»Æ}òäILLŒ¿¿ÿ¦M›>}úôìÙ³ØØXš¦·nÝÚÙÙI&r#îªUŒ±Éd:yòddd$MÓñññ­­­B¤|}}­VëÈÈHzzºL&‹-++ã–iO\\\II‰SŸW8K||¼+e²®cÇŽ)Š£GšÍfNüéÓ§ÑÑÑÄ½ŽŽŽEëí›qì™eY???ž«?þÔh4ÁÁÁaaaÅÅÅsssNÕÀ¥%¹äÇ8/9ðF£Q*•¶´´áÙ³gwíÚ…í’I6²²²ÆÆÆ¦§§&Üi૪ª:::æçç ÃöíÛI'\½Á`@ÕÕÕaŒÇÆÆš››¹£ûöí±X,P©T999Üôæ^ÜU«ã‚‚‚-[¶ôöö.,,tttô÷÷ ”§¦¦¦¦¦NLL ’‡y§ghh!ôùóg§>¯dâ•+eŒ±V«MOO7ããã)))§NâÄsrrFGG-‹F£Ù±cÇ¢õö͸?ƒÜìééé{÷îeYv`` 66¶´´Ô©¸$Ü%Wx ð¤æøñãã……•JUQQÿåËR,<ðöÔÔÔÙ×ÿþÝÛÛ[§Ó±,Ë•‘£ÝÝÝdX__ÒëõÜÐßßß±ž¸«V§¦¦$ɇÜXáJj||!ÔÖÖF†ŽËlmmEF7úË›…§\YY “ɤR©Íf#ëâ®}^¾|©T*9ñžž²ÿÍ›7~~~œ®ê¹fÜ÷̹ʲ¬}Ï<ˆŒŒt£. qÉŽqæ?Z+„C‡\¹r¥¡¡eÙììlÇšˆˆˆ¥Ê¾xñââÅ‹]]]dÙ&“i~~ž;ºzõêÊÊJNWRR’páÂ…äädr(,,ŒlPÅšÍf›ÍæãããFÜU«ãuëÖ ï““"ïK*•Š ¹ {är9© \’‹ÎÂSÎÎÎÎÎÎnllLLLÄ“umÞ¼™cŒ­VëÂÂ* ²AÓôÌÌŒÍfs_oïžû3H ï«\«d£¸$Ü%á,çC»Ý»wK¥ÒçÏŸß»w/??ŸÜ~ðu½¼x†aB&“‰ ¹eƬ¬¬#GŽôõõMNNVVV"„ð¯'33³®®ntttçÎ999Âv/îªÕððp‰DÒÓÓ³ ©5kÖ „úûûÉ÷‚B¡ˆ‹‹{ôèѲv5‹B¡P«Õ>tê†R©Dµµµ±,˲ìÄÄ„Ùlæ­]x=·áªgž2y9æzîëëã^ ‘Ã)—º$œåü¤···V«-++«ªª:|ø°ûâÐÐP„Pww7FFFÊåòòòòùùùÞÞÞóçÏ“ýÓÓÓ6›-$$ÄÏϯ···´´”§£×ë_½ze6›W­ZÅ0ŒÏ®MwÚ*MÓ………äáëׯƒƒƒ¥÷ìÙsæÌ™ÉÉÉ¡¡¡«W¯:-Óét:îòåËÃÃÃ!ƒÁpúôéêêê•ÏB”Ï;744„16›ÍïÞ½#‡†Ñh4'Nœà&}ýúµ÷Ö»ê™çj@@@ZZéÙ`0\ºtéàÁƒnf—º$”E/úÒÕÕ…R«ÕÜÞ=¼ýÇEEEÁÁÁåååãêêꘘŠ¢’’’îÞ½‹þs{ýúu…BAQTbbâíÛ·É~N­³³399Y&“Éd²¤¤¤·oßâÅ>°ºwÕªÉd*,,T*•4M¯_¿žÜS ”úñãGZZÃ0¼O†›››)вX,¤¬±±1###((ˆa˜¨¨(òæ•ÏB&Ú¿pp0EQ*•*##£¶¶–ššš*,, g&&&æÆîÍRïªgGWGGGóóóår¹B¡(**šuT—„¸´(Žq–à_/›óòòàë±ðoàgx–DDDDDDDDÿÁøGðÏÐÚÚJŠåà€¸¤ñ?¤ãHì!â®UIEND®B`‚vsmartcard-3.3/docs/_images/tikz-5b402031da401947efbeae7481d47bd35196791d.svg0000644000175000017500000031077613546304763023560 0ustar philphil vsmartcard-3.3/docs/_images/inheritance-2df37359f5f3e9e8ae5b3298a982b18985d97b0f.png0000644000175000017500000000433713546304763025203 0ustar philphil‰PNG  IHDRô$1s€†bKGDÿÿÿ ½§“”IDATxœíœYL[ÆO©ˆÐM"4Z"Å ”€" mId©"!‚MŒ‰•DÐHTcT­C\ &K0B+$* Q±ìhÙJÁ²zîÉsët¡rÑ'ç÷4ÿ3gþóo¾´Z ACElþoÌï‡CYp¸1”‡CY–j??¿7þ/R0˜ÿÂëׯ»»» GÈá |ôèÑ”„Á,ÉÉɤ¼-ÁPn eÁáÆPn eY´p7440™ÌéééÅjˆxûö-F›ššZܶ´ŠÙÙÙ?kâ¹PÃÉ_bѨÕjíììHã‘§^ê»wï„B¡£££££cPPГ'Oyyy«V­"æäççÓh´ÊÊJTNNN.[¶ìéÓ§æz’Vaî¹,@ؼ [3 H$¿tßÅå÷nKfff~kÿEd¥ZÙjzz:&&F,«Tªþþ~©TÊáp"‘¨½½½«« M“Ëår¹•555z½>22r±ÔZ/ÌJ†††´?(//'%™c¥W |:ðgöìÙ-rãÆ 6e{{»MGGÇ›7o“““èàÁƒ«W¯ØÚÚ ƒÁ¸yó&1 ]ŽJN!,((X»v-‹ÅrssKMMíïï'& ùR©Ô××—Édz{{_»v8[RRâïïïàà°iÓ¦¦¦¦²²2@Àd2·nÝÚÚÚŠnd¡¹9©B­V{òäIÇd2×­[רØhM+[[[N700 ‘HØl¶@ ÈËË#–IÐÜÜ 46ÙÃã°°B8;;»|ùòÇoÞ¼:}útxx8É¢²··7i¸e'­&“Éø|>:>sæ @©TBëêêØl¶N§#I" ™S[[Kòjhh(55ÕÅÅ…Ëåž:ujffƤ¥fC !4Ý_·Z­¶³³khh@åÙ³g…B!4ð$$$ ›|&Ã]ZZÚÜÜ<77×ÛÛ”ó{{{UUUÂáááúúzâìîÝ»¦¦¦ÒÒÒ|||’’’ˆi³ÜÜœTazzzhh¨R©ÔëõÍÍÍ]]]V¶‚ÆÅÅÅÅÅŽŽöôô }IgrrÒÃÃ#66¶´´ôÛ·o†§öíÛ—šš !¬««[³fÍÌÌ ›ÍV«ÕÂàààsçÎYpҜᖴFØÈÈNG&„††òùü‚‚á… $‰±$“>z%‘Hbcc5Mww·@ ÈÎÎ6i©e!ÜhαcÇ „z½ÞÇǧ¸¸™øñãGÃ…YnC^¼xáääd8ÿëׯt:=??_£Ñ\kkkCeuu5 ££ƒ(Œõ“š›“úýûwVWWgÁ s­FFFïß¿Geqq±Ée¶··9r„ÇãÑh´mÛ¶µ´´ ñ»wﺻ»CsrrŽ= !ܱc‡L&Óh4t:ýÕ«Wœœ7Ü&´RXpppaaáèè(‡Ã),,LJJ‚nß¾ýúõëĽ8dee™ó™(5¡WEEE<ÏxÚ¼Gw!{îƒ>|øP§Ó) F“˜˜h<Ç××÷WÛVTT„‡‡»¹¹±ÙìÄÄDµZ=77GœõððÉdeee\.7""¢¦¦†8ÅårуÁ •èwš›“ÚÝÝ !äóùÖë$Zõõõ|||PIàñx·oßF;l''§´´44.‰T*Õ§OŸ …P(DEEÉåòêêj{{ûy¬´ˆ'ç&‹«ªª^¾|¹eË–ØØX…B¡ÕjkkkÅb1q­J¥ÒüàüùóÄ8Ég¢Dï$„E¾¾¾hÄäU¿ÄBÂmggW^^~ïÞ½””´É#÷µ±! X,@«Õ¢’X†Z­NHH8|øpggçØØ˜L&ÀŸÿJh×®]UUUƒƒƒQQQIIIÖ ¶Üܜԕ+WÒh´/_¾, •§§'€ø¡ô…c¼½½?þáâôó󫨨¨­­ŠŠ…B¹\.—Ë###—,YÌ;IZ…I¬w’$L,+ŠÊÊÊèèhwwwOOÏÜÜÜ+V‚yoJF”èň𪳳“xy²r9f︀kètúþýûóòòJKK:dy²›› ­­ •<ÏÙÙY*•ÎÍÍ)•Ê‹/¢ññññÙÙYWWW{{{¥R™MêÓÑÑñìÙ³‰‰‰¥K—²X,ô€­dÞæ&¥2™ÌôôôŒŒ ´Ïiiiééé±²•££cLLLVVÖØØX__ß•+WŒçtvvæää æÃÃá¡¡ÄY‘HtõêU>Ÿïää ìïï/))‰D–$­Â˜y´ ,,,lll¬¨¨½T‹ÅâË—/’‡Ã‰G^õöö^ºtéÀÿ¥á¿Ì»q1ÉçÏŸĈɟÊ™™™...G*•BŸ?îïïÏ`0BBBîܹ~lFsss½¼¼ Fppð­[·ÀÏ;ÈÖÖÖ°°06›Íf³CBBjjjà|;xÃÒrssRµZmFF†··7“É\¿~=ÚZÙJ¥RÅÇdzX,ÒoKêëë ÆÔÔÔÀÀÀÞ½{¹\®ƒƒƒ»»{rrrOOq9zO8qâ1²sçN@SS1bÎIÃU?“NZ/,::ÚÕÕU¯×C+**÷ïß74œa@PP¹ÇdèÕàà`JJг³³——Wffæôô´Éi–1Ž. þüÖŸœœŒ¿òŠù1Ž.þn †²àpc( 7†²àpc( 7†²àpc( 7†²àpc( ùCüOy0)èƒsr¸1Ê€·%ʂá,8Üʂá,ÿ–bF¶kM^IEND®B`‚vsmartcard-3.3/docs/_images/tikz-0405e52eb98193c32482e91a30737e1e9684bad0.svg0000644000175000017500002230126313546304763023417 0ustar philphil vsmartcard-3.3/docs/remote-reader/0000755000175000017500000000000013546304763015675 5ustar philphilvsmartcard-3.3/docs/remote-reader/README.html0000644000175000017500000003471713546304763017534 0ustar philphil Remote Smart Card Reader — vsmartcard 2017-01-16 documentation

Remote Smart Card Reader¶

Allow a host computer to use the smartphone’s NFC hardware as contact-less smartcard reader. On the host computer a special smart card driver, vpcd, must be installed. The app establishes a connection to vpcd over the network when a contact-less card is detected.

\input{$wd/bilder/tikzstyles.tex}
    \node (pcsc) [klein, aktivbox, inner xsep=.75cm, align=center] {PC/SC\\Framework};
\node (sca) [aktivbox, klein, left=.75cm of pcsc, align=center] {Smart Card\\Application};
\node (vpcd) [box, at=(pcsc.east), kleiner] {\texttt{vpcd}};
\node (phone) [right=2cm of vpcd] {\includegraphics[width=3cm]{$wd/bilder/smartphone.pdf}};
\node (app) [at=(phone.center)] {\includegraphics[width=2.8cm, height=4.9cm]{$wd/bilder/remote-reader.png}};
\node (card) [right=0cm of phone, rotate=45] {\includegraphics[width=2cm]{$wd/bilder/smartcard.pdf}};

\begin{pgfonlayer}{background}
    \node (box) [box, fit=(pcsc) (sca) (vpcd), inner ysep=1.5em] {};
    \node [at=(box.north west)] {\includegraphics[width=1cm]{$wd/bilder/computer-tango.pdf}};
    \path[linie]
    (sca) edge (pcsc)
    (vpcd) edge node {\includegraphics[width=1.5cm]{$wd/bilder/simplecloud.pdf}} (app)
    ;
    \draw [rfid] (phone.center) -- (card.center) ;
\end{pgfonlayer}

Remote Smart Card Reader used to access a contact-less card

The Remote Smart Card Reader has the following dependencies:

  • NFC hardware built into the smartphone
  • Android 4.4 “KitKat” or CyanogenMod 11 (or newer)
  • permissions for a data connection (communication with vpcd) and for using NFC (communication to the card); scanning the configuration via QR code requires permission to access the camera
  • vpcd installed on the host computer

For remotely accessing a traditional smart card reader on one computer from an other computer, the Virtual Smart Card in relay mode can be used:

\input{$wd/bilder/tikzstyles.tex}
    \node (pcsc) [klein, aktivbox, inner xsep=.75cm, align=center] {PC/SC\\Framework};
\node (sca) [aktivbox, klein, left=.75cm of pcsc, align=center] {Smart Card\\Application};
\node (vpcd) [box, at=(pcsc.east), kleiner] {\texttt{vpcd}};
    \node (pcsc2) [klein, aktivbox, inner xsep=.75cm, align=center, below=2.5cm of vpcd] {PC/SC\\Framework};
\node (vicc) [aktivbox, left=1cm of pcsc2, kleiner] {\texttt{vicc -t relay}};
\node (reader) [right=1cm of pcsc2] {\includegraphics[width=2cm]{$wd/bilder/my_cardreader.pdf}};
\node (card) [at=(reader.east), rotate=45] {\includegraphics[width=2cm]{$wd/bilder/smartcard.pdf}};

\begin{pgfonlayer}{background}
    \node (box) [box, fit=(pcsc) (sca) (vpcd), inner ysep=1.5em] {};
    \node (box2) [box, fit=(vicc) (pcsc2), inner ysep=1.5em] {};
    \node [at=(box.north west)] {\includegraphics[width=1cm]{$wd/bilder/computer-tango.pdf}};
    \node [at=(box2.north west)] {\includegraphics[width=1cm]{$wd/bilder/computer-tango.pdf}};
    \path[linie]
    (sca) edge (pcsc)
    (vpcd) edge [out=south, in=north] node {\includegraphics[width=1.5cm]{$wd/bilder/simplecloud.pdf}} (vicc)
    (vicc) edge (pcsc2)
    (pcsc2) edge [usb] (reader.center)
    ;
\end{pgfonlayer}

Virtual Smart Card used in relay mode to remotely access a card

Note

This software can actually be used in a relay attack allowing full access to the card. We discussed the impact especially on the Relay attack against the German ID card, but it generally concerns all contact-less smart cards.

Download and Install¶

The Remote Smart Card Reader is available on F-Droid [2].

Remote Smart Card Reader on F-Droid

To manually compile the app you need to fetch the sources:

git clone https://github.com/frankmorgner/vsmartcard.git

We use Android Studio [1] to build and deploy the application. Use File ‣ Open to select vsmartcard/remote-reader. Attach your smartphone and choose Run ‣ Run ‘app’.

On the host system, where the smart card at the phone’s NFC interface is relayed to, vpcd needs to be installed. It can be installed on Windows and Unix. On the host computer, vpcd-config prints a QR code to configure the Remote Smart Card Reader. Scan the configuration with the bar code scanner of your choice.

Question¶

Do you have questions, suggestions or contributions? Feedback of any kind is more than welcome! Please use our project trackers.

Back to top

© Copyright 2009-2017 by Dominik Oepen and Frank Morgner.

vsmartcard-3.3/docs/.nojekyll0000644000175000017500000000000013546304763014760 0ustar philphilvsmartcard-3.3/docs/searchindex.js0000644000175000017500000017610213546304763016004 0ustar philphilSearch.setIndex({envversion:42,terms:{pezorform_security_oper:14,prefix:[6,8,0],stringtoint:[3,25],controlreferencetempl:[22,7],auf:19,crtl:30,shortdescript:[28,1,18,5],under:[24,9,14,7],digit:[22,24,18,1,28,14,5,7],everi:6,internet:6,counttestcas:[28,1,18,5],mutual_challeng:[24,9,14,7],vector:13,tlvutil:[3,15],verif:[22,8,24,2,14,7],repres:25,seper:6,direct:[30,14,7],second:[18,14,1,28,26,5],street:6,even:[18,14,1,28,26,5,3],"while":3,"new":[22,8,24,10,19,14,26,3,6,17,7],net:[6,2],newlist:26,here:[6,8,3,19,0],xff:3,studio:[6,21,2,0],path:[26,14,9,3,17],wdk:6,infoplist:6,currentef:[26,14],bitmask:[22,24,14,7],teardownclass:[28,1,18,5],powerup:[11,7,14,20,3,30],operation_on_str:13,forwar:0,shortfid:26,cfbundlesignatur:6,"_npa_se__eac_pace_step3":7,libeac:6,ord:3,middlewar:8,describ:6,epassport:24,tlv_data:12,call:[18,1,28,26,5,3],passport:[6,13,24,2,17],type:6,until:[9,14,24],successful:3,giovanni:19,"_cardgenerator__generate_epass":17,notif:8,inttostr:[3,25],warn:[6,3],berlin:19,warm:[20,30],relai:2,bertlv_unpack:12,killal:6,unpack:12,must:[22,8,24,17,18,0,28,14,13,1,5,6,26,21,3,7],springer:19,join:3,restor:[22,24,9,14,7],setup:[28,1,18,5],work:[6,8,3,0],failunlessequ:[28,1,18,5],assertisnon:[28,1,18,5],"05_":19,alioth:[6,8,20,0],root:6,"_unformat_hexdump":25,give:[6,3],sysconfdir:6,autodetect:[8,0],termin:[22,9,0,2,24,14,7],indic:[22,24,14,7],want:[8,2,3,19],generatecard:17,plist:6,end:[22,26,24,14,7],bund:8,how:[8,3,0],answer:[30,14,7],verifi:[22,8,9,2,24,14,6,7],config:[6,22,21,7,0],updat:[6,8,26,2,14],recogn:3,createfil:[26,14],perform_security_oper:[22,24,9,14,7],earlier:6,befor:[28,18,1,3,5],generate_public_key_pair:[22,24,9,14,7],parallel:6,besitz:19,util:[6,3,15],attempt:6,third:[30,14,7],local_ip:3,classmethod:[28,1,18,5],lost:3,perform:[22,8,24,30,14,20,7],maintain:30,environ:[22,24,0,9,14,7],enter:[9,14,24],order:[22,8,9,18,28,14,24,26,1,5,3,7],feedback:[8,0,2,27,6,21],over:[6,21,3,0],cyanogenmod:[21,2],fix:26,add_data:3,cla:[8,25],better:3,connecttoport:[30,3],complex:3,fid:[26,14,3],persist:17,sendcommandapdu:3,schmidt:19,them:[30,2],thei:[22,18,28,13,1,5,6],fragment:8,interrupt:8,echo:8,personalauswei:[19,10],choic:21,capdu:[22,24,9,14,30,7],smartphon:[19,21,2],each:[28,26,1,18,5],debug:[6,28,1,18,5],swutil:[3,15],store_s:[24,9,14,7],mean:[22,9,18,28,14,24,13,1,5,6,30,3,7],simpletlv_unpack:12,runtest:[28,1,18,5],network:[21,3],newli:26,currentdf:[26,14],content:[22,25,17,26,14,3,7],reader:2,expected_regexp:[28,1,18,5],dsa:[24,9,14,7],cipherspec:13,standard:[8,24,18,0,28,1,5,6,3],feature_execute_pac:8,kit:6,test_external_authent:5,convent:[30,14,7],traceback:30,ist:19,teardown:[28,1,18,5],atr:[14,30,3,7],render:[3,25],hook:[28,18,1,3,5],unlik:[28,1,18,5],alreadi:[22,7],system_profil:6,"__getrecord":26,"f\u00fcr":19,cardnumb:9,seekabl:[14,30,3,7],makethirdsoftwarefunctiont:[30,14,7],pkgconfig:0,master:[19,9,14,2,26,30,7],toolset:6,listen:0,"_recordstructureef__getrecord":26,tool:[6,8,27,0],technik:19,logginglevel:[30,3],establishpacechannel:8,vpcd:[21,0],assertisinst:[28,1,18,5],provid:[22,24,18,28,1,5,6,3,7],expr:[28,1,18,5],strip_pad:13,project:[8,19,2,27,0,6,21],close:[3,11],feature_modify_pin_direct:8,modern:[8,0],assertnotalmostequ:[28,1,18,5],raw:[22,24,14,7],seed:24,dataobjecthandlingdecodeencapsul:[26,14],getsocknam:3,cfbundledevelopmentregion:6,maxl:[14,3,7],"_npa_se__unpack_general_authent":7,transmit:[8,2,3,0],ulrich:19,sock_dgram:3,shall:[6,22,24,14,7],object:[22,9,17,18,25,28,1,24,26,14,5,30,3,7],deleg:[6,2,27],regular:[28,1,18,5],bsi:8,secondsft:[26,14],encipher:[22,24,14,7],"0x00000000":6,doi:19,doc:[6,26],doe:[6,24,3,0],tech:27,"__str__":25,random:[8,9,14,24],syntax:6,pkc:6,pkg:0,identifi:[24,0,26,2,9,14,7],pki:24,involv:26,despit:0,isequ:26,exactli:[28,1,18,5],efstructure_linear_variable_:3,holder:6,explain:0,configur:[8,21,2,0],than:[8,18,0,2,27,28,1,5,6,21],dfselectionbyfid:[26,14],recordidentifiersupport:[26,14],server_sock:3,stop:[6,30,3],esign_cert:[6,30,3,7],getreaderpacecap:8,assertrais:[28,1,18,5],report:[6,8,0],eid_pin:7,die_gesamte_technik_ist_sich:19,bar:21,"public":[22,19,9,24,14,6,7],bac:6,security_environ:[22,24,9,14,7],dg15:6,dg16:6,dg12:6,cfbundleexecut:6,"0x40":14,result:[22,24,18,28,1,12,26,14,5,30,3,7],respons:[22,8,9,25,0,11,14,2,27,24,26,3,6,30,17,7],fail:[28,18,1,3,5],themselv:19,foss:19,placeofbirth:6,best:[3,0],said:3,tlv_unpack:12,sigint:3,henryk:6,attribut:[18,25,14,1,28,26,5],accord:[22,24,26,14,30,3,7],extend:[6,19,3],f000000001:2,extens:27,erweiterung:19,restore_s:[24,9,14,7],histchar:[30,14,7],protect:[22,9,2,24,14,6,7],keycard:2,identifier_previ:26,against:[6,21,0],stuttgart:19,und:19,logic:26,countri:6,test_rapdu:28,com:[8,10,0,19,2,27,3,6,21],asctim:3,diff:[28,1,18,5],trust:[6,8,24,14,22],assum:3,nicer:[28,1,18,5],ottavi:6,been:[18,10,28,1,5,3],assertregexpmatch:[28,1,18,5],tizen:2,basic:[24,30],erasebinari:[26,14],numread:6,life:[26,14],lifo:[28,1,18,5],xxx:3,smartwatch:2,ani:[8,9,0,14,2,27,24,3,6,21,7],"0x18d1":6,craft:8,basiert:19,ident:[6,2,10],gnu:[6,8,0],servic:[6,27],properti:[26,25],sourceforg:[6,8,3,0],heidelberg:19,assertsetequ:[28,1,18,5],sln:6,aid:0,print_ascii:3,anchor:[6,22,24,14],keytyp:[24,9,14,7],kwarg:[28,1,18,25,5],conf:[6,3],make_properti:26,verify_cryptographic_checksum:[22,24,14,7],sever:[6,8,0],receiv:[11,30,3,0],suggest:[8,0,2,27,6,21],make:[6,8,25,0],format:3,keyref_is_puk:7,big:[22,14,24,3,7],complet:[18,0,28,1,5,6,3],hasfixedrecords:26,f276a288bcfba69d34f31001:2,searchbinaryplain:[26,14],rais:[18,14,1,28,26,5,3],assertmultilineequ:[28,1,18,5],c_apdu:25,xjf:8,"07_":19,fraunhof:19,client:8,putdataplain:[26,14],thi:[22,8,9,17,18,25,0,28,14,11,24,13,1,30,5,6,20,21,3,7,26],settimeout:3,protocol:[24,2,27,14,6,30,3,7],just:[28,30,1,18,5],photo:17,human:[28,1,18,5],ifdcap:6,previous:[22,24,3,7],"27th":19,els:3,expon:14,adress:25,wissen:19,applic:[8,0,2,27,6,30,21],get_challeng:[24,9,14,7],mayb:8,parse_statu:25,"_selectfil":[26,14],apart:19,measur:[28,1,18,5],daemon:6,specif:[9,18,1,24,28,14,5,3,7],"pl\u00f6tz":6,manual:[21,2,27],tuple1:[28,1,18,5],tuple2:[28,1,18,5],specifii:6,asserttupleequ:[28,1,18,5],www:[6,8,2,0],right:[24,9,14,7],old:[19,26],residencepermit2:6,residencepermit1:6,inact:6,successfulli:6,transmiss:[30,14,7],assertdictcontainssubset:[28,1,18,5],icc:24,tcp_port:6,esign_ca_cert:[6,30,3,7],subclass:[28,1,18,5],t15:[30,14,7],tracker:[8,0,2,27,6,21],unit:[26,14],ifdvendorid:6,localhost:6,core:8,plu:[28,1,18,5],verify_digital_signatur:[22,24,14,7],repositori:[8,19,2,0,6,21],zur:19,obj:[28,8,1,18,5],writebinaryencapsul:[26,14],decodeextendedheaderlist:12,posess:[24,9,7],algo:13,qrserver:3,produc:30,zum:19,encod:[6,22,3,7],down:[14,20,3,30,7],pair:[22,24,7],storag:[6,17],datasetfil:[6,30,3,17],accordingli:6,git:[8,19,2,27,0,6,21],a000000527210101:2,wai:6,cert:6,test_get_and_set_card:1,testnpacardgener:1,pace_mrz:7,avail:[8,0,14,2,26,3,19,6,21],gid:2,editor:19,form:[9,0,24,13,14,17,7],offer:19,datagroupvalu:6,"true":[18,25,14,1,28,26,5],reset:[9,30,11,26,24,14,20,3,7],lopensc:8,readernum:[30,3,11],decodeoffsetdataobject:12,deletefil:[26,14],intern:[22,24,9,14,7],testutil:28,russello:19,featur:19,decrypt:[24,26,9,13,14,7],smartcardfilesystem:[3,15],handlertest:[16,3,15],exist:[2,3,0],ship:[6,8,0],check:[8,9,18,14,24,28,1,5,6,3,7],encrypt:[26,9,14,24,13,3,17,7],warn_noinfo63:14,fukuchi:6,"_set_s":[22,24,14,7],tip:27,decive_unit:6,test:[8,0,2,3,15,6,21],issimpletlv:[26,14],shiguo:19,pbkdf2:6,szenario:19,pseudo:8,hashmethod:13,time:[6,8,3,0],disable_check:[30,3,7],"0x4ee1":6,skip:[28,1,18,5],global:[22,24,9,14,7],signific:[28,1,18,5],identifier_first:26,assertlessequ:[28,1,18,5],depend:[8,24,25,0,26,2,13,14,6,21],zone:24,decim:[28,1,18,5],readabl:[28,24,1,18,5],the_except:[28,1,18,5],x03:3,x02:3,x01:3,x00:13,isinst:[28,1,18,5],x04:3,sourc:[8,21,2,3,27],string:[22,8,9,18,25,0,28,14,12,13,1,30,5,6,26,3,7],addcleanup:[28,1,18,5],unfamiliar:[6,8,0],rdr_to_pc_datablock:8,cryptoutils_test:[29,3,15],brows:[19,21,2],gg487509:8,level:3,die:19,iter:[28,1,18,5],assertequ:[28,1,18,5],item:[28,26,1,18,5],vletoux:2,assertisnot:[28,1,18,5],droid:[21,2],pace_puk:7,sign:[6,22,24,14,7],unprotect:[22,24,9,14,7],scardtransmit:8,port:[6,30,3,0],codeproject:6,appear:8,docleanup:[28,1,18,5],current:[22,19,9,0,26,2,24,13,14,6,17,7],xml:[6,0],deriv:[24,3],honour:[28,1,18,5],gener:[22,9,17,18,25,0,28,14,2,24,13,1,5,6,26,21,3,7],agreement:[22,24,14,7],tcardemul:27,modif:[8,3],address:6,decipher:[22,24,14,7],do_someth:[28,1,18,5],wait:[6,0],box:8,writeor:26,checksum:[22,13,24,14,7],step:[6,7],"__repr__":25,seq2:[28,1,18,5],seq1:[28,1,18,5],"0x8c7b":[6,3],extra:[28,1,18,5],modul:[6,8,3,15,0],mobil:19,"0x60":14,epass:[6,16,3,15],err_incorrectparamet:3,univers:8,connector:[6,0],"_controlreferencetemplate__set_iv":[22,7],handler:30,msi:6,msg:[18,11,1,28,14,30,5,20,3,7],mse:22,msc:6,plug:6,club:19,a000000397425446590201:2,visual:[6,0],templat:[22,24,26,14,3,7],ifdversionnumb:6,kdir:8,tlv_find_tag:12,pretend:6,focu:6,descriptor:[26,14],whatev:25,purpos:[28,18,1,5,0],respsons:30,passportsam:24,openport:[30,3],chip:6,levelnam:3,simul:[2,27],occur:[26,14],verlag:19,multipl:[6,8,3],write:[26,14],"0x80":[22,24,14,7],expected_seq:[28,1,18,5],map:[14,3],product:[6,8],"m\u00fcller":19,max:[13,30,14,7],clone:[8,19,2,27,0,6,21],dataobjecthandlingdecodeplain:[26,14],usabl:[8,19],aid_list:0,mai:[22,9,0,2,27,24,13,14,6,7],data:[22,8,9,18,25,0,28,14,2,12,13,1,30,5,6,26,21,3,7,24],accessori:27,rapdu:[30,3],autotool:6,explicit:[28,1,18,5],inform:[22,19,9,26,24,14,7],"switch":[22,8,24,14,6,7],combin:[22,8,7,0],callabl:[28,1,18,5],"_passportsam__computekei":24,readbinaryplain:[26,14],still:[6,8,19,0],pointer:26,group:[6,3],ifdmanufacturerstr:6,platform:[8,0,2,27,6,21],window:[8,21,0],requir:[8,24,2,3,6,21],mail:6,main:[6,30,2,3,0],"0xe2":[26,14],"universit\u00e4t":19,ef_cardsecur:[6,30,3,7],initi:[22,8,24,26,2,27,13,3,6,7],nation:6,now:[8,9,0,24,14,6,7],discuss:[21,0],nor:[26,14],jump:6,term:6,name:[6,26,14,25,0],revers:[6,3],win32:6,compil:[8,0,2,27,6,21],replac:[22,9,26,24,14,6,7],dfselectionbyfulldfnam:[26,14],continu:10,manage_security_environ:[22,24,9,14,7],space:25,hce:[2,27],correct:[26,14,9,3,24],argz:[26,14],after:[28,1,18,5],failunlessalmostequ:[28,1,18,5],skiptest:[28,1,18,5],header_authent:[24,9,14,7],seutil:[3,15],"_npa_se__eac_pace_step2":7,org:[8,0,2,27,6,20,21],"byte":[22,9,25,26,24,14,30,3,7],"_npa_se__eac_pace_step1":7,"_npa_se__eac_pace_step4":7,actual_seq:[28,1,18,5],pc_to_rdr_secur:8,thing:[26,3],place:[6,28,1,18,5],support:[22,8,18,10,0,28,14,13,1,5,6,17,7],first:[18,28,1,26,14,5,6,3],oper:[22,24,18,0,28,1,13,14,5,26,7],directli:[6,0],arrai:6,yourself:[19,3],symmetri:[28,1,18,5],open:[6,21,2,3,30],size:[26,13,14],ioanni:19,given:[22,24,9,18,0,28,14,12,26,1,5,30,3,7],workaround:3,gertrud:6,caught:[28,1,18,5],citi:6,deciph:[22,24,14,7],fmd:[26,14],keyref_is_mrz:7,especi:[8,21,0],failifalmostequ:[28,1,18,5],dg21:6,specifi:[22,24,9,18,0,28,14,12,13,1,5,6,26,3,7],github:[8,10,19,2,27,0,6,21],mostli:3,"_cardgenerator__generate_iso_card":17,listread:3,simpletlv_data:[26,14],cardsecur:6,setupclass:[28,1,18,5],applet:2,oath:2,ifdproductstr:6,getcard:[3,17],sai:6,unprotected_result:[24,9,14,7],sam:[22,9,17,24,26,14,30,3,7],argument:[6,28,1,18,5],assertless:[28,1,18,5],sar:19,assertgreat:[28,1,18,5],test_internal_authent:5,inpterpret:3,"0x9e":[22,24,14,7],engin:19,"0x9a":[22,8,24,14,7],libpath:6,take:[9,18,28,1,24,26,14,5,7],noth:[22,24,14,7],begin:[26,14],sure:[6,3],normal:[18,1,28,14,5,3],buffer:3,cardgener:[3,15],err_wronglength:3,fci:[26,14],waldmann:19,mrz:[17,7],later:[6,14,3,0],runtim:2,salt:13,hmac:13,show:6,german:[6,21,2,10,0],permiss:[21,2],slot:6,onli:[26,8,24,18,0,28,14,13,1,5,3],activ:0,state:26,protect_respons:[22,24,14,7],dict:6,test_pad:18,erasebinaryencapsul:[26,14],variou:[22,8,24,19,13,14,7],get:[8,17,18,0,28,14,26,1,5,6,3],academictitl:6,ssc:[13,24],mmo11:19,"_virtualicc__recvfromvpicc":30,yield:6,telecommun:19,where:[8,0,26,3,6,21],wiki:8,kernel:8,maximum:[26,9,14,24],testcas:[28,1,18,5],dfname:[26,14],concern:[19,21,0],detect:21,expected_except:[28,1,18,5],handlertesto:[20,3],decodeheaderlist:12,between:[8,18,14,2,28,1,5,6,30,7],"import":[3,27],parent:[26,14,3],commandchaing:[30,14,7],cycl:[26,14],iso7816o:[14,30,3,7],come:3,readlin:6,bertlv_pack:12,apdu:[22,8,9,25,0,11,14,2,27,24,26,3,30,7],cryptoflexs:14,blocklen:13,cryptoflexo:[14,3],recordhandlingdecod:[26,14],mani:12,cfbundlenam:6,overview:[6,3],unittest:[28,1,18,5],period:6,dispatch:[9,30],encodefilecontrolparamet:[26,14],virtualicc:[30,3],save:6,hexdump:25,"_cardgenerator__generate_npa":17,invers:[30,14,7],certifc:6,workshop:19,vendor_ifd_typ:6,systemroot:6,andrea:19,updaterecordplain:[26,14],those:[28,18,1,3,5],dataunitsdecodeplain:[26,14],"case":[8,18,25,0,14,28,1,5,6,3],thesi:19,mount:8,sex:6,invok:[22,24,18,1,28,14,5,7],eid:19,assertsequenceequ:[28,1,18,5],assertnotisinst:[28,1,18,5],redlich:19,eras:[22,24,26,9,14,7],"return":[22,24,9,18,25,28,14,2,12,13,1,30,5,26,3,7],bixvread:6,"__init__":3,develop:[21,2,27,10,0],readrecord:[26,14],seq_typ:[28,1,18,5],media:19,intermediari:8,same:[18,28,1,5,6,3],enciph:[22,24,14,7],binari:[6,26,14,25],html:[8,19,2,6,20,21],pad:[22,13,24,14],lite:[6,20,0],card_typ:[17,30,1,3],"_getdata":25,rfid:0,driver:[6,8,20,21],capabl:[26,30,14,7],extern:[6,22,24,14,7],identifier_next:26,libexec:6,appropri:[22,24,14,27,7],ykneo:2,cct:22,channelid:6,without:[8,18,25,28,2,13,1,5,6],crypt:13,ccc:19,execut:[18,11,14,28,1,30,5,6,20,3,7],when:[18,25,0,28,1,5,6,30,21,3],test_counter_decr:5,rest:3,religiousartisticnam:6,datacod:26,except:[18,28,1,4,5,3],littl:3,maxrecords:[26,3],blob:2,exercis:28,mor12:19,real:[6,8,3,11,0],around:0,read:[24,17,26,14,6,3],prettyprint_anyth:26,neuen:19,neuer:10,world:2,integ:[26,14],authentisierung:19,either:[22,24,26,2,14,7],updaterecordencapsul:[26,14],manag:[18,28,1,5,6,3],what:[22,24,0,26,14,3],communityid:6,putdata:[26,14],pythonwar:6,assertionerror:[28,1,18,5],ifd:6,fsencrypt:[24,9,14,7],exit:[6,8,3,0],tr03119:8,pace_can:7,tdi:[30,14,7],power:[14,20,3,30,7],quit:3,inspect:[28,1,18,5],calculate_mac:13,dataunitsdecodeencapsul:[26,14],writerecord:[26,14],"throw":3,bitstr:[30,14,7],src:[8,2,0],x38:3,mutual_authent:[24,9,14,7],wolf:19,act:[6,3],other:[6,8,21],routin:6,elementari:26,morgner:[8,19,0],getatr:[11,7,14,20,3,30],set_asym_algorithm:[24,9,14,7],strip:13,your:[8,0,2,27,3,6,21],compon:8,sicher:19,log:3,openmoko:[6,8,0],overwrit:[3,25],start:[6,8,26,0],interfac:[8,2],extended_length:30,unam:8,tupl:[18,14,12,1,28,26,5],bundl:6,regard:[26,14],cryptograph:[22,13,24,14,7],getdata:[26,14],qrencod:6,possibl:[6,8,2,0],"default":[8,18,0,28,1,5,6],decodediscretionarydataobject:12,firstsft:[26,14],connect:[11,2,0,3,6,30,21],cbc:13,scanner:21,eraserecord:[26,14],deem:[28,1,18,5],file:[8,9,0,14,2,26,3,6,30,21,17,7],fill:17,googl:0,prepend:[26,13,14],field:[22,24,14,7,25],valid:[9,18,14,24,28,1,5,6,3,7],wixtoolset:6,you:[8,18,0,28,14,2,27,26,1,19,5,6,21,3],string2:13,string1:13,tlv:[22,24,14,12,26,7],congress:19,annex:24,sequenc:[24,18,13,28,1,5],rpc_type:6,docstr:[28,26,1,18,5],gidsapplet:2,"_baseassertequ":[28,1,18,5],directori:[6,8,3],descript:[28,1,18,5],to_str:[22,7],mass:6,dst:22,openpac:6,represent:26,all:[22,24,9,18,0,28,14,12,26,1,5,6,21,3,7],technischerichtlinien:8,"0x9000":8,recordpoint:26,lian:19,follow:[8,0,14,2,26,3,19,6,21],disk:[3,17],edg:[6,8,0],af_inet:3,articl:6,init:[6,8,2],program:[6,19,3],far:6,icao:[13,24,17],mechan:[22,24,14,7],failur:[28,1,18,5],feature_verify_pin_direct:8,list:[8,18,0,28,14,12,26,1,5,6,3],"0x0d46":8,smartcardsam:[3,15],adjust:[22,24,7],"7_win32":6,yubico:2,zero:[9,18,1,24,28,14,5],design:3,pass:[30,3],dfselectionbyapplication_implicit:[26,14],xor:26,sun:0,section:[3,0],abl:[6,27,17],dateofbirth:6,pcsc_scan:6,version:[8,9,0,2,27,24,14,6,21,7],consecut:25,method:[22,9,18,1,24,28,14,5,17,7],full:[21,25,0],hash:[22,13,24,14,7],crypto_checksum:13,num_id:26,test_security_environ:5,modifi:[22,8,3,7,0],valu:[22,9,18,25,0,28,14,24,26,1,5,6,30,7],search:[26,14],surpress:30,"_controlreferencetemplate__set_kei":[22,7],testcryptoutil:18,social:19,updatebinaryplain:[26,14],"_npa_se__pack_general_authent":7,via:[8,9,0,11,2,27,13,3,6,30,21],default_s:[9,7],filenam:8,fsdecrypt:[24,9,14,7],decrement:[9,14,24],establish:[6,21],select:[0,26,2,27,13,14,30,21,3,7],pyreadlin:6,regist:[18,0,27,28,1,5,6,3],two:[18,14,1,28,26,5],taken:6,dummy_hcd:8,more:[22,8,24,18,0,2,27,28,1,5,6,21,3,7],tester:[6,20],eraseto:26,building_gadget_usb_modul:8,sigkil:6,"_setbyt":25,forwared:8,none:[26,24,9,17,18,25,28,14,12,13,1,5,30,3,7],updaterecord:[26,14],dev:[6,8],den:19,def:3,eriknellessen:2,prompt:17,scan:[21,2,3],"_addskip":[28,1,18,5],challeng:[24,9,14,7],accept:[28,1,18,5],acardemul:[2,0],explor:6,updatebinaryencapsul:[26,14],test_capdu:28,iso7816:[6,1,3],testresult:[28,1,18,5],secur:[22,8,9,19,14,24,3,6,30,7],anoth:8,qes_pin:7,iso:[6,2,0],simpl:[26,14,2,3],referenc:[24,9,14,7],assertlistequ:[28,1,18,5],openpicc:0,helloworldapplet:2,associ:[22,24,7],signfic:[28,1,18,5],"short":[26,25],encodebertlvdatalist:12,cardtyp:3,appendrecord:[26,14],help:[6,8,0],compute_digital_signatur:[22,24,14,7],pseudorandom:13,through:[6,8,2],reconnect:3,keyref_is_can:7,suffer:[28,1,18,5],paramet:[22,9,18,28,14,24,13,1,30,5,26,7],style:[28,1,18,5],recordnumbersupport:[26,14],might:[24,14,9,3,7],pcd:[6,30,3],assertitemsequ:[28,1,18,5],extendedl:[30,14,7],gadget:8,framework:6,ins2handl:[30,14,7],cfbundlevers:6,instruct:[26,14],authent:[22,24,9,14,7],"_controlreferencetemplate__set_algo":[22,7],mingw:0,"27c3":19,found:[28,18,1,3,5],standardmsg:[28,1,18,5],unequ:[28,1,18,5],libpcsclit:6,expect:[28,18,1,3,5],bertlv:12,virtualsmartcard:[6,3],angriff:19,einem:19,failifequ:[28,1,18,5],"0xac":[22,24,14,7],publish:6,research:19,print:[8,0,3,6,30,21],"_cardgenerator__generate_cryptoflex":17,foreground:0,puk:[24,9,14,7],with_mark:12,krontiri:19,differ:[22,19,24,18,28,17,13,1,5,6,3,7],reason:[28,1,18,5],base:[22,8,9,18,25,0,11,14,2,24,28,26,1,30,4,5,20,17,7],put:[26,14],dfselectionbypartialdfnam:[26,14],cyberflex:[6,13],mmc:6,basi:[28,1,18,5],omit:[18,1,28,14,5,30,7],round:[28,1,18,5],"0xa4":[26,14,3],assign:[26,25],humboldt:19,propertylist:6,"_makesalt":13,number:[8,9,18,0,28,14,24,26,1,5,6,3,7],done:[3,0],dylib:6,qrcode:3,stabl:6,miss:[6,8,0],gpl:[8,0,2,27,6,21],guess:6,mobilen:19,smartcardo:[11,7,14,20,3,30],script:6,interact:17,jen:19,store:[22,24,9,14,7],option:[8,18,0,28,14,13,1,5,6,30,17,7],selectfil:[26,14],part:[6,19,26],pars:[22,9,25,24,14,3,7],readdatagroup:[3,17],esign:6,utils_test:[29,3,15],kind:[22,8,24,0,2,27,14,6,21],callableobj:[28,1,18,5],cyclic:26,remot:[2,0],remov:[22,26,24,14],get_index:26,dtd:6,issuingst:6,keyref_is_pin:7,str:[3,25],randomli:6,comput:[22,19,24,2,13,14,6,21,7],extra_fci_data:26,packag:3,do_encrypt:13,dedic:26,"null":6,cvca:[6,30,3,7],bz2:8,lib:[6,8,0],self:[28,18,1,3,5],also:[8,0,14,2,27,26,3,6,17],callable_obj:[28,1,18,5],build:[8,21,2,0],vsmartcard:[8,19,2,27,0,6,21],get_referenced_ciph:9,bixvreaderinstal:6,distribut:0,om11:19,spusbdatatyp:6,choos:[6,21,2,27,0],most:[8,18,0,12,28,1,5,3],maco:6,assignlogicalchannel:[30,14,7],resp_data:24,filesystem:[24,9,14,17,7],cover:[6,0],newvalu:[26,12],esign_kei:[30,3,7],microsoft:[6,8,0],session:3,"_getsw":25,find:[6,8,3,12,0],impact:[21,0],firewal:3,pretti:3,solut:6,simpletlv_pack:12,iec:0,documenttyp:6,openpcd:0,ifdread:6,express:[28,1,18,5],parse_se_config:[22,7],nativ:0,restart:6,keyword:[28,1,18,5],crt:[22,24,7],"_getassertequalityfunc":[28,1,18,5],d2760001240102000000000000010000:2,certif:[6,22,24,14,27],set:[22,24,18,0,28,1,26,14,5,6,30,17,7],dump:25,startup:6,default_uid:8,methodnam:[28,1,18,5],atexit:3,see:[8,30,0,14,26,3,6,20,7],arg:[18,25,28,1,26,14,4,5,30,3,7],pcsc:[6,0],someth:6,opensc_lib:8,ca_kei:[6,30,3,7],subdir:8,linelen:25,altern:[6,8,19,0],signatur:[6,22,24,14,7],ef_cardaccess:[6,30,3,7],compute_cryptographic_checksum:[22,24,14,7],both:[28,8,1,18,5],informatik:19,last:[26,13,14],someexcept:[28,1,18,5],unexpected_regexp:[28,1,18,5],dlitz:6,context:[28,18,1,3,5],pdf:19,load:[6,8,3],simpli:[6,3],"_handlertestos__output_from_l":20,point:26,ubuntu:[6,8,0],header:[22,8,24,0,14,7],param:26,"_truncatemessag":[28,1,18,5],backend:0,java:2,devic:[6,8,2],ifdprotocolsupport:6,secret:[24,13,9,14,7],"0xb2":[26,14],"0xb3":[26,14],"0xb0":[26,14],"0xb1":[26,14],test_card_cr:1,imag:6,vendor_nam:6,hassimpletlv:26,winscard:0,testsmartcardsam:5,look:[8,19,26,2,0,3,6],"0xbc":[22,24,14,7],straight:3,histor:[26,30,14,7],pace:[6,8,2],dominik:[19,0],abov:6,error:[8,18,28,14,26,1,5,3],sw1:[8,3,25],sw2:[8,3,25],fixtur:[28,1,18,5],loop:30,pack:12,writeand:26,itself:3,getdataencapsul:[26,14],decor:26,familynam:6,x64:6,recordstructureef:[26,3],"0x8e":[22,24,14,7],decod:[26,14],test_incorrect_pin:5,x82:6,optim:[28,1,18,5],wherea:8,sym:22,user:[9,24,14,6,30,17],"_setsw":25,chang:[8,9,0,24,14,6,7],recent:8,equival:[28,1,18,5],older:[6,8,19,0],entri:8,momr12:19,custom_url:3,iscycl:26,lastcommandsw:3,informat:19,input:13,recalculate_length:12,bin:6,vendor:[6,8],transpar:26,bertlv_data:[26,14],pace_pin:7,index_curr:[26,14],bix:6,assertfals:[28,1,18,5],bit:[26,13,14],basicconfig:3,nofurtherinfo:3,reader0:6,reader1:6,reader2:6,signal:[30,3],collect:[28,1,18,5],givennam:6,modprob:8,some:[8,3,19],back:[11,30,3,27,0],understood:9,sampl:2,"_deprec":[28,1,18,5],updatebinari:[26,14],assertnotequ:[28,1,18,5],publikationen:8,prop:[26,25],informationstechnologi:19,licel:2,retri:[9,14,24],"_controlreferencetemplate__replace_tag":[22,7],machin:[6,8,24],previou:[26,14],run:[8,21,2,0],"_format_field":25,word:25,sm_header:[22,24,14,7],signalhandl:[30,3],"\u00ecnfo":6,output:6,requestedtl:[26,14],readrecordplain:[26,14],memori:[24,9,14,7],newtlvlist:[26,14],dialog:27,block:[13,9,3,14,24],directconvent:[30,14,7],ensur:6,ifdproductid:6,cfbundleinfodictionaryvers:6,institut:19,ff557573:6,sock:3,"long":[26,14,3,0],custom:8,epass_s:24,"0xca":[26,14],includ:[22,19,9,18,0,14,2,27,24,28,1,5,6,3,7],"0xcb":[26,14],forward:[8,30,3,11],getrespons:[30,14,7],tradit:[6,21],fabio:6,doctyp:6,assertnotin:[28,1,18,5],pwd:8,"0x00000001":6,link:6,newer:[21,2],delta:[28,1,18,5],line:[8,18,25,28,1,5,6],sdk:[21,2,27],info:[6,8,3],fdid:[21,2],fdb:3,utf:6,assertisnotnon:[28,1,18,5],libifdvpcd:6,get_cipher_blocklen:13,chao:19,lectur:19,verify_certif:[22,24,14,7],effective_l:25,incomplet:6,get_ciph:13,frankmorgn:[8,10,19,2,27,0,6,21],titl:0,sequenti:26,invalid:[6,14,9,3,24],handler_test:[6,20,3],nice:25,"_make_byte_properti":25,asserttru:[28,1,18,5],libccid:8,vicc:[6,30,3,0],algorithm:[22,9,24,13,14,7],"_classsetupfail":[28,1,18,5],hello:2,code:[22,8,24,25,0,14,2,12,26,3,6,21,7],partial:[26,14],hashmap:9,"_formatmessag":[28,1,18,5],birthnam:6,pcsclite:[6,8,20,0],privat:[22,9,24,14,6,7],jcardsim:2,send:[22,24,11,14,0,27,13,3,30],cfbundlepackagetyp:6,sent:[3,0],unverifi:6,libopensc:8,w64:0,mous:6,electron:[6,2,10],volum:19,implicitli:3,"_deldata":25,tri:6,magic:3,smartcardsam_test:[29,3,15],"try":[19,3],getstatu:25,maxsiz:26,pleas:[8,0,2,27,6,21],writebinari:[26,14],assertdictequ:[28,1,18,5],odd:[26,14],click:6,append:[22,13,26,14,7],compat:8,index:[9,18,0,28,1,26,14,5],compar:[28,14,1,18,5],access:[22,8,9,10,0,2,24,14,6,30,21,7],pwendland:2,can:[8,18,0,11,14,2,28,26,1,19,5,6,21,3,7],eac_step:7,gesamt:19,len:[14,30,3,7],let:3,filedescriptor:[26,14,3],establishpacechannelinput:8,sinc:[6,8],authenticate_head:[22,24,14,7],erase_s:[24,9,14,7],copyright:6,autoreconf:[6,8,0],headless:27,cardgenerator_test:[29,3,15],implement:[6,8,2],honor:26,new_fil:3,app:[0,2,27,3,6,21],submodul:[6,8,2,27],apt:8,api:[6,3],regexp:[28,1,18,5],wix:6,from:[22,19,9,17,18,0,11,14,2,27,24,28,26,1,5,6,30,21,3,7],zip:6,commun:[19,0,2,27,3,6,30,21],doubl:6,next:[26,14,27,7],encodedataoffsetobject:12,readrecordencapsul:[26,14],chr:3,camera:[21,2],usr:[6,8],chv:[24,9,14,7],makesecondsoftwarefunctiont:[26,14],secondsoftwar:[26,14],comparison:[28,1,18,5],"_npa_se__eac_ca":7,unplug:6,actual:[18,11,0,28,1,5,21,3],retriev:[24,9,14,7],alia:[28,1,18,5],onetimewrit:26,endian:3,cardsecret:9,fetch:[27,21,2,3],control:[22,26,24,14,7],tar:8,process:[2,27,0],sudo:[6,8],calcul:[24,0,13,14,30,7],tag:[22,24,14,12,26,7],proprietari:[6,8,26],serial:[6,8],tai:[30,14,7],taj:[30,14,7],original_func:[28,1,18,5],"0xd0":[26,14],"0xd1":[26,14],"0xd2":[26,14],remotesmartcardread:[21,2],"0xd6":[26,14],"0xd7":[26,14],six:22,sig:30,instead:[18,25,2,28,1,5,6],msdn:[6,8],npa:2,maximumchannel:[30,14,7],protect_result:[24,9,14,7],assert_:[28,1,18,5],bndl:6,physic:[3,11],derive_kei:24,erasebinaryplain:[26,14],"_get_referenced_kei":[24,9,14,7],sit:19,asserti:[28,1,18,5],correspond:[9,3],element:[6,28,1,18,5],issu:[6,8,0],"0xda":[26,14],"0xdb":[26,14],"0xdc":[26,14],"0xdd":[26,14],allow:[18,0,2,27,28,1,5,6,21],datefmt:3,failunless:[28,1,18,5],insight:3,chipkartenles:19,"_diffthreshold":[28,1,18,5],cryptoutil:[3,15],addtypeequalityfunc:[28,1,18,5],chosen:6,npa_at_crt:7,isoapplet:2,therefor:17,"0xxx":3,handl:[26,14,3],handi:19,index_htm:8,get_cipher_keylen:13,nfc:[19,0,2,3,6,21],rfu:[24,9,14,7],edit:3,swerror:[3,4],mode:[22,8,9,0,13,3,6,21],dateofexpiri:6,scardcontrol:8,decodetaglist:12,subset:8,establishpacechanneloutput:8,failif:[28,1,18,5],meta:25,"static":[26,24,14,30,7],our:[8,25,10,0,19,2,27,3,6,21],patch:8,simpletlv:12,special:[8,21],out:[8,3],variabl:26,suitabl:13,hardwar:[6,8,21,2,0],ref:26,insmod:8,umbrella:19,frank:[8,19,0],manipul:[22,24,14,7],standalon:6,getpath:[26,14],dictionari:[22,7],usual:[8,18,26,28,1,5,6,3],releas:[6,8,19,0],"_setdata":25,linuxtag:19,bleed:[6,8,0],relayo:[3,11],indent:[26,25],keep:[28,1,18,5],counterpart:8,length:[22,18,25,28,14,12,13,1,5,26,3,7],enforc:[28,1,18,5],softwar:[0,26,14,6,30,21,3,7],padding_class:13,smartcard:[19,11,26,3,6,30,21],general_authent:7,list1:[28,1,18,5],list2:[28,1,18,5],wudfhost:6,dfselectionbypath:[26,14],readbinari:[26,14],unknown:[26,14,3],licens:[8,0,2,27,6,21],mkdir:8,system:[8,9,19,0,3,6,21],messag:[22,9,18,28,14,24,13,1,4,5,6,30,3,7],attach:[21,2,27],attack:[11,21,3,0],privaci:19,readbinaryencapsul:[26,14],longmessag:[28,1,18,5],shell:6,gear:27,deconstruct:[28,1,18,5],failunlessrais:[28,1,18,5],rsa:[24,9,14,7],udc:8,nobodi:24,datatyp:[28,1,18,5],makeatr:[30,14,7],makefirstsoftwarefunctiont:[26,14],structur:[26,12],charact:[30,14,7],ber:[26,14],counter:[9,18,28,14,24,13,1,5],r_apdu:[3,25],session_kei:13,have:[8,18,0,19,2,27,28,1,5,6,21,3],tabl:[22,24,14,26,30,7],need:[8,9,18,0,14,2,27,24,28,1,5,6,21,3,7],oepen:[19,0],sicherheitsanalys:19,set_mf:[24,9,14,7],cryptoflexgeneratortest:1,npao:[3,7],min:3,"0x04":[8,3],"0x00":[22,24,3,7],"0x01":[8,3],"0x02":[8,3],"0x03":8,"0x3010":8,identifier_last:26,which:[22,18,25,0,28,14,2,13,1,5,6,26,3,30],"_recordstructureef__getrecordsbynumb":26,pkg_config_path:0,powerdown:[11,7,14,20,3,30],unless:[28,1,18,5],firstsoftwar:[26,14],assertalmostequ:[28,1,18,5],cipher:[24,13,9,14,7],kitkat:[21,2],deploi:[21,2,27],transparentstructureef:[26,14,3],cryptoflexmf:[14,3],"class":[22,9,17,18,25,11,28,14,24,26,1,30,5,20,3,7],prove:[24,9,7],"0xe0":[26,14],"0xe4":[26,14],url:[6,19],request:[6,19,26,3],pipe:[6,8],determin:[28,1,18,5],"0x0e":[26,14],"0x0f":[26,14],reset_retry_count:7,test_readdatagroup:1,"0x0c":[26,14],text:[28,14,1,18,5],verbos:[6,8,0],elif:3,bring:6,anywai:[6,24],setter:[24,9,14,7],locat:[8,19,0],destroypacechannel:8,ducktyp:[28,1,18,5],should:[22,8,24,18,0,28,14,26,1,5,6,3,7],local:[6,8],contribut:[8,0,2,27,6,21],typeobj:[28,1,18,5],cryptoflexsam:14,libqrencod:6,pypi:6,tbi:[30,14,7],pc_to_rdr_xfrblock:8,tbj:[30,14,7],enabl:[6,8,19,0],integr:[6,10],contain:[22,9,18,28,1,24,26,14,5,6,7],devmgmt:6,cardaccess:6,putdataencapsul:[26,14],datalist:[26,12],frame:30,knowledg:3,append_pad:13,refdataobj:26,gmail:8,statu:[26,8,14,25],thehistor:[26,14],correctli:[9,14,7],pattern:[28,1,18,5],written:[8,0],cardconnectionexcept:3,neither:[26,14],email:6,get_card_numb:[24,9,14,7],kei:[22,9,14,24,13,3,6,7],parse_sm_capdu:[22,24,9,14,7],entir:3,disconnect:3,addit:0,g_ether:8,resetrecordpoint:26,datagroupnam:6,equal:[9,18,28,1,24,26,14,5],etc:[6,3],asym:22,instanc:[26,12],internal_authent:[24,9,14,7],npa_sam:7,formatresult:[14,30,3,7],walk:26,respect:3,num_result:12,"_recordstructureef__getrecordsbyidentifi":26,encodediscretionarydataobject:12,creat:[6,8],searchbinaryencapsul:[26,14],datagroup:17,include_fil:12,immedi:[28,1,18,5],mrtd:[6,24],assertnotregexpmatch:[28,1,18,5],assert:[28,1,18,5],togeth:[2,0],openpgp:2,present:8,tagungsband:19,multi:[28,1,18,5],erasefrom:26,plain:[22,24,9,14,7],assertraisesregexp:[28,1,18,5],defin:[8,9,24],"_virtualicc__sendtovpicc":30,efstructure_transpar:3,ini:6,layer:6,almost:[28,1,18,5],incom:[6,0],"7_3":19,scienc:19,welcom:[8,2],cross:0,member:[28,1,18,5],constantdefinit:[3,15],set1:[28,1,18,5],set2:[28,1,18,5],umdf:6,contactless:2,http:[8,10,0,19,2,27,3,6,20,21],hostnam:[6,3,0],writebinaryplain:[26,14],shortfidsupport:[26,14],php:0,setcard:17,efstructure_linear_fixed_:3,off:[8,3],well:6,"0x10":8,exampl:[6,8,0],command:[22,8,9,30,25,0,11,14,2,27,24,26,3,6,20,7],english:6,error_cod:[28,1,18,5],umfeld:19,latest:[6,8,19,0],distanc:0,tcp:[6,26,14],des3:13,tcj:[30,14,7],tck:[30,14,7],tci:[30,14,7],web:19,superset:[28,1,18,5],ifdfriendlynam:6,makefil:8,add:[22,8,18,0,28,1,5,3,7],cleanup:[18,11,28,1,5,3],getdataplain:[26,14],match:[18,0,1,28,26,5,6],futur:[24,9,14,7],efstructure_cyclic_nofurtherinfo:3,piec:26,built:[6,21,2,0],realiz:0,know:[6,3],press:30,recurs:[6,26],insert:0,like:[6,8,0],success:[9,18,1,24,28,14,5,7],mo10:19,unord:[28,1,18,5],necessari:0,"0xff":[8,30,3,14,7],pariti:24,failureexcept:[28,1,18,5],home:10,peter:19,librari:[],tmp:[8,0],guid:[19,27],lead:6,avoid:3,cryptoflex:[6,16,3,17,15],"_format_part":25,importerror:3,nellesson:2,"enum":0,dcb:[26,14],host:[8,0,2,3,6,30,21],mitm:[3,11],although:6,offset:[26,14,12,25],pyscard:[6,3],about:[6,3],getfile_byrefdataobj:26,socket:[6,30,2,3],assertin:[28,1,18,5],friendlynam:6,lifecycl:[26,14],fals:[18,25,28,14,12,26,1,5,6,30,3,7],disabl:6,own:[18,2,27,28,1,5,6],change_reference_data:[24,9,14,7],automat:[18,1,28,14,5,6,30,7],dataset:[6,3],normal_rest:3,pacecap:8,appl:6,"function":[26,19,9,18,25,10,28,14,24,13,1,5,30,3,7],iso7816generatortest:1,unexpect:[28,1,18,5],eac:[6,7],oep10:19,bug:[6,8,3,0],count:[28,1,18,5],whether:[22,9,18,1,24,28,14,5,30,7],record:[26,3],below:[6,0],devicenam:6,pcscd:[6,3],seid:[22,24,9,14,7],maxdiff:[28,1,18,5],otherwis:[22,18,0,28,1,26,14,5,7],problem:6,devices_compatibility_matrix:0,smartcardservic:6,pil:6,pin:[8,9,2,14,24],"int":[8,0],erik:2,probabl:[6,8,0],detail:[18,28,1,5,6,3],virtual:2,expr2:[28,1,18,5],expr1:[28,1,18,5],bool:[26,30,14,7],defaulttestresult:[28,1,18,5],npa_s:7,external_authent:[24,9,14,7],debian:[6,8,20,0],stai:0,lastcommandoffcut:3,assertgreaterequ:[28,1,18,5],pycrypto:6,samsung:27,excclass:[28,1,18,5],dg14:6,auxiliari:[6,8,0],applicationidentifi:[26,14]},objtypes:{"0":"py:module","1":"py:method","2":"py:class","3":"py:staticmethod","4":"py:attribute","5":"py:classmethod","6":"py:function","7":"py:exception"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","class","Python class"],"3":["py","staticmethod","Python static method"],"4":["py","attribute","Python attribute"],"5":["py","classmethod","Python class method"],"6":["py","function","Python function"],"7":["py","exception","Python exception"]},filenames:["pcsc-relay/README","virtualsmartcard/api/virtualsmartcard.tests.CardGenerator_test","ACardEmulator/README","virtualsmartcard/api","virtualsmartcard/api/virtualsmartcard.SWutils","virtualsmartcard/api/virtualsmartcard.tests.SmartcardSAM_test","virtualsmartcard/README","virtualsmartcard/api/virtualsmartcard.cards.nPA","ccid/README","virtualsmartcard/api/virtualsmartcard.SmartcardSAM","npa/README","virtualsmartcard/api/virtualsmartcard.cards.Relay","virtualsmartcard/api/virtualsmartcard.TLVutils","virtualsmartcard/api/virtualsmartcard.CryptoUtils","virtualsmartcard/api/virtualsmartcard.cards.cryptoflex","virtualsmartcard/api/virtualsmartcard","virtualsmartcard/api/virtualsmartcard.cards","virtualsmartcard/api/virtualsmartcard.CardGenerator","virtualsmartcard/api/virtualsmartcard.tests.CryptoUtils_test","index","virtualsmartcard/api/virtualsmartcard.cards.HandlerTest","remote-reader/README","virtualsmartcard/api/virtualsmartcard.SEutils","virtualsmartcard/api/virtualsmartcard.ConstantDefinitions","virtualsmartcard/api/virtualsmartcard.cards.ePass","virtualsmartcard/api/virtualsmartcard.utils","virtualsmartcard/api/virtualsmartcard.SmartcardFilesystem","TCardEmulator/README","virtualsmartcard/api/virtualsmartcard.tests.utils_test","virtualsmartcard/api/virtualsmartcard.tests","virtualsmartcard/api/virtualsmartcard.VirtualSmartcard"],titles:["PC/SC Relay","CardGenerator_test Module","Android Smart Card Emulator","Creating a Virtual Smart Card","SWutils Module","SmartcardSAM_test Module","Virtual Smart Card","nPA Module","USB CCID Emulator","SmartcardSAM Module","nPA Smart Card Library","Relay Module","TLVutils Module","CryptoUtils Module","cryptoflex Module","virtualsmartcard Package","cards Package","CardGenerator Module","CryptoUtils_test Module","Welcome to the Virtual Smart Card Architecture documentation!","HandlerTest Module","Remote Smart Card Reader","SEutils Module","ConstantDefinitions Module","ePass Module","utils Module","SmartcardFilesystem Module","Tizen Smart Card Emulator","utils_test Module","tests Package","VirtualSmartcard Module"],objects:{"virtualsmartcard.VirtualSmartcard.VirtualICC":{run:[30,1,1,""],"_VirtualICC__recvFromVPICC":[30,1,1,""],openPort:[30,3,1,""],stop:[30,1,1,""],connectToPort:[30,3,1,""],signalHandler:[30,1,1,""],"_VirtualICC__sendToVPICC":[30,1,1,""]},"virtualsmartcard.cards.nPA.NPAOS":{reset:[7,1,1,""],execute:[7,1,1,""],mf:[7,4,1,""],SAM:[7,4,1,""],makeATR:[7,3,1,""],getATR:[7,1,1,""],makeThirdSoftwareFunctionTable:[7,3,1,""],getResponse:[7,1,1,""],powerUp:[7,1,1,""],seekable:[7,3,1,""],formatResult:[7,1,1,""],powerDown:[7,1,1,""]},"virtualsmartcard.tests.utils_test":{TestUtils:[28,2,1,""]},"virtualsmartcard.cards.cryptoflex.CryptoflexMF":{selectFile:[14,1,1,""],getDataEncapsulated:[14,1,1,""],currentDF:[14,1,1,""],decrypt:[14,1,1,""],firstSFT:[14,4,1,""],dataObjectHandlingDecodeEncapsulated:[14,1,1,""],select:[14,1,1,""],dfname:[14,4,1,""],updateRecordEncapsulated:[14,1,1,""],"_selectFile":[14,1,1,""],currentEF:[14,1,1,""],deleteFile:[14,1,1,""],append:[14,1,1,""],content:[14,4,1,""],encrypt:[14,1,1,""],readRecordPlain:[14,1,1,""],eraseBinaryPlain:[14,1,1,""],create:[14,3,1,""],dataUnitsDecodeEncapsulated:[14,1,1,""],lifecycle:[14,4,1,""],current:[14,4,1,""],putDataPlain:[14,1,1,""],fid:[14,4,1,""],bertlv_data:[14,4,1,""],writeRecord:[14,1,1,""],makeSecondSoftwareFunctionTable:[14,3,1,""],getDataPlain:[14,1,1,""],updateBinaryPlain:[14,1,1,""],simpletlv_data:[14,4,1,""],dataUnitsDecodePlain:[14,1,1,""],parent:[14,4,1,""],readbinary:[14,1,1,""],updatebinary:[14,1,1,""],createFile:[14,1,1,""],dataObjectHandlingDecodePlain:[14,1,1,""],getpath:[14,1,1,""],putDataEncapsulated:[14,1,1,""],searchBinaryPlain:[14,1,1,""],appendRecord:[14,1,1,""],readBinaryPlain:[14,1,1,""],filedescriptor:[14,4,1,""],readRecordEncapsulated:[14,1,1,""],erasebinary:[14,1,1,""],getdata:[14,1,1,""],data:[14,4,1,""],updateRecordPlain:[14,1,1,""],recordHandlingDecode:[14,1,1,""],makeFirstSoftwareFunctionTable:[14,3,1,""],putdata:[14,1,1,""],eraseRecord:[14,1,1,""],encodeFileControlParameter:[14,3,1,""],readBinaryEncapsulated:[14,1,1,""],writeBinaryEncapsulated:[14,1,1,""],writerecord:[14,1,1,""],updaterecord:[14,1,1,""],writeBinaryPlain:[14,1,1,""],remove:[14,1,1,""],eraseBinaryEncapsulated:[14,1,1,""],readrecord:[14,1,1,""],appendrecord:[14,1,1,""],updateBinaryEncapsulated:[14,1,1,""],secondSFT:[14,4,1,""],writebinary:[14,1,1,""],searchBinaryEncapsulated:[14,1,1,""]},"virtualsmartcard.VirtualSmartcard.SmartcardOS":{reset:[30,1,1,""],powerDown:[30,1,1,""],powerUp:[30,1,1,""],execute:[30,1,1,""],getATR:[30,1,1,""]},"virtualsmartcard.VirtualSmartcard":{SmartcardOS:[30,2,1,""],Iso7816OS:[30,2,1,""],VirtualICC:[30,2,1,""]},"virtualsmartcard.SmartcardFilesystem.File":{simpletlv_data:[26,4,1,""],putdata:[26,1,1,""],encrypt:[26,1,1,""],parent:[26,4,1,""],readbinary:[26,1,1,""],updatebinary:[26,1,1,""],erasebinary:[26,1,1,""],decrypt:[26,1,1,""],getpath:[26,1,1,""],lifecycle:[26,4,1,""],readrecord:[26,1,1,""],appendrecord:[26,1,1,""],bertlv_data:[26,4,1,""],fid:[26,4,1,""],filedescriptor:[26,4,1,""],writerecord:[26,1,1,""],getdata:[26,1,1,""],writebinary:[26,1,1,""],select:[26,1,1,""],updaterecord:[26,1,1,""]},"virtualsmartcard.SEutils.ControlReferenceTemplate":{to_string:[22,1,1,""],parse_SE_config:[22,1,1,""],"_ControlReferenceTemplate__set_algo":[22,1,1,""],"_ControlReferenceTemplate__set_iv":[22,1,1,""],"_ControlReferenceTemplate__set_key":[22,1,1,""],"_ControlReferenceTemplate__replace_tag":[22,1,1,""]},"virtualsmartcard.SmartcardFilesystem.MF":{selectFile:[26,1,1,""],create:[26,3,1,""],getDataEncapsulated:[26,1,1,""],updaterecord:[26,1,1,""],decrypt:[26,1,1,""],firstSFT:[26,4,1,""],dataObjectHandlingDecodeEncapsulated:[26,1,1,""],writeBinaryPlain:[26,1,1,""],updateRecordEncapsulated:[26,1,1,""],dfname:[26,4,1,""],"_selectFile":[26,1,1,""],currentEF:[26,1,1,""],deleteFile:[26,1,1,""],append:[26,1,1,""],readbinary:[26,1,1,""],updatebinary:[26,1,1,""],encrypt:[26,1,1,""],readRecordPlain:[26,1,1,""],eraseBinaryPlain:[26,1,1,""],erasebinary:[26,1,1,""],dataUnitsDecodeEncapsulated:[26,1,1,""],updateRecordPlain:[26,1,1,""],current:[26,4,1,""],putDataPlain:[26,1,1,""],fid:[26,4,1,""],writeRecord:[26,1,1,""],content:[26,4,1,""],makeSecondSoftwareFunctionTable:[26,3,1,""],updateBinaryPlain:[26,1,1,""],select:[26,1,1,""],simpletlv_data:[26,4,1,""],dataUnitsDecodePlain:[26,1,1,""],parent:[26,4,1,""],bertlv_data:[26,4,1,""],writeBinaryEncapsulated:[26,1,1,""],createFile:[26,1,1,""],dataObjectHandlingDecodePlain:[26,1,1,""],getpath:[26,1,1,""],putDataEncapsulated:[26,1,1,""],searchBinaryPlain:[26,1,1,""],appendRecord:[26,1,1,""],readBinaryPlain:[26,1,1,""],filedescriptor:[26,4,1,""],readRecordEncapsulated:[26,1,1,""],writerecord:[26,1,1,""],getdata:[26,1,1,""],data:[26,4,1,""],lifecycle:[26,4,1,""],recordHandlingDecode:[26,1,1,""],makeFirstSoftwareFunctionTable:[26,3,1,""],putdata:[26,1,1,""],eraseRecord:[26,1,1,""],encodeFileControlParameter:[26,3,1,""],readBinaryEncapsulated:[26,1,1,""],getDataPlain:[26,1,1,""],currentDF:[26,1,1,""],remove:[26,1,1,""],eraseBinaryEncapsulated:[26,1,1,""],readrecord:[26,1,1,""],appendrecord:[26,1,1,""],updateBinaryEncapsulated:[26,1,1,""],secondSFT:[26,4,1,""],writebinary:[26,1,1,""],searchBinaryEncapsulated:[26,1,1,""]},"virtualsmartcard.tests.CryptoUtils_test.TestCryptoUtils":{addTypeEqualityFunc:[18,1,1,""],assertLessEqual:[18,1,1,""],tearDown:[18,1,1,""],assertNotEquals:[18,1,1,""],assertNotAlmostEquals:[18,1,1,""],assertNotAlmostEqual:[18,1,1,""],assertIsNone:[18,1,1,""],test_padding:[18,1,1,""],"_getAssertEqualityFunc":[18,1,1,""],failureException:[18,4,1,""],fail:[18,1,1,""],assertEqual:[18,1,1,""],assertRegexpMatches:[18,1,1,""],shortDescription:[18,1,1,""],failUnlessRaises:[18,1,1,""],"_classSetupFailed":[18,4,1,""],skipTest:[18,1,1,""],assertLess:[18,1,1,""],assertMultiLineEqual:[18,1,1,""],"_diffThreshold":[18,4,1,""],assertSequenceEqual:[18,1,1,""],"_addSkip":[18,1,1,""],"_truncateMessage":[18,1,1,""],assertIn:[18,1,1,""],assertRaisesRegexp:[18,1,1,""],addCleanup:[18,1,1,""],assertGreater:[18,1,1,""],"_baseAssertEqual":[18,1,1,""],run:[18,1,1,""],tearDownClass:[18,5,1,""],assertItemsEqual:[18,1,1,""],assertRaises:[18,1,1,""],longMessage:[18,4,1,""],assertAlmostEquals:[18,1,1,""],assertTrue:[18,1,1,""],assertDictEqual:[18,1,1,""],failIfAlmostEqual:[18,1,1,""],doCleanups:[18,1,1,""],assertDictContainsSubset:[18,1,1,""],failIfEqual:[18,1,1,""],failUnlessAlmostEqual:[18,1,1,""],setUp:[18,1,1,""],failIf:[18,1,1,""],assertNotRegexpMatches:[18,1,1,""],assertFalse:[18,1,1,""],assertNotIsInstance:[18,1,1,""],assertTupleEqual:[18,1,1,""],"_formatMessage":[18,1,1,""],assertEquals:[18,1,1,""],maxDiff:[18,4,1,""],assertIs:[18,1,1,""],assertIsInstance:[18,1,1,""],"_deprecate":[18,1,1,""],failUnlessEqual:[18,1,1,""],assert_:[18,1,1,""],failUnless:[18,1,1,""],assertAlmostEqual:[18,1,1,""],setUpClass:[18,5,1,""],assertNotEqual:[18,1,1,""],assertIsNot:[18,1,1,""],assertIsNotNone:[18,1,1,""],id:[18,1,1,""],defaultTestResult:[18,1,1,""],assertListEqual:[18,1,1,""],debug:[18,1,1,""],assertNotIn:[18,1,1,""],countTestCases:[18,1,1,""],assertSetEqual:[18,1,1,""],assertGreaterEqual:[18,1,1,""]},"virtualsmartcard.cards.ePass.PassportSAM":{erase_SE:[24,1,1,""],store_SE:[24,1,1,""],perform_security_operation:[24,1,1,""],get_card_number:[24,1,1,""],set_asym_algorithm:[24,1,1,""],parse_SM_CAPDU:[24,1,1,""],restore_SE:[24,1,1,""],verify:[24,1,1,""],change_reference_data:[24,1,1,""],mutual_authenticate:[24,1,1,""],protect_result:[24,1,1,""],derive_key:[24,3,1,""],FSdecrypt:[24,1,1,""],generate_public_key_pair:[24,1,1,""],"_PassportSAM__computeKeys":[24,1,1,""],set_MF:[24,1,1,""],FSencrypt:[24,1,1,""],external_authenticate:[24,1,1,""],get_challenge:[24,1,1,""],internal_authenticate:[24,1,1,""],"_get_referenced_key":[24,1,1,""],manage_security_environment:[24,1,1,""]},"virtualsmartcard.tests.utils_test.TestUtils":{addTypeEqualityFunc:[28,1,1,""],tearDown:[28,1,1,""],assertNotEquals:[28,1,1,""],failIfAlmostEqual:[28,1,1,""],assertNotAlmostEquals:[28,1,1,""],assertNotAlmostEqual:[28,1,1,""],maxDiff:[28,4,1,""],"_getAssertEqualityFunc":[28,1,1,""],failureException:[28,4,1,""],fail:[28,1,1,""],assertEqual:[28,1,1,""],test_RAPDU:[28,1,1,""],shortDescription:[28,1,1,""],assertGreater:[28,1,1,""],"_classSetupFailed":[28,4,1,""],skipTest:[28,1,1,""],assertLess:[28,1,1,""],failUnlessEqual:[28,1,1,""],"_diffThreshold":[28,4,1,""],assertSequenceEqual:[28,1,1,""],"_addSkip":[28,1,1,""],"_truncateMessage":[28,1,1,""],assertDictContainsSubset:[28,1,1,""],assertRaisesRegexp:[28,1,1,""],addCleanup:[28,1,1,""],id:[28,1,1,""],assertRegexpMatches:[28,1,1,""],"_baseAssertEqual":[28,1,1,""],assertLessEqual:[28,1,1,""],tearDownClass:[28,5,1,""],assertItemsEqual:[28,1,1,""],failUnlessAlmostEqual:[28,1,1,""],assertAlmostEquals:[28,1,1,""],test_CAPDU:[28,1,1,""],assertTrue:[28,1,1,""],assertDictEqual:[28,1,1,""],run:[28,1,1,""],doCleanups:[28,1,1,""],assertIn:[28,1,1,""],failIfEqual:[28,1,1,""],assertRaises:[28,1,1,""],setUp:[28,1,1,""],failIf:[28,1,1,""],assertNotRegexpMatches:[28,1,1,""],assertFalse:[28,1,1,""],assertNotIsInstance:[28,1,1,""],assertTupleEqual:[28,1,1,""],"_formatMessage":[28,1,1,""],assertEquals:[28,1,1,""],assertIsNone:[28,1,1,""],assertIs:[28,1,1,""],assertIsInstance:[28,1,1,""],"_deprecate":[28,1,1,""],assertMultiLineEqual:[28,1,1,""],assert_:[28,1,1,""],failUnless:[28,1,1,""],assertAlmostEqual:[28,1,1,""],setUpClass:[28,5,1,""],failUnlessRaises:[28,1,1,""],assertNotEqual:[28,1,1,""],assertIsNot:[28,1,1,""],assertIsNotNone:[28,1,1,""],longMessage:[28,4,1,""],defaultTestResult:[28,1,1,""],assertListEqual:[28,1,1,""],debug:[28,1,1,""],assertNotIn:[28,1,1,""],countTestCases:[28,1,1,""],assertSetEqual:[28,1,1,""],assertGreaterEqual:[28,1,1,""]},virtualsmartcard:{CryptoUtils:[13,0,0,"-"],CardGenerator:[17,0,0,"-"],utils:[25,0,0,"-"],SEutils:[22,0,0,"-"],ConstantDefinitions:[23,0,0,"-"],SmartcardFilesystem:[26,0,0,"-"],SmartcardSAM:[9,0,0,"-"],TLVutils:[12,0,0,"-"],SWutils:[4,0,0,"-"],VirtualSmartcard:[30,0,0,"-"]},"virtualsmartcard.SmartcardFilesystem.TransparentStructureEF":{putdata:[26,1,1,""],shortfid:[26,4,1,""],select:[26,1,1,""],readbinary:[26,1,1,""],updatebinary:[26,1,1,""],encrypt:[26,1,1,""],erasebinary:[26,1,1,""],lifecycle:[26,4,1,""],fid:[26,4,1,""],bertlv_data:[26,4,1,""],datacoding:[26,4,1,""],parent:[26,4,1,""],decrypt:[26,1,1,""],getpath:[26,1,1,""],filedescriptor:[26,4,1,""],writerecord:[26,1,1,""],getdata:[26,1,1,""],data:[26,4,1,""],simpletlv_data:[26,4,1,""],updaterecord:[26,1,1,""],readrecord:[26,1,1,""],appendrecord:[26,1,1,""],writebinary:[26,1,1,""]},"virtualsmartcard.SEutils.Security_Environment":{compute_digital_signature:[22,1,1,""],encipher:[22,1,1,""],hash:[22,1,1,""],perform_security_operation:[22,1,1,""],verify_certificate:[22,1,1,""],"_set_SE":[22,1,1,""],parse_SM_CAPDU:[22,1,1,""],verify_digital_signature:[22,1,1,""],protect_response:[22,1,1,""],generate_public_key_pair:[22,1,1,""],decipher:[22,1,1,""],verify_cryptographic_checksum:[22,1,1,""],compute_cryptographic_checksum:[22,1,1,""],manage_security_environment:[22,1,1,""]},"virtualsmartcard.cards.cryptoflex":{CryptoflexSAM:[14,2,1,""],CryptoflexMF:[14,2,1,""],CryptoflexOS:[14,2,1,""],CryptoflexSE:[14,2,1,""]},"virtualsmartcard.SmartcardFilesystem.DF":{putdata:[26,1,1,""],dfname:[26,4,1,""],append:[26,1,1,""],readbinary:[26,1,1,""],updatebinary:[26,1,1,""],encrypt:[26,1,1,""],decrypt:[26,1,1,""],lifecycle:[26,4,1,""],content:[26,4,1,""],select:[26,1,1,""],fid:[26,4,1,""],parent:[26,4,1,""],bertlv_data:[26,4,1,""],getpath:[26,1,1,""],filedescriptor:[26,4,1,""],writerecord:[26,1,1,""],getdata:[26,1,1,""],data:[26,4,1,""],simpletlv_data:[26,4,1,""],updaterecord:[26,1,1,""],remove:[26,1,1,""],writebinary:[26,1,1,""],readrecord:[26,1,1,""],appendrecord:[26,1,1,""],erasebinary:[26,1,1,""]},"virtualsmartcard.TLVutils":{encodebertlvDatalist:[12,6,1,""],tlv_find_tags:[12,6,1,""],decodeDiscretionaryDataObjects:[12,6,1,""],tlv_find_tag:[12,6,1,""],simpletlv_unpack:[12,6,1,""],decodeExtendedHeaderList:[12,6,1,""],bertlv_unpack:[12,6,1,""],encodeDiscretionaryDataObjects:[12,6,1,""],decodeHeaderList:[12,6,1,""],simpletlv_pack:[12,6,1,""],bertlv_pack:[12,6,1,""],encodeDataOffsetObjects:[12,6,1,""],tlv_unpack:[12,6,1,""],decodeTagList:[12,6,1,""],unpack:[12,6,1,""],decodeOffsetDataObjects:[12,6,1,""],pack:[12,6,1,""]},"virtualsmartcard.utils":{hexdump:[25,6,1,""],"_unformat_hexdump":[25,6,1,""],APDU:[25,2,1,""],R_APDU:[25,2,1,""],parse_status:[25,6,1,""],"_make_byte_property":[25,6,1,""],stringtoint:[25,6,1,""],inttostring:[25,6,1,""],C_APDU:[25,2,1,""]},"virtualsmartcard.SmartcardFilesystem.RecordStructureEF":{eraserecord:[26,1,1,""],updaterecord:[26,1,1,""],putdata:[26,1,1,""],hasSimpleTlv:[26,1,1,""],shortfid:[26,4,1,""],select:[26,1,1,""],readbinary:[26,1,1,""],recordpointer:[26,4,1,""],encrypt:[26,1,1,""],isCyclic:[26,1,1,""],hasFixedRecordSize:[26,1,1,""],erasebinary:[26,1,1,""],lifecycle:[26,4,1,""],fid:[26,4,1,""],bertlv_data:[26,4,1,""],datacoding:[26,4,1,""],"_RecordStructureEF__getRecordsByIdentifier":[26,1,1,""],maxrecordsize:[26,4,1,""],parent:[26,4,1,""],resetRecordPointer:[26,1,1,""],updatebinary:[26,1,1,""],getpath:[26,1,1,""],"_RecordStructureEF__getRecords":[26,1,1,""],records:[26,4,1,""],filedescriptor:[26,4,1,""],writerecord:[26,1,1,""],getdata:[26,1,1,""],simpletlv_data:[26,4,1,""],"_RecordStructureEF__getRecordsByNumber":[26,1,1,""],decrypt:[26,1,1,""],readrecord:[26,1,1,""],appendrecord:[26,1,1,""],writebinary:[26,1,1,""]},"virtualsmartcard.tests.CardGenerator_test":{ISO7816GeneratorTest:[1,2,1,""],TestNPACardGenerator:[1,2,1,""],CryptoflexGeneratorTest:[1,2,1,""]},"virtualsmartcard.SmartcardFilesystem.Record":{identifier:[26,4,1,""],data:[26,4,1,""]},"virtualsmartcard.cards":{cryptoflex:[14,0,0,"-"],ePass:[24,0,0,"-"],nPA:[7,0,0,"-"],Relay:[11,0,0,"-"],HandlerTest:[20,0,0,"-"]},"virtualsmartcard.tests.SmartcardSAM_test":{TestSmartcardSAM:[5,2,1,""]},"virtualsmartcard.cards.nPA":{NPAOS:[7,2,1,""],nPA_SAM:[7,2,1,""],nPA_AT_CRT:[7,2,1,""],nPA_SE:[7,2,1,""]},"virtualsmartcard.cards.ePass.ePass_SE":{compute_digital_signature:[24,1,1,""],encipher:[24,1,1,""],hash:[24,1,1,""],perform_security_operation:[24,1,1,""],verify_certificate:[24,1,1,""],"_set_SE":[24,1,1,""],parse_SM_CAPDU:[24,1,1,""],verify_digital_signature:[24,1,1,""],generate_public_key_pair:[24,1,1,""],decipher:[24,1,1,""],verify_cryptographic_checksum:[24,1,1,""],protect_response:[24,1,1,""],compute_cryptographic_checksum:[24,1,1,""],manage_security_environment:[24,1,1,""]},"virtualsmartcard.CryptoUtils":{operation_on_string:[13,6,1,""],hash:[13,6,1,""],get_cipher:[13,6,1,""],append_padding:[13,6,1,""],decrypt:[13,6,1,""],"_makesalt":[13,6,1,""],calculate_MAC:[13,6,1,""],get_cipher_keylen:[13,6,1,""],cipher:[13,6,1,""],encrypt:[13,6,1,""],get_cipher_blocklen:[13,6,1,""],crypto_checksum:[13,6,1,""],strip_padding:[13,6,1,""]},"virtualsmartcard.tests.CardGenerator_test.ISO7816GeneratorTest":{addTypeEqualityFunc:[1,1,1,""],tearDown:[1,1,1,""],assertNotEquals:[1,1,1,""],test_card_creation:[1,1,1,""],addCleanup:[1,1,1,""],assertIsNone:[1,1,1,""],"_getAssertEqualityFunc":[1,1,1,""],assertEqual:[1,1,1,""],id:[1,1,1,""],failureException:[1,4,1,""],assertRegexpMatches:[1,1,1,""],shortDescription:[1,1,1,""],assertGreater:[1,1,1,""],"_classSetupFailed":[1,4,1,""],skipTest:[1,1,1,""],assertLess:[1,1,1,""],assertMultiLineEqual:[1,1,1,""],assertSequenceEqual:[1,1,1,""],"_addSkip":[1,1,1,""],"_truncateMessage":[1,1,1,""],assertIn:[1,1,1,""],assertRaisesRegexp:[1,1,1,""],assertNotAlmostEqual:[1,1,1,""],assertNotRegexpMatches:[1,1,1,""],failUnlessRaises:[1,1,1,""],assertTupleEqual:[1,1,1,""],"_baseAssertEqual":[1,1,1,""],assertLessEqual:[1,1,1,""],tearDownClass:[1,5,1,""],assertItemsEqual:[1,1,1,""],failUnlessAlmostEqual:[1,1,1,""],assertAlmostEquals:[1,1,1,""],assertTrue:[1,1,1,""],assertDictEqual:[1,1,1,""],run:[1,1,1,""],doCleanups:[1,1,1,""],assertDictContainsSubset:[1,1,1,""],failIfEqual:[1,1,1,""],assertEquals:[1,1,1,""],setUp:[1,1,1,""],failIf:[1,1,1,""],assertNotAlmostEquals:[1,1,1,""],assertFalse:[1,1,1,""],assertNotIsInstance:[1,1,1,""],failIfAlmostEqual:[1,1,1,""],"_formatMessage":[1,1,1,""],maxDiff:[1,4,1,""],assertIs:[1,1,1,""],assertIsInstance:[1,1,1,""],assertRaises:[1,1,1,""],countTestCases:[1,1,1,""],test_get_and_set_card:[1,1,1,""],failUnlessEqual:[1,1,1,""],assert_:[1,1,1,""],fail:[1,1,1,""],failUnless:[1,1,1,""],assertAlmostEqual:[1,1,1,""],setUpClass:[1,5,1,""],assertListEqual:[1,1,1,""],assertIsNot:[1,1,1,""],card_type:[1,4,1,""],"_diffThreshold":[1,4,1,""],longMessage:[1,4,1,""],defaultTestResult:[1,1,1,""],assertNotEqual:[1,1,1,""],debug:[1,1,1,""],assertNotIn:[1,1,1,""],"_deprecate":[1,1,1,""],assertSetEqual:[1,1,1,""],assertGreaterEqual:[1,1,1,""],assertIsNotNone:[1,1,1,""]},"virtualsmartcard.SWutils":{SwError:[4,7,1,""]},"virtualsmartcard.SWutils.SwError":{message:[4,4,1,""],args:[4,4,1,""]},"virtualsmartcard.SmartcardFilesystem":{prettyprint_anything:[26,6,1,""],MF:[26,2,1,""],getfile_byrefdataobj:[26,6,1,""],get_indexes:[26,6,1,""],make_property:[26,6,1,""],DF:[26,2,1,""],EF:[26,2,1,""],RecordStructureEF:[26,2,1,""],walk:[26,6,1,""],write:[26,6,1,""],Record:[26,2,1,""],File:[26,2,1,""],isEqual:[26,6,1,""],TransparentStructureEF:[26,2,1,""]},"virtualsmartcard.cards.cryptoflex.CryptoflexSE":{compute_digital_signature:[14,1,1,""],encipher:[14,1,1,""],hash:[14,1,1,""],perform_security_operation:[14,1,1,""],verify_certificate:[14,1,1,""],"_set_SE":[14,1,1,""],parse_SM_CAPDU:[14,1,1,""],verify_digital_signature:[14,1,1,""],protect_response:[14,1,1,""],generate_public_key_pair:[14,1,1,""],decipher:[14,1,1,""],verify_cryptographic_checksum:[14,1,1,""],compute_cryptographic_checksum:[14,1,1,""],manage_security_environment:[14,1,1,""]},"virtualsmartcard.cards.ePass":{PassportSAM:[24,2,1,""],ePass_SE:[24,2,1,""]},"virtualsmartcard.CardGenerator.CardGenerator":{getCard:[17,1,1,""],readDatagroups:[17,1,1,""],"_CardGenerator__generate_nPA":[17,1,1,""],"_CardGenerator__generate_ePass":[17,1,1,""],generateCard:[17,1,1,""],"_CardGenerator__generate_iso_card":[17,1,1,""],setCard:[17,1,1,""],"_CardGenerator__generate_cryptoflex":[17,1,1,""]},"virtualsmartcard.cards.nPA.nPA_AT_CRT":{"_ControlReferenceTemplate__set_algo":[7,1,1,""],"_ControlReferenceTemplate__set_iv":[7,1,1,""],PACE_PUK:[7,4,1,""],PACE_MRZ:[7,4,1,""],parse_SE_config:[7,1,1,""],PACE_PIN:[7,4,1,""],to_string:[7,1,1,""],keyref_is_pin:[7,1,1,""],keyref_is_puk:[7,1,1,""],PACE_CAN:[7,4,1,""],"_ControlReferenceTemplate__replace_tag":[7,1,1,""],keyref_is_can:[7,1,1,""],keyref_is_mrz:[7,1,1,""],"_ControlReferenceTemplate__set_key":[7,1,1,""]},"virtualsmartcard.SEutils":{Security_Environment:[22,2,1,""],ControlReferenceTemplate:[22,2,1,""]},"virtualsmartcard.cards.Relay":{RelayOS:[11,2,1,""]},"virtualsmartcard.cards.HandlerTest":{HandlerTestOS:[20,2,1,""]},"virtualsmartcard.utils.APDU":{"_getdata":[25,1,1,""],data:[25,4,1,""],"_setdata":[25,1,1,""],"_setbyte":[25,1,1,""],"_format_parts":[25,1,1,""],"_deldata":[25,1,1,""]},"virtualsmartcard.SmartcardSAM":{get_referenced_cipher:[9,6,1,""],SAM:[9,2,1,""]},"virtualsmartcard.cards.HandlerTest.HandlerTestOS":{reset:[20,1,1,""],execute:[20,1,1,""],powerUp:[20,1,1,""],powerDown:[20,1,1,""],getATR:[20,1,1,""],"_HandlerTestOS__output_from_le":[20,1,1,""]},"virtualsmartcard.tests.CardGenerator_test.TestNPACardGenerator":{assertGreaterEqual:[1,1,1,""],addTypeEqualityFunc:[1,1,1,""],tearDown:[1,1,1,""],assertNotEquals:[1,1,1,""],assertGreater:[1,1,1,""],assertNotAlmostEquals:[1,1,1,""],addCleanup:[1,1,1,""],maxDiff:[1,4,1,""],failUnlessAlmostEqual:[1,1,1,""],"_getAssertEqualityFunc":[1,1,1,""],assertListEqual:[1,1,1,""],assertEqual:[1,1,1,""],fail:[1,1,1,""],failureException:[1,4,1,""],assertRegexpMatches:[1,1,1,""],shortDescription:[1,1,1,""],id:[1,1,1,""],assertDictContainsSubset:[1,1,1,""],assertLess:[1,1,1,""],failUnlessEqual:[1,1,1,""],"_diffThreshold":[1,4,1,""],test_readDatagroups:[1,1,1,""],"_addSkip":[1,1,1,""],"_truncateMessage":[1,1,1,""],assertNotIn:[1,1,1,""],assertRaisesRegexp:[1,1,1,""],assertNotAlmostEqual:[1,1,1,""],failUnlessRaises:[1,1,1,""],"_baseAssertEqual":[1,1,1,""],assertLessEqual:[1,1,1,""],tearDownClass:[1,5,1,""],doCleanups:[1,1,1,""],assertRaises:[1,1,1,""],run:[1,1,1,""],assertAlmostEquals:[1,1,1,""],assertTrue:[1,1,1,""],assertDictEqual:[1,1,1,""],test_card_creation:[1,1,1,""],failIfAlmostEqual:[1,1,1,""],assertItemsEqual:[1,1,1,""],assertIn:[1,1,1,""],failIfEqual:[1,1,1,""],assertEquals:[1,1,1,""],setUp:[1,1,1,""],failIf:[1,1,1,""],"_classSetupFailed":[1,4,1,""],assertNotRegexpMatches:[1,1,1,""],debug:[1,1,1,""],assertNotIsInstance:[1,1,1,""],assertTupleEqual:[1,1,1,""],"_formatMessage":[1,1,1,""],assertIsNone:[1,1,1,""],assertIs:[1,1,1,""],assertIsInstance:[1,1,1,""],countTestCases:[1,1,1,""],assertMultiLineEqual:[1,1,1,""],assert_:[1,1,1,""],failUnless:[1,1,1,""],assertAlmostEqual:[1,1,1,""],setUpClass:[1,5,1,""],skipTest:[1,1,1,""],assertIsNot:[1,1,1,""],assertSequenceEqual:[1,1,1,""],card_type:[1,4,1,""],assertIsNotNone:[1,1,1,""],longMessage:[1,4,1,""],defaultTestResult:[1,1,1,""],assertNotEqual:[1,1,1,""],assertFalse:[1,1,1,""],"_deprecate":[1,1,1,""],assertSetEqual:[1,1,1,""],test_get_and_set_card:[1,1,1,""]},"virtualsmartcard.utils.C_APDU":{Le:[25,4,1,""],Lc:[25,4,1,""],render:[25,1,1,""],ins:[25,4,1,""],parse:[25,1,1,""],"_setbyte":[25,1,1,""],le:[25,4,1,""],lc:[25,4,1,""],"_format_fields":[25,1,1,""],cla:[25,4,1,""],P2:[25,4,1,""],"case":[25,1,1,""],P1:[25,4,1,""],"_getdata":[25,1,1,""],effective_Le:[25,4,1,""],CLA:[25,4,1,""],"_setdata":[25,1,1,""],data:[25,4,1,""],"_deldata":[25,1,1,""],p2:[25,4,1,""],p1:[25,4,1,""],INS:[25,4,1,""],"_format_parts":[25,1,1,""]},"virtualsmartcard.cards.Relay.RelayOS":{reset:[11,1,1,""],execute:[11,1,1,""],powerUp:[11,1,1,""],powerDown:[11,1,1,""],getATR:[11,1,1,""],cleanup:[11,1,1,""]},"virtualsmartcard.utils.R_APDU":{parse:[25,1,1,""],SW2:[25,4,1,""],"_getdata":[25,1,1,""],render:[25,1,1,""],"_format_parts":[25,1,1,""],SW:[25,4,1,""],sw:[25,4,1,""],data:[25,4,1,""],"_setbyte":[25,1,1,""],SW1:[25,4,1,""],"_getsw":[25,1,1,""],"_setsw":[25,1,1,""],sw1:[25,4,1,""],"_setdata":[25,1,1,""],sw2:[25,4,1,""],"_format_fields":[25,1,1,""],"_deldata":[25,1,1,""]},"virtualsmartcard.cards.cryptoflex.CryptoflexSAM":{erase_SE:[14,1,1,""],pezorform_security_operation:[14,1,1,""],store_SE:[14,1,1,""],set_asym_algorithm:[14,1,1,""],perform_security_operation:[14,1,1,""],verify:[14,1,1,""],protect_result:[14,1,1,""],change_reference_data:[14,1,1,""],set_MF:[14,1,1,""],FSencrypt:[14,1,1,""],external_authenticate:[14,1,1,""],restore_SE:[14,1,1,""],parse_SM_CAPDU:[14,1,1,""],FSdecrypt:[14,1,1,""],generate_public_key_pair:[14,1,1,""],internal_authenticate:[14,1,1,""],"_get_referenced_key":[14,1,1,""],mutual_authenticate:[14,1,1,""],get_challenge:[14,1,1,""],get_card_number:[14,1,1,""],manage_security_environment:[14,1,1,""]},"virtualsmartcard.VirtualSmartcard.Iso7816OS":{reset:[30,1,1,""],formatResult:[30,1,1,""],mf:[30,4,1,""],SAM:[30,4,1,""],powerDown:[30,1,1,""],getATR:[30,1,1,""],makeThirdSoftwareFunctionTable:[30,3,1,""],getResponse:[30,1,1,""],powerUp:[30,1,1,""],execute:[30,1,1,""],seekable:[30,3,1,""],makeATR:[30,3,1,""]},"virtualsmartcard.cards.nPA.nPA_SAM":{erase_SE:[7,1,1,""],store_SE:[7,1,1,""],perform_security_operation:[7,1,1,""],get_card_number:[7,1,1,""],set_asym_algorithm:[7,1,1,""],parse_SM_CAPDU:[7,1,1,""],restore_SE:[7,1,1,""],verify:[7,1,1,""],reset_retry_counter:[7,1,1,""],change_reference_data:[7,1,1,""],mutual_authenticate:[7,1,1,""],general_authenticate:[7,1,1,""],protect_result:[7,1,1,""],FSdecrypt:[7,1,1,""],generate_public_key_pair:[7,1,1,""],set_MF:[7,1,1,""],FSencrypt:[7,1,1,""],external_authenticate:[7,1,1,""],get_challenge:[7,1,1,""],internal_authenticate:[7,1,1,""],"_get_referenced_key":[7,1,1,""],manage_security_environment:[7,1,1,""]},"virtualsmartcard.tests.CardGenerator_test.CryptoflexGeneratorTest":{addTypeEqualityFunc:[1,1,1,""],tearDown:[1,1,1,""],assertNotEquals:[1,1,1,""],assertIn:[1,1,1,""],test_card_creation:[1,1,1,""],assertNotAlmostEqual:[1,1,1,""],maxDiff:[1,4,1,""],failUnlessAlmostEqual:[1,1,1,""],"_truncateMessage":[1,1,1,""],assertEqual:[1,1,1,""],fail:[1,1,1,""],failureException:[1,4,1,""],assertRegexpMatches:[1,1,1,""],shortDescription:[1,1,1,""],id:[1,1,1,""],"_classSetupFailed":[1,4,1,""],skipTest:[1,1,1,""],assertLess:[1,1,1,""],failUnlessEqual:[1,1,1,""],assertSequenceEqual:[1,1,1,""],"_addSkip":[1,1,1,""],test_get_and_set_card:[1,1,1,""],assertNotIn:[1,1,1,""],assertRaisesRegexp:[1,1,1,""],addCleanup:[1,1,1,""],assertGreater:[1,1,1,""],"_baseAssertEqual":[1,1,1,""],run:[1,1,1,""],tearDownClass:[1,5,1,""],assertItemsEqual:[1,1,1,""],assertEquals:[1,1,1,""],assertLessEqual:[1,1,1,""],assertAlmostEquals:[1,1,1,""],assertTrue:[1,1,1,""],assertDictEqual:[1,1,1,""],failIfAlmostEqual:[1,1,1,""],doCleanups:[1,1,1,""],assertDictContainsSubset:[1,1,1,""],failIfEqual:[1,1,1,""],assertRaises:[1,1,1,""],setUp:[1,1,1,""],failIf:[1,1,1,""],assertNotRegexpMatches:[1,1,1,""],assertFalse:[1,1,1,""],assertNotIsInstance:[1,1,1,""],assertTupleEqual:[1,1,1,""],"_formatMessage":[1,1,1,""],assertIsNone:[1,1,1,""],assertIs:[1,1,1,""],assertIsInstance:[1,1,1,""],"_deprecate":[1,1,1,""],assertNotAlmostEquals:[1,1,1,""],assertMultiLineEqual:[1,1,1,""],assert_:[1,1,1,""],failUnless:[1,1,1,""],assertAlmostEqual:[1,1,1,""],setUpClass:[1,5,1,""],failUnlessRaises:[1,1,1,""],assertNotEqual:[1,1,1,""],assertIsNot:[1,1,1,""],card_type:[1,4,1,""],"_diffThreshold":[1,4,1,""],"_getAssertEqualityFunc":[1,1,1,""],longMessage:[1,4,1,""],defaultTestResult:[1,1,1,""],assertListEqual:[1,1,1,""],debug:[1,1,1,""],countTestCases:[1,1,1,""],assertSetEqual:[1,1,1,""],assertGreaterEqual:[1,1,1,""],assertIsNotNone:[1,1,1,""]},"virtualsmartcard.CardGenerator":{CardGenerator:[17,2,1,""]},"virtualsmartcard.SmartcardFilesystem.EF":{updaterecord:[26,1,1,""],putdata:[26,1,1,""],shortfid:[26,4,1,""],select:[26,1,1,""],readbinary:[26,1,1,""],updatebinary:[26,1,1,""],encrypt:[26,1,1,""],erasebinary:[26,1,1,""],simpletlv_data:[26,4,1,""],fid:[26,4,1,""],datacoding:[26,4,1,""],parent:[26,4,1,""],bertlv_data:[26,4,1,""],getpath:[26,1,1,""],filedescriptor:[26,4,1,""],writerecord:[26,1,1,""],getdata:[26,1,1,""],lifecycle:[26,4,1,""],decrypt:[26,1,1,""],readrecord:[26,1,1,""],appendrecord:[26,1,1,""],writebinary:[26,1,1,""]},"virtualsmartcard.tests.SmartcardSAM_test.TestSmartcardSAM":{addTypeEqualityFunc:[5,1,1,""],test_counter_decrement:[5,1,1,""],tearDown:[5,1,1,""],assertNotEquals:[5,1,1,""],assertGreater:[5,1,1,""],assertNotAlmostEquals:[5,1,1,""],addCleanup:[5,1,1,""],maxDiff:[5,4,1,""],failUnlessAlmostEqual:[5,1,1,""],"_getAssertEqualityFunc":[5,1,1,""],assertListEqual:[5,1,1,""],failureException:[5,4,1,""],fail:[5,1,1,""],run:[5,1,1,""],assertRegexpMatches:[5,1,1,""],shortDescription:[5,1,1,""],failUnlessRaises:[5,1,1,""],"_classSetupFailed":[5,4,1,""],skipTest:[5,1,1,""],assertLess:[5,1,1,""],assertDictContainsSubset:[5,1,1,""],assertSequenceEqual:[5,1,1,""],"_addSkip":[5,1,1,""],"_truncateMessage":[5,1,1,""],assertIn:[5,1,1,""],assertRaisesRegexp:[5,1,1,""],assertNotAlmostEqual:[5,1,1,""],id:[5,1,1,""],"_baseAssertEqual":[5,1,1,""],assertLessEqual:[5,1,1,""],tearDownClass:[5,5,1,""],test_incorrect_pin:[5,1,1,""],assertRaises:[5,1,1,""],test_external_authenticate:[5,1,1,""],assertAlmostEquals:[5,1,1,""],assertTrue:[5,1,1,""],assertDictEqual:[5,1,1,""],failIfAlmostEqual:[5,1,1,""],doCleanups:[5,1,1,""],assertNotIn:[5,1,1,""],failIfEqual:[5,1,1,""],assertEquals:[5,1,1,""],test_internal_authenticate:[5,1,1,""],assertNotRegexpMatches:[5,1,1,""],debug:[5,1,1,""],assertNotIsInstance:[5,1,1,""],assertTupleEqual:[5,1,1,""],"_formatMessage":[5,1,1,""],assertIsNone:[5,1,1,""],assertIs:[5,1,1,""],assertIsInstance:[5,1,1,""],"_deprecate":[5,1,1,""],failUnlessEqual:[5,1,1,""],assert_:[5,1,1,""],failUnless:[5,1,1,""],assertAlmostEqual:[5,1,1,""],setUpClass:[5,5,1,""],assertNotEqual:[5,1,1,""],assertIsNot:[5,1,1,""],assertMultiLineEqual:[5,1,1,""],"_diffThreshold":[5,4,1,""],test_security_environment:[5,1,1,""],longMessage:[5,4,1,""],defaultTestResult:[5,1,1,""],assertIsNotNone:[5,1,1,""],failIf:[5,1,1,""],assertFalse:[5,1,1,""],setUp:[5,1,1,""],countTestCases:[5,1,1,""],assertEqual:[5,1,1,""],assertSetEqual:[5,1,1,""],assertGreaterEqual:[5,1,1,""],assertItemsEqual:[5,1,1,""]},"virtualsmartcard.tests":{SmartcardSAM_test:[5,0,0,"-"],CryptoUtils_test:[18,0,0,"-"],utils_test:[28,0,0,"-"],CardGenerator_test:[1,0,0,"-"]},"virtualsmartcard.tests.CryptoUtils_test":{TestCryptoUtils:[18,2,1,""]},"virtualsmartcard.SmartcardSAM.SAM":{erase_SE:[9,1,1,""],perform_security_operation:[9,1,1,""],store_SE:[9,1,1,""],FSencrypt:[9,1,1,""],change_reference_data:[9,1,1,""],verify:[9,1,1,""],protect_result:[9,1,1,""],parse_SM_CAPDU:[9,1,1,""],set_MF:[9,1,1,""],set_asym_algorithm:[9,1,1,""],external_authenticate:[9,1,1,""],get_challenge:[9,1,1,""],FSdecrypt:[9,1,1,""],generate_public_key_pair:[9,1,1,""],internal_authenticate:[9,1,1,""],"_get_referenced_key":[9,1,1,""],mutual_authenticate:[9,1,1,""],restore_SE:[9,1,1,""],get_card_number:[9,1,1,""],manage_security_environment:[9,1,1,""]},"virtualsmartcard.cards.nPA.nPA_SE":{general_authenticate:[7,1,1,""],perform_security_operation:[7,1,1,""],"_nPA_SE__eac_pace_step2":[7,1,1,""],parse_SM_CAPDU:[7,1,1,""],protect_response:[7,1,1,""],"_nPA_SE__pack_general_authenticate":[7,3,1,""],verify_cryptographic_checksum:[7,1,1,""],verify_certificate:[7,1,1,""],"_set_SE":[7,1,1,""],compute_digital_signature:[7,1,1,""],eac_step:[7,4,1,""],hash:[7,1,1,""],"_nPA_SE__eac_ca":[7,1,1,""],"_nPA_SE__unpack_general_authenticate":[7,3,1,""],generate_public_key_pair:[7,1,1,""],decipher:[7,1,1,""],"_nPA_SE__eac_pace_step3":[7,1,1,""],"_nPA_SE__eac_pace_step1":[7,1,1,""],compute_cryptographic_checksum:[7,1,1,""],"_nPA_SE__eac_pace_step4":[7,1,1,""],encipher:[7,1,1,""],external_authenticate:[7,1,1,""],verify_digital_signature:[7,1,1,""],manage_security_environment:[7,1,1,""]},"virtualsmartcard.cards.cryptoflex.CryptoflexOS":{reset:[14,1,1,""],execute:[14,1,1,""],mf:[14,4,1,""],SAM:[14,4,1,""],makeATR:[14,3,1,""],formatResult:[14,1,1,""],getATR:[14,1,1,""],makeThirdSoftwareFunctionTable:[14,3,1,""],getResponse:[14,1,1,""],powerUp:[14,1,1,""],seekable:[14,3,1,""],powerDown:[14,1,1,""]}},titleterms:{gadgetf:8,creat:3,less:[21,2,27],libnfc:0,smartcardfilesystem:26,utils_test:28,packag:[16,29,15],unix:[6,8,0],handlertest:20,opensc:8,cryptoutil:13,linux:[6,8,0],download:[8,19,2,27,0,6,21],instal:[8,0,2,27,6,21],librari:10,epass:24,usb:8,hint:[8,0],similar:[6,8,0],cardgenerator_test:1,configur:6,question:[8,0,2,27,6,21],written:6,virtual:[6,19,3],contact:[21,2,27],note:[8,0,2,27,6,21],window:6,other:3,interfac:0,build:6,reader:[8,21],test:29,android:[21,2,0],document:[19,3],contactless:0,modul:[22,23,9,18,25,11,28,14,12,13,1,30,4,5,24,20,26,17,7],smart:[8,10,0,19,2,27,3,6,21],architectur:19,tizen:27,run:6,ccid:8,python:6,usag:[8,0],npa:[7,10],smartwatch:27,cardgener:17,cryptoflex:14,mac:6,virtualsmartcard:[30,15],seutil:22,relai:[11,0],cryptoutils_test:18,compliant:8,vpicc:6,card:[8,10,0,19,2,27,16,3,6,21],vpcd:6,util:25,like:3,phone:[21,2],remot:21,type:3,middlewar:0,emul:[6,8,2,27,0],smartcardsam:9,exampl:3,iso:3,tlvutil:12,constantdefinit:23,smartcardsam_test:5,implement:3,refer:[8,19,2,27,0,6,21],swutil:4,welcom:19}})vsmartcard-3.3/docs/.buildinfo0000644000175000017500000000034613546304763015121 0ustar philphil# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 8e5f2a4bcebac1b2d77d5116e3094531 tags: 645f666f9bcd5a90fca523b33c5a78b7 vsmartcard-3.3/docs/.gitignore0000644000175000017500000000001313546304763015124 0ustar philphil.buildinfo vsmartcard-3.3/docs/_static/0000755000175000017500000000000013546304763014570 5ustar philphilvsmartcard-3.3/docs/_static/bootstrap-2.3.2/0000755000175000017500000000000013546304763017245 5ustar philphilvsmartcard-3.3/docs/_static/bootstrap-2.3.2/css/0000755000175000017500000000000013546304763020035 5ustar philphilvsmartcard-3.3/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css0000644000175000017500000031703713546304763023361 0ustar philphil/*! * Bootstrap v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} vsmartcard-3.3/docs/_static/bootstrap-2.3.2/css/bootstrap.css0000644000175000017500000037057013546304763022600 0ustar philphil/*! * Bootstrap v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. */ .clearfix { *zoom: 1; } .clearfix:before, .clearfix:after { display: table; line-height: 0; content: ""; } .clearfix:after { clear: both; } .hide-text { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } .input-block-level { display: block; width: 100%; min-height: 30px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; } audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; } audio:not([controls]) { display: none; } html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } a:hover, a:active { outline: 0; } sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } img { width: auto\9; height: auto; max-width: 100%; vertical-align: middle; border: 0; -ms-interpolation-mode: bicubic; } #map_canvas img, .google-maps img { max-width: none; } button, input, select, textarea { margin: 0; font-size: 100%; vertical-align: middle; } button, input { *overflow: visible; line-height: normal; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0; } button, html input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; } label, select, button, input[type="button"], input[type="reset"], input[type="submit"], input[type="radio"], input[type="checkbox"] { cursor: pointer; } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield; } input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; } textarea { overflow: auto; vertical-align: top; } @media print { * { color: #000 !important; text-shadow: none !important; background: transparent !important; box-shadow: none !important; } a, a:visited { text-decoration: underline; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } @page { margin: 0.5cm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } } body { margin: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px; color: #333333; background-color: #ffffff; } a { color: #0088cc; text-decoration: none; } a:hover, a:focus { color: #005580; text-decoration: underline; } .img-rounded { -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .img-polaroid { padding: 4px; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } .img-circle { -webkit-border-radius: 500px; -moz-border-radius: 500px; border-radius: 500px; } .row { margin-left: -20px; *zoom: 1; } .row:before, .row:after { display: table; line-height: 0; content: ""; } .row:after { clear: both; } [class*="span"] { float: left; min-height: 1px; margin-left: 20px; } .container, .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container { width: 940px; } .span12 { width: 940px; } .span11 { width: 860px; } .span10 { width: 780px; } .span9 { width: 700px; } .span8 { width: 620px; } .span7 { width: 540px; } .span6 { width: 460px; } .span5 { width: 380px; } .span4 { width: 300px; } .span3 { width: 220px; } .span2 { width: 140px; } .span1 { width: 60px; } .offset12 { margin-left: 980px; } .offset11 { margin-left: 900px; } .offset10 { margin-left: 820px; } .offset9 { margin-left: 740px; } .offset8 { margin-left: 660px; } .offset7 { margin-left: 580px; } .offset6 { margin-left: 500px; } .offset5 { margin-left: 420px; } .offset4 { margin-left: 340px; } .offset3 { margin-left: 260px; } .offset2 { margin-left: 180px; } .offset1 { margin-left: 100px; } .row-fluid { width: 100%; *zoom: 1; } .row-fluid:before, .row-fluid:after { display: table; line-height: 0; content: ""; } .row-fluid:after { clear: both; } .row-fluid [class*="span"] { display: block; float: left; width: 100%; min-height: 30px; margin-left: 2.127659574468085%; *margin-left: 2.074468085106383%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .row-fluid [class*="span"]:first-child { margin-left: 0; } .row-fluid .controls-row [class*="span"] + [class*="span"] { margin-left: 2.127659574468085%; } .row-fluid .span12 { width: 100%; *width: 99.94680851063829%; } .row-fluid .span11 { width: 91.48936170212765%; *width: 91.43617021276594%; } .row-fluid .span10 { width: 82.97872340425532%; *width: 82.92553191489361%; } .row-fluid .span9 { width: 74.46808510638297%; *width: 74.41489361702126%; } .row-fluid .span8 { width: 65.95744680851064%; *width: 65.90425531914893%; } .row-fluid .span7 { width: 57.44680851063829%; *width: 57.39361702127659%; } .row-fluid .span6 { width: 48.93617021276595%; *width: 48.88297872340425%; } .row-fluid .span5 { width: 40.42553191489362%; *width: 40.37234042553192%; } .row-fluid .span4 { width: 31.914893617021278%; *width: 31.861702127659576%; } .row-fluid .span3 { width: 23.404255319148934%; *width: 23.351063829787233%; } .row-fluid .span2 { width: 14.893617021276595%; *width: 14.840425531914894%; } .row-fluid .span1 { width: 6.382978723404255%; *width: 6.329787234042553%; } .row-fluid .offset12 { margin-left: 104.25531914893617%; *margin-left: 104.14893617021275%; } .row-fluid .offset12:first-child { margin-left: 102.12765957446808%; *margin-left: 102.02127659574467%; } .row-fluid .offset11 { margin-left: 95.74468085106382%; *margin-left: 95.6382978723404%; } .row-fluid .offset11:first-child { margin-left: 93.61702127659574%; *margin-left: 93.51063829787232%; } .row-fluid .offset10 { margin-left: 87.23404255319149%; *margin-left: 87.12765957446807%; } .row-fluid .offset10:first-child { margin-left: 85.1063829787234%; *margin-left: 84.99999999999999%; } .row-fluid .offset9 { margin-left: 78.72340425531914%; *margin-left: 78.61702127659572%; } .row-fluid .offset9:first-child { margin-left: 76.59574468085106%; *margin-left: 76.48936170212764%; } .row-fluid .offset8 { margin-left: 70.2127659574468%; *margin-left: 70.10638297872339%; } .row-fluid .offset8:first-child { margin-left: 68.08510638297872%; *margin-left: 67.9787234042553%; } .row-fluid .offset7 { margin-left: 61.70212765957446%; *margin-left: 61.59574468085106%; } .row-fluid .offset7:first-child { margin-left: 59.574468085106375%; *margin-left: 59.46808510638297%; } .row-fluid .offset6 { margin-left: 53.191489361702125%; *margin-left: 53.085106382978715%; } .row-fluid .offset6:first-child { margin-left: 51.063829787234035%; *margin-left: 50.95744680851063%; } .row-fluid .offset5 { margin-left: 44.68085106382979%; *margin-left: 44.57446808510638%; } .row-fluid .offset5:first-child { margin-left: 42.5531914893617%; *margin-left: 42.4468085106383%; } .row-fluid .offset4 { margin-left: 36.170212765957444%; *margin-left: 36.06382978723405%; } .row-fluid .offset4:first-child { margin-left: 34.04255319148936%; *margin-left: 33.93617021276596%; } .row-fluid .offset3 { margin-left: 27.659574468085104%; *margin-left: 27.5531914893617%; } .row-fluid .offset3:first-child { margin-left: 25.53191489361702%; *margin-left: 25.425531914893618%; } .row-fluid .offset2 { margin-left: 19.148936170212764%; *margin-left: 19.04255319148936%; } .row-fluid .offset2:first-child { margin-left: 17.02127659574468%; *margin-left: 16.914893617021278%; } .row-fluid .offset1 { margin-left: 10.638297872340425%; *margin-left: 10.53191489361702%; } .row-fluid .offset1:first-child { margin-left: 8.51063829787234%; *margin-left: 8.404255319148938%; } [class*="span"].hide, .row-fluid [class*="span"].hide { display: none; } [class*="span"].pull-right, .row-fluid [class*="span"].pull-right { float: right; } .container { margin-right: auto; margin-left: auto; *zoom: 1; } .container:before, .container:after { display: table; line-height: 0; content: ""; } .container:after { clear: both; } .container-fluid { padding-right: 20px; padding-left: 20px; *zoom: 1; } .container-fluid:before, .container-fluid:after { display: table; line-height: 0; content: ""; } .container-fluid:after { clear: both; } p { margin: 0 0 10px; } .lead { margin-bottom: 20px; font-size: 21px; font-weight: 200; line-height: 30px; } small { font-size: 85%; } strong { font-weight: bold; } em { font-style: italic; } cite { font-style: normal; } .muted { color: #999999; } a.muted:hover, a.muted:focus { color: #808080; } .text-warning { color: #c09853; } a.text-warning:hover, a.text-warning:focus { color: #a47e3c; } .text-error { color: #b94a48; } a.text-error:hover, a.text-error:focus { color: #953b39; } .text-info { color: #3a87ad; } a.text-info:hover, a.text-info:focus { color: #2d6987; } .text-success { color: #468847; } a.text-success:hover, a.text-success:focus { color: #356635; } .text-left { text-align: left; } .text-right { text-align: right; } .text-center { text-align: center; } h1, h2, h3, h4, h5, h6 { margin: 10px 0; font-family: inherit; font-weight: bold; line-height: 20px; color: inherit; text-rendering: optimizelegibility; } h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { font-weight: normal; line-height: 1; color: #999999; } h1, h2, h3 { line-height: 40px; } h1 { font-size: 38.5px; } h2 { font-size: 31.5px; } h3 { font-size: 24.5px; } h4 { font-size: 17.5px; } h5 { font-size: 14px; } h6 { font-size: 11.9px; } h1 small { font-size: 24.5px; } h2 small { font-size: 17.5px; } h3 small { font-size: 14px; } h4 small { font-size: 14px; } .page-header { padding-bottom: 9px; margin: 20px 0 30px; border-bottom: 1px solid #eeeeee; } ul, ol { padding: 0; margin: 0 0 10px 25px; } ul ul, ul ol, ol ol, ol ul { margin-bottom: 0; } li { line-height: 20px; } ul.unstyled, ol.unstyled { margin-left: 0; list-style: none; } ul.inline, ol.inline { margin-left: 0; list-style: none; } ul.inline > li, ol.inline > li { display: inline-block; *display: inline; padding-right: 5px; padding-left: 5px; *zoom: 1; } dl { margin-bottom: 20px; } dt, dd { line-height: 20px; } dt { font-weight: bold; } dd { margin-left: 10px; } .dl-horizontal { *zoom: 1; } .dl-horizontal:before, .dl-horizontal:after { display: table; line-height: 0; content: ""; } .dl-horizontal:after { clear: both; } .dl-horizontal dt { float: left; width: 160px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; } .dl-horizontal dd { margin-left: 180px; } hr { margin: 20px 0; border: 0; border-top: 1px solid #eeeeee; border-bottom: 1px solid #ffffff; } abbr[title], abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #999999; } abbr.initialism { font-size: 90%; text-transform: uppercase; } blockquote { padding: 0 0 0 15px; margin: 0 0 20px; border-left: 5px solid #eeeeee; } blockquote p { margin-bottom: 0; font-size: 17.5px; font-weight: 300; line-height: 1.25; } blockquote small { display: block; line-height: 20px; color: #999999; } blockquote small:before { content: '\2014 \00A0'; } blockquote.pull-right { float: right; padding-right: 15px; padding-left: 0; border-right: 5px solid #eeeeee; border-left: 0; } blockquote.pull-right p, blockquote.pull-right small { text-align: right; } blockquote.pull-right small:before { content: ''; } blockquote.pull-right small:after { content: '\00A0 \2014'; } q:before, q:after, blockquote:before, blockquote:after { content: ""; } address { display: block; margin-bottom: 20px; font-style: normal; line-height: 20px; } code, pre { padding: 0 3px 2px; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 12px; color: #333333; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } code { padding: 2px 4px; color: #d14; white-space: nowrap; background-color: #f7f7f9; border: 1px solid #e1e1e8; } pre { display: block; padding: 9.5px; margin: 0 0 10px; font-size: 13px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre; white-space: pre-wrap; background-color: #f5f5f5; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.15); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } pre.prettyprint { margin-bottom: 20px; } pre code { padding: 0; color: inherit; white-space: pre; white-space: pre-wrap; background-color: transparent; border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } form { margin: 0 0 20px; } fieldset { padding: 0; margin: 0; border: 0; } legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 21px; line-height: 40px; color: #333333; border: 0; border-bottom: 1px solid #e5e5e5; } legend small { font-size: 15px; color: #999999; } label, input, button, select, textarea { font-size: 14px; font-weight: normal; line-height: 20px; } input, button, select, textarea { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } label { display: block; margin-bottom: 5px; } select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { display: inline-block; height: 20px; padding: 4px 6px; margin-bottom: 10px; font-size: 14px; line-height: 20px; color: #555555; vertical-align: middle; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } input, textarea, .uneditable-input { width: 206px; } textarea { height: auto; } textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { background-color: #ffffff; border: 1px solid #cccccc; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; -moz-transition: border linear 0.2s, box-shadow linear 0.2s; -o-transition: border linear 0.2s, box-shadow linear 0.2s; transition: border linear 0.2s, box-shadow linear 0.2s; } textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="date"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus, .uneditable-input:focus { border-color: rgba(82, 168, 236, 0.8); outline: 0; outline: thin dotted \9; /* IE6-9 */ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); } input[type="radio"], input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; *margin-top: 0; line-height: normal; } input[type="file"], input[type="image"], input[type="submit"], input[type="reset"], input[type="button"], input[type="radio"], input[type="checkbox"] { width: auto; } select, input[type="file"] { height: 30px; /* In IE7, the height of the select element cannot be changed by height, only font-size */ *margin-top: 4px; /* For IE7, add top margin to align select with labels */ line-height: 30px; } select { width: 220px; background-color: #ffffff; border: 1px solid #cccccc; } select[multiple], select[size] { height: auto; } select:focus, input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .uneditable-input, .uneditable-textarea { color: #999999; cursor: not-allowed; background-color: #fcfcfc; border-color: #cccccc; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); } .uneditable-input { overflow: hidden; white-space: nowrap; } .uneditable-textarea { width: auto; height: auto; } input:-moz-placeholder, textarea:-moz-placeholder { color: #999999; } input:-ms-input-placeholder, textarea:-ms-input-placeholder { color: #999999; } input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { color: #999999; } .radio, .checkbox { min-height: 20px; padding-left: 20px; } .radio input[type="radio"], .checkbox input[type="checkbox"] { float: left; margin-left: -20px; } .controls > .radio:first-child, .controls > .checkbox:first-child { padding-top: 5px; } .radio.inline, .checkbox.inline { display: inline-block; padding-top: 5px; margin-bottom: 0; vertical-align: middle; } .radio.inline + .radio.inline, .checkbox.inline + .checkbox.inline { margin-left: 10px; } .input-mini { width: 60px; } .input-small { width: 90px; } .input-medium { width: 150px; } .input-large { width: 210px; } .input-xlarge { width: 270px; } .input-xxlarge { width: 530px; } input[class*="span"], select[class*="span"], textarea[class*="span"], .uneditable-input[class*="span"], .row-fluid input[class*="span"], .row-fluid select[class*="span"], .row-fluid textarea[class*="span"], .row-fluid .uneditable-input[class*="span"] { float: none; margin-left: 0; } .input-append input[class*="span"], .input-append .uneditable-input[class*="span"], .input-prepend input[class*="span"], .input-prepend .uneditable-input[class*="span"], .row-fluid input[class*="span"], .row-fluid select[class*="span"], .row-fluid textarea[class*="span"], .row-fluid .uneditable-input[class*="span"], .row-fluid .input-prepend [class*="span"], .row-fluid .input-append [class*="span"] { display: inline-block; } input, textarea, .uneditable-input { margin-left: 0; } .controls-row [class*="span"] + [class*="span"] { margin-left: 20px; } input.span12, textarea.span12, .uneditable-input.span12 { width: 926px; } input.span11, textarea.span11, .uneditable-input.span11 { width: 846px; } input.span10, textarea.span10, .uneditable-input.span10 { width: 766px; } input.span9, textarea.span9, .uneditable-input.span9 { width: 686px; } input.span8, textarea.span8, .uneditable-input.span8 { width: 606px; } input.span7, textarea.span7, .uneditable-input.span7 { width: 526px; } input.span6, textarea.span6, .uneditable-input.span6 { width: 446px; } input.span5, textarea.span5, .uneditable-input.span5 { width: 366px; } input.span4, textarea.span4, .uneditable-input.span4 { width: 286px; } input.span3, textarea.span3, .uneditable-input.span3 { width: 206px; } input.span2, textarea.span2, .uneditable-input.span2 { width: 126px; } input.span1, textarea.span1, .uneditable-input.span1 { width: 46px; } .controls-row { *zoom: 1; } .controls-row:before, .controls-row:after { display: table; line-height: 0; content: ""; } .controls-row:after { clear: both; } .controls-row [class*="span"], .row-fluid .controls-row [class*="span"] { float: left; } .controls-row .checkbox[class*="span"], .controls-row .radio[class*="span"] { padding-top: 5px; } input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] { cursor: not-allowed; background-color: #eeeeee; } input[type="radio"][disabled], input[type="checkbox"][disabled], input[type="radio"][readonly], input[type="checkbox"][readonly] { background-color: transparent; } .control-group.warning .control-label, .control-group.warning .help-block, .control-group.warning .help-inline { color: #c09853; } .control-group.warning .checkbox, .control-group.warning .radio, .control-group.warning input, .control-group.warning select, .control-group.warning textarea { color: #c09853; } .control-group.warning input, .control-group.warning select, .control-group.warning textarea { border-color: #c09853; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .control-group.warning input:focus, .control-group.warning select:focus, .control-group.warning textarea:focus { border-color: #a47e3c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; } .control-group.warning .input-prepend .add-on, .control-group.warning .input-append .add-on { color: #c09853; background-color: #fcf8e3; border-color: #c09853; } .control-group.error .control-label, .control-group.error .help-block, .control-group.error .help-inline { color: #b94a48; } .control-group.error .checkbox, .control-group.error .radio, .control-group.error input, .control-group.error select, .control-group.error textarea { color: #b94a48; } .control-group.error input, .control-group.error select, .control-group.error textarea { border-color: #b94a48; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .control-group.error input:focus, .control-group.error select:focus, .control-group.error textarea:focus { border-color: #953b39; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; } .control-group.error .input-prepend .add-on, .control-group.error .input-append .add-on { color: #b94a48; background-color: #f2dede; border-color: #b94a48; } .control-group.success .control-label, .control-group.success .help-block, .control-group.success .help-inline { color: #468847; } .control-group.success .checkbox, .control-group.success .radio, .control-group.success input, .control-group.success select, .control-group.success textarea { color: #468847; } .control-group.success input, .control-group.success select, .control-group.success textarea { border-color: #468847; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .control-group.success input:focus, .control-group.success select:focus, .control-group.success textarea:focus { border-color: #356635; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; } .control-group.success .input-prepend .add-on, .control-group.success .input-append .add-on { color: #468847; background-color: #dff0d8; border-color: #468847; } .control-group.info .control-label, .control-group.info .help-block, .control-group.info .help-inline { color: #3a87ad; } .control-group.info .checkbox, .control-group.info .radio, .control-group.info input, .control-group.info select, .control-group.info textarea { color: #3a87ad; } .control-group.info input, .control-group.info select, .control-group.info textarea { border-color: #3a87ad; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .control-group.info input:focus, .control-group.info select:focus, .control-group.info textarea:focus { border-color: #2d6987; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; } .control-group.info .input-prepend .add-on, .control-group.info .input-append .add-on { color: #3a87ad; background-color: #d9edf7; border-color: #3a87ad; } input:focus:invalid, textarea:focus:invalid, select:focus:invalid { color: #b94a48; border-color: #ee5f5b; } input:focus:invalid:focus, textarea:focus:invalid:focus, select:focus:invalid:focus { border-color: #e9322d; -webkit-box-shadow: 0 0 6px #f8b9b7; -moz-box-shadow: 0 0 6px #f8b9b7; box-shadow: 0 0 6px #f8b9b7; } .form-actions { padding: 19px 20px 20px; margin-top: 20px; margin-bottom: 20px; background-color: #f5f5f5; border-top: 1px solid #e5e5e5; *zoom: 1; } .form-actions:before, .form-actions:after { display: table; line-height: 0; content: ""; } .form-actions:after { clear: both; } .help-block, .help-inline { color: #595959; } .help-block { display: block; margin-bottom: 10px; } .help-inline { display: inline-block; *display: inline; padding-left: 5px; vertical-align: middle; *zoom: 1; } .input-append, .input-prepend { display: inline-block; margin-bottom: 10px; font-size: 0; white-space: nowrap; vertical-align: middle; } .input-append input, .input-prepend input, .input-append select, .input-prepend select, .input-append .uneditable-input, .input-prepend .uneditable-input, .input-append .dropdown-menu, .input-prepend .dropdown-menu, .input-append .popover, .input-prepend .popover { font-size: 14px; } .input-append input, .input-prepend input, .input-append select, .input-prepend select, .input-append .uneditable-input, .input-prepend .uneditable-input { position: relative; margin-bottom: 0; *margin-left: 0; vertical-align: top; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; } .input-append input:focus, .input-prepend input:focus, .input-append select:focus, .input-prepend select:focus, .input-append .uneditable-input:focus, .input-prepend .uneditable-input:focus { z-index: 2; } .input-append .add-on, .input-prepend .add-on { display: inline-block; width: auto; height: 20px; min-width: 16px; padding: 4px 5px; font-size: 14px; font-weight: normal; line-height: 20px; text-align: center; text-shadow: 0 1px 0 #ffffff; background-color: #eeeeee; border: 1px solid #ccc; } .input-append .add-on, .input-prepend .add-on, .input-append .btn, .input-prepend .btn, .input-append .btn-group > .dropdown-toggle, .input-prepend .btn-group > .dropdown-toggle { vertical-align: top; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .input-append .active, .input-prepend .active { background-color: #a9dba9; border-color: #46a546; } .input-prepend .add-on, .input-prepend .btn { margin-right: -1px; } .input-prepend .add-on:first-child, .input-prepend .btn:first-child { -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px; } .input-append input, .input-append select, .input-append .uneditable-input { -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px; } .input-append input + .btn-group .btn:last-child, .input-append select + .btn-group .btn:last-child, .input-append .uneditable-input + .btn-group .btn:last-child { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; } .input-append .add-on, .input-append .btn, .input-append .btn-group { margin-left: -1px; } .input-append .add-on:last-child, .input-append .btn:last-child, .input-append .btn-group:last-child > .dropdown-toggle { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; } .input-prepend.input-append input, .input-prepend.input-append select, .input-prepend.input-append .uneditable-input { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .input-prepend.input-append input + .btn-group .btn, .input-prepend.input-append select + .btn-group .btn, .input-prepend.input-append .uneditable-input + .btn-group .btn { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; } .input-prepend.input-append .add-on:first-child, .input-prepend.input-append .btn:first-child { margin-right: -1px; -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px; } .input-prepend.input-append .add-on:last-child, .input-prepend.input-append .btn:last-child { margin-left: -1px; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; } .input-prepend.input-append .btn-group:first-child { margin-left: 0; } input.search-query { padding-right: 14px; padding-right: 4px \9; padding-left: 14px; padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ margin-bottom: 0; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } /* Allow for input prepend/append in search forms */ .form-search .input-append .search-query, .form-search .input-prepend .search-query { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .form-search .input-append .search-query { -webkit-border-radius: 14px 0 0 14px; -moz-border-radius: 14px 0 0 14px; border-radius: 14px 0 0 14px; } .form-search .input-append .btn { -webkit-border-radius: 0 14px 14px 0; -moz-border-radius: 0 14px 14px 0; border-radius: 0 14px 14px 0; } .form-search .input-prepend .search-query { -webkit-border-radius: 0 14px 14px 0; -moz-border-radius: 0 14px 14px 0; border-radius: 0 14px 14px 0; } .form-search .input-prepend .btn { -webkit-border-radius: 14px 0 0 14px; -moz-border-radius: 14px 0 0 14px; border-radius: 14px 0 0 14px; } .form-search input, .form-inline input, .form-horizontal input, .form-search textarea, .form-inline textarea, .form-horizontal textarea, .form-search select, .form-inline select, .form-horizontal select, .form-search .help-inline, .form-inline .help-inline, .form-horizontal .help-inline, .form-search .uneditable-input, .form-inline .uneditable-input, .form-horizontal .uneditable-input, .form-search .input-prepend, .form-inline .input-prepend, .form-horizontal .input-prepend, .form-search .input-append, .form-inline .input-append, .form-horizontal .input-append { display: inline-block; *display: inline; margin-bottom: 0; vertical-align: middle; *zoom: 1; } .form-search .hide, .form-inline .hide, .form-horizontal .hide { display: none; } .form-search label, .form-inline label, .form-search .btn-group, .form-inline .btn-group { display: inline-block; } .form-search .input-append, .form-inline .input-append, .form-search .input-prepend, .form-inline .input-prepend { margin-bottom: 0; } .form-search .radio, .form-search .checkbox, .form-inline .radio, .form-inline .checkbox { padding-left: 0; margin-bottom: 0; vertical-align: middle; } .form-search .radio input[type="radio"], .form-search .checkbox input[type="checkbox"], .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { float: left; margin-right: 3px; margin-left: 0; } .control-group { margin-bottom: 10px; } legend + .control-group { margin-top: 20px; -webkit-margin-top-collapse: separate; } .form-horizontal .control-group { margin-bottom: 20px; *zoom: 1; } .form-horizontal .control-group:before, .form-horizontal .control-group:after { display: table; line-height: 0; content: ""; } .form-horizontal .control-group:after { clear: both; } .form-horizontal .control-label { float: left; width: 160px; padding-top: 5px; text-align: right; } .form-horizontal .controls { *display: inline-block; *padding-left: 20px; margin-left: 180px; *margin-left: 0; } .form-horizontal .controls:first-child { *padding-left: 180px; } .form-horizontal .help-block { margin-bottom: 0; } .form-horizontal input + .help-block, .form-horizontal select + .help-block, .form-horizontal textarea + .help-block, .form-horizontal .uneditable-input + .help-block, .form-horizontal .input-prepend + .help-block, .form-horizontal .input-append + .help-block { margin-top: 10px; } .form-horizontal .form-actions { padding-left: 180px; } table { max-width: 100%; background-color: transparent; border-collapse: collapse; border-spacing: 0; } .table { width: 100%; margin-bottom: 20px; } .table th, .table td { padding: 8px; line-height: 20px; text-align: left; vertical-align: top; border-top: 1px solid #dddddd; } .table th { font-weight: bold; } .table thead th { vertical-align: bottom; } .table caption + thead tr:first-child th, .table caption + thead tr:first-child td, .table colgroup + thead tr:first-child th, .table colgroup + thead tr:first-child td, .table thead:first-child tr:first-child th, .table thead:first-child tr:first-child td { border-top: 0; } .table tbody + tbody { border-top: 2px solid #dddddd; } .table .table { background-color: #ffffff; } .table-condensed th, .table-condensed td { padding: 4px 5px; } .table-bordered { border: 1px solid #dddddd; border-collapse: separate; *border-collapse: collapse; border-left: 0; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .table-bordered th, .table-bordered td { border-left: 1px solid #dddddd; } .table-bordered caption + thead tr:first-child th, .table-bordered caption + tbody tr:first-child th, .table-bordered caption + tbody tr:first-child td, .table-bordered colgroup + thead tr:first-child th, .table-bordered colgroup + tbody tr:first-child th, .table-bordered colgroup + tbody tr:first-child td, .table-bordered thead:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child td { border-top: 0; } .table-bordered thead:first-child tr:first-child > th:first-child, .table-bordered tbody:first-child tr:first-child > td:first-child, .table-bordered tbody:first-child tr:first-child > th:first-child { -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topleft: 4px; } .table-bordered thead:first-child tr:first-child > th:last-child, .table-bordered tbody:first-child tr:first-child > td:last-child, .table-bordered tbody:first-child tr:first-child > th:last-child { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-topright: 4px; } .table-bordered thead:last-child tr:last-child > th:first-child, .table-bordered tbody:last-child tr:last-child > td:first-child, .table-bordered tbody:last-child tr:last-child > th:first-child, .table-bordered tfoot:last-child tr:last-child > td:first-child, .table-bordered tfoot:last-child tr:last-child > th:first-child { -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomleft: 4px; } .table-bordered thead:last-child tr:last-child > th:last-child, .table-bordered tbody:last-child tr:last-child > td:last-child, .table-bordered tbody:last-child tr:last-child > th:last-child, .table-bordered tfoot:last-child tr:last-child > td:last-child, .table-bordered tfoot:last-child tr:last-child > th:last-child { -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -moz-border-radius-bottomright: 4px; } .table-bordered tfoot + tbody:last-child tr:last-child td:first-child { -webkit-border-bottom-left-radius: 0; border-bottom-left-radius: 0; -moz-border-radius-bottomleft: 0; } .table-bordered tfoot + tbody:last-child tr:last-child td:last-child { -webkit-border-bottom-right-radius: 0; border-bottom-right-radius: 0; -moz-border-radius-bottomright: 0; } .table-bordered caption + thead tr:first-child th:first-child, .table-bordered caption + tbody tr:first-child td:first-child, .table-bordered colgroup + thead tr:first-child th:first-child, .table-bordered colgroup + tbody tr:first-child td:first-child { -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topleft: 4px; } .table-bordered caption + thead tr:first-child th:last-child, .table-bordered caption + tbody tr:first-child td:last-child, .table-bordered colgroup + thead tr:first-child th:last-child, .table-bordered colgroup + tbody tr:first-child td:last-child { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-topright: 4px; } .table-striped tbody > tr:nth-child(odd) > td, .table-striped tbody > tr:nth-child(odd) > th { background-color: #f9f9f9; } .table-hover tbody tr:hover > td, .table-hover tbody tr:hover > th { background-color: #f5f5f5; } table td[class*="span"], table th[class*="span"], .row-fluid table td[class*="span"], .row-fluid table th[class*="span"] { display: table-cell; float: none; margin-left: 0; } .table td.span1, .table th.span1 { float: none; width: 44px; margin-left: 0; } .table td.span2, .table th.span2 { float: none; width: 124px; margin-left: 0; } .table td.span3, .table th.span3 { float: none; width: 204px; margin-left: 0; } .table td.span4, .table th.span4 { float: none; width: 284px; margin-left: 0; } .table td.span5, .table th.span5 { float: none; width: 364px; margin-left: 0; } .table td.span6, .table th.span6 { float: none; width: 444px; margin-left: 0; } .table td.span7, .table th.span7 { float: none; width: 524px; margin-left: 0; } .table td.span8, .table th.span8 { float: none; width: 604px; margin-left: 0; } .table td.span9, .table th.span9 { float: none; width: 684px; margin-left: 0; } .table td.span10, .table th.span10 { float: none; width: 764px; margin-left: 0; } .table td.span11, .table th.span11 { float: none; width: 844px; margin-left: 0; } .table td.span12, .table th.span12 { float: none; width: 924px; margin-left: 0; } .table tbody tr.success > td { background-color: #dff0d8; } .table tbody tr.error > td { background-color: #f2dede; } .table tbody tr.warning > td { background-color: #fcf8e3; } .table tbody tr.info > td { background-color: #d9edf7; } .table-hover tbody tr.success:hover > td { background-color: #d0e9c6; } .table-hover tbody tr.error:hover > td { background-color: #ebcccc; } .table-hover tbody tr.warning:hover > td { background-color: #faf2cc; } .table-hover tbody tr.info:hover > td { background-color: #c4e3f3; } [class^="icon-"], [class*=" icon-"] { display: inline-block; width: 14px; height: 14px; margin-top: 1px; *margin-right: .3em; line-height: 14px; vertical-align: text-top; background-image: url("../img/glyphicons-halflings.png"); background-position: 14px 14px; background-repeat: no-repeat; } /* White icons with optional class, or on hover/focus/active states of certain elements */ .icon-white, .nav-pills > .active > a > [class^="icon-"], .nav-pills > .active > a > [class*=" icon-"], .nav-list > .active > a > [class^="icon-"], .nav-list > .active > a > [class*=" icon-"], .navbar-inverse .nav > .active > a > [class^="icon-"], .navbar-inverse .nav > .active > a > [class*=" icon-"], .dropdown-menu > li > a:hover > [class^="icon-"], .dropdown-menu > li > a:focus > [class^="icon-"], .dropdown-menu > li > a:hover > [class*=" icon-"], .dropdown-menu > li > a:focus > [class*=" icon-"], .dropdown-menu > .active > a > [class^="icon-"], .dropdown-menu > .active > a > [class*=" icon-"], .dropdown-submenu:hover > a > [class^="icon-"], .dropdown-submenu:focus > a > [class^="icon-"], .dropdown-submenu:hover > a > [class*=" icon-"], .dropdown-submenu:focus > a > [class*=" icon-"] { background-image: url("../img/glyphicons-halflings-white.png"); } .icon-glass { background-position: 0 0; } .icon-music { background-position: -24px 0; } .icon-search { background-position: -48px 0; } .icon-envelope { background-position: -72px 0; } .icon-heart { background-position: -96px 0; } .icon-star { background-position: -120px 0; } .icon-star-empty { background-position: -144px 0; } .icon-user { background-position: -168px 0; } .icon-film { background-position: -192px 0; } .icon-th-large { background-position: -216px 0; } .icon-th { background-position: -240px 0; } .icon-th-list { background-position: -264px 0; } .icon-ok { background-position: -288px 0; } .icon-remove { background-position: -312px 0; } .icon-zoom-in { background-position: -336px 0; } .icon-zoom-out { background-position: -360px 0; } .icon-off { background-position: -384px 0; } .icon-signal { background-position: -408px 0; } .icon-cog { background-position: -432px 0; } .icon-trash { background-position: -456px 0; } .icon-home { background-position: 0 -24px; } .icon-file { background-position: -24px -24px; } .icon-time { background-position: -48px -24px; } .icon-road { background-position: -72px -24px; } .icon-download-alt { background-position: -96px -24px; } .icon-download { background-position: -120px -24px; } .icon-upload { background-position: -144px -24px; } .icon-inbox { background-position: -168px -24px; } .icon-play-circle { background-position: -192px -24px; } .icon-repeat { background-position: -216px -24px; } .icon-refresh { background-position: -240px -24px; } .icon-list-alt { background-position: -264px -24px; } .icon-lock { background-position: -287px -24px; } .icon-flag { background-position: -312px -24px; } .icon-headphones { background-position: -336px -24px; } .icon-volume-off { background-position: -360px -24px; } .icon-volume-down { background-position: -384px -24px; } .icon-volume-up { background-position: -408px -24px; } .icon-qrcode { background-position: -432px -24px; } .icon-barcode { background-position: -456px -24px; } .icon-tag { background-position: 0 -48px; } .icon-tags { background-position: -25px -48px; } .icon-book { background-position: -48px -48px; } .icon-bookmark { background-position: -72px -48px; } .icon-print { background-position: -96px -48px; } .icon-camera { background-position: -120px -48px; } .icon-font { background-position: -144px -48px; } .icon-bold { background-position: -167px -48px; } .icon-italic { background-position: -192px -48px; } .icon-text-height { background-position: -216px -48px; } .icon-text-width { background-position: -240px -48px; } .icon-align-left { background-position: -264px -48px; } .icon-align-center { background-position: -288px -48px; } .icon-align-right { background-position: -312px -48px; } .icon-align-justify { background-position: -336px -48px; } .icon-list { background-position: -360px -48px; } .icon-indent-left { background-position: -384px -48px; } .icon-indent-right { background-position: -408px -48px; } .icon-facetime-video { background-position: -432px -48px; } .icon-picture { background-position: -456px -48px; } .icon-pencil { background-position: 0 -72px; } .icon-map-marker { background-position: -24px -72px; } .icon-adjust { background-position: -48px -72px; } .icon-tint { background-position: -72px -72px; } .icon-edit { background-position: -96px -72px; } .icon-share { background-position: -120px -72px; } .icon-check { background-position: -144px -72px; } .icon-move { background-position: -168px -72px; } .icon-step-backward { background-position: -192px -72px; } .icon-fast-backward { background-position: -216px -72px; } .icon-backward { background-position: -240px -72px; } .icon-play { background-position: -264px -72px; } .icon-pause { background-position: -288px -72px; } .icon-stop { background-position: -312px -72px; } .icon-forward { background-position: -336px -72px; } .icon-fast-forward { background-position: -360px -72px; } .icon-step-forward { background-position: -384px -72px; } .icon-eject { background-position: -408px -72px; } .icon-chevron-left { background-position: -432px -72px; } .icon-chevron-right { background-position: -456px -72px; } .icon-plus-sign { background-position: 0 -96px; } .icon-minus-sign { background-position: -24px -96px; } .icon-remove-sign { background-position: -48px -96px; } .icon-ok-sign { background-position: -72px -96px; } .icon-question-sign { background-position: -96px -96px; } .icon-info-sign { background-position: -120px -96px; } .icon-screenshot { background-position: -144px -96px; } .icon-remove-circle { background-position: -168px -96px; } .icon-ok-circle { background-position: -192px -96px; } .icon-ban-circle { background-position: -216px -96px; } .icon-arrow-left { background-position: -240px -96px; } .icon-arrow-right { background-position: -264px -96px; } .icon-arrow-up { background-position: -289px -96px; } .icon-arrow-down { background-position: -312px -96px; } .icon-share-alt { background-position: -336px -96px; } .icon-resize-full { background-position: -360px -96px; } .icon-resize-small { background-position: -384px -96px; } .icon-plus { background-position: -408px -96px; } .icon-minus { background-position: -433px -96px; } .icon-asterisk { background-position: -456px -96px; } .icon-exclamation-sign { background-position: 0 -120px; } .icon-gift { background-position: -24px -120px; } .icon-leaf { background-position: -48px -120px; } .icon-fire { background-position: -72px -120px; } .icon-eye-open { background-position: -96px -120px; } .icon-eye-close { background-position: -120px -120px; } .icon-warning-sign { background-position: -144px -120px; } .icon-plane { background-position: -168px -120px; } .icon-calendar { background-position: -192px -120px; } .icon-random { width: 16px; background-position: -216px -120px; } .icon-comment { background-position: -240px -120px; } .icon-magnet { background-position: -264px -120px; } .icon-chevron-up { background-position: -288px -120px; } .icon-chevron-down { background-position: -313px -119px; } .icon-retweet { background-position: -336px -120px; } .icon-shopping-cart { background-position: -360px -120px; } .icon-folder-close { width: 16px; background-position: -384px -120px; } .icon-folder-open { width: 16px; background-position: -408px -120px; } .icon-resize-vertical { background-position: -432px -119px; } .icon-resize-horizontal { background-position: -456px -118px; } .icon-hdd { background-position: 0 -144px; } .icon-bullhorn { background-position: -24px -144px; } .icon-bell { background-position: -48px -144px; } .icon-certificate { background-position: -72px -144px; } .icon-thumbs-up { background-position: -96px -144px; } .icon-thumbs-down { background-position: -120px -144px; } .icon-hand-right { background-position: -144px -144px; } .icon-hand-left { background-position: -168px -144px; } .icon-hand-up { background-position: -192px -144px; } .icon-hand-down { background-position: -216px -144px; } .icon-circle-arrow-right { background-position: -240px -144px; } .icon-circle-arrow-left { background-position: -264px -144px; } .icon-circle-arrow-up { background-position: -288px -144px; } .icon-circle-arrow-down { background-position: -312px -144px; } .icon-globe { background-position: -336px -144px; } .icon-wrench { background-position: -360px -144px; } .icon-tasks { background-position: -384px -144px; } .icon-filter { background-position: -408px -144px; } .icon-briefcase { background-position: -432px -144px; } .icon-fullscreen { background-position: -456px -144px; } .dropup, .dropdown { position: relative; } .dropdown-toggle { *margin-bottom: -3px; } .dropdown-toggle:active, .open .dropdown-toggle { outline: 0; } .caret { display: inline-block; width: 0; height: 0; vertical-align: top; border-top: 4px solid #000000; border-right: 4px solid transparent; border-left: 4px solid transparent; content: ""; } .dropdown .caret { margin-top: 8px; margin-left: 2px; } .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; background-color: #ffffff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); *border-right-width: 2px; *border-bottom-width: 2px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box; } .dropdown-menu.pull-right { right: 0; left: auto; } .dropdown-menu .divider { *width: 100%; height: 1px; margin: 9px 1px; *margin: -5px 0 5px; overflow: hidden; background-color: #e5e5e5; border-bottom: 1px solid #ffffff; } .dropdown-menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 20px; color: #333333; white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a { color: #ffffff; text-decoration: none; background-color: #0081c2; background-image: -moz-linear-gradient(top, #0088cc, #0077b3); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); background-image: -o-linear-gradient(top, #0088cc, #0077b3); background-image: linear-gradient(to bottom, #0088cc, #0077b3); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { color: #ffffff; text-decoration: none; background-color: #0081c2; background-image: -moz-linear-gradient(top, #0088cc, #0077b3); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); background-image: -o-linear-gradient(top, #0088cc, #0077b3); background-image: linear-gradient(to bottom, #0088cc, #0077b3); background-repeat: repeat-x; outline: 0; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { color: #999999; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { text-decoration: none; cursor: default; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .open { *z-index: 1000; } .open > .dropdown-menu { display: block; } .dropdown-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 990; } .pull-right > .dropdown-menu { right: 0; left: auto; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { border-top: 0; border-bottom: 4px solid #000000; content: ""; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 1px; } .dropdown-submenu { position: relative; } .dropdown-submenu > .dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; -webkit-border-radius: 0 6px 6px 6px; -moz-border-radius: 0 6px 6px 6px; border-radius: 0 6px 6px 6px; } .dropdown-submenu:hover > .dropdown-menu { display: block; } .dropup .dropdown-submenu > .dropdown-menu { top: auto; bottom: 0; margin-top: 0; margin-bottom: -2px; -webkit-border-radius: 5px 5px 5px 0; -moz-border-radius: 5px 5px 5px 0; border-radius: 5px 5px 5px 0; } .dropdown-submenu > a:after { display: block; float: right; width: 0; height: 0; margin-top: 5px; margin-right: -10px; border-color: transparent; border-left-color: #cccccc; border-style: solid; border-width: 5px 0 5px 5px; content: " "; } .dropdown-submenu:hover > a:after { border-left-color: #ffffff; } .dropdown-submenu.pull-left { float: none; } .dropdown-submenu.pull-left > .dropdown-menu { left: -100%; margin-left: 10px; -webkit-border-radius: 6px 0 6px 6px; -moz-border-radius: 6px 0 6px 6px; border-radius: 6px 0 6px 6px; } .dropdown .dropdown-menu .nav-header { padding-right: 20px; padding-left: 20px; } .typeahead { z-index: 1051; margin-top: 2px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .well { min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); } .well blockquote { border-color: #ddd; border-color: rgba(0, 0, 0, 0.15); } .well-large { padding: 24px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .well-small { padding: 9px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .fade { opacity: 0; -webkit-transition: opacity 0.15s linear; -moz-transition: opacity 0.15s linear; -o-transition: opacity 0.15s linear; transition: opacity 0.15s linear; } .fade.in { opacity: 1; } .collapse { position: relative; height: 0; overflow: hidden; -webkit-transition: height 0.35s ease; -moz-transition: height 0.35s ease; -o-transition: height 0.35s ease; transition: height 0.35s ease; } .collapse.in { height: auto; } .close { float: right; font-size: 20px; font-weight: bold; line-height: 20px; color: #000000; text-shadow: 0 1px 0 #ffffff; opacity: 0.2; filter: alpha(opacity=20); } .close:hover, .close:focus { color: #000000; text-decoration: none; cursor: pointer; opacity: 0.4; filter: alpha(opacity=40); } button.close { padding: 0; cursor: pointer; background: transparent; border: 0; -webkit-appearance: none; } .btn { display: inline-block; *display: inline; padding: 4px 12px; margin-bottom: 0; *margin-left: .3em; font-size: 14px; line-height: 20px; color: #333333; text-align: center; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); vertical-align: middle; cursor: pointer; background-color: #f5f5f5; *background-color: #e6e6e6; background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); background-repeat: repeat-x; border: 1px solid #cccccc; *border: 0; border-color: #e6e6e6 #e6e6e6 #bfbfbf; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); border-bottom-color: #b3b3b3; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); *zoom: 1; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .btn:hover, .btn:focus, .btn:active, .btn.active, .btn.disabled, .btn[disabled] { color: #333333; background-color: #e6e6e6; *background-color: #d9d9d9; } .btn:active, .btn.active { background-color: #cccccc \9; } .btn:first-child { *margin-left: 0; } .btn:hover, .btn:focus { color: #333333; text-decoration: none; background-position: 0 -15px; -webkit-transition: background-position 0.1s linear; -moz-transition: background-position 0.1s linear; -o-transition: background-position 0.1s linear; transition: background-position 0.1s linear; } .btn:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .btn.active, .btn:active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); } .btn.disabled, .btn[disabled] { cursor: default; background-image: none; opacity: 0.65; filter: alpha(opacity=65); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .btn-large { padding: 11px 19px; font-size: 17.5px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .btn-large [class^="icon-"], .btn-large [class*=" icon-"] { margin-top: 4px; } .btn-small { padding: 2px 10px; font-size: 11.9px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .btn-small [class^="icon-"], .btn-small [class*=" icon-"] { margin-top: 0; } .btn-mini [class^="icon-"], .btn-mini [class*=" icon-"] { margin-top: -1px; } .btn-mini { padding: 0 6px; font-size: 10.5px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .btn-block { display: block; width: 100%; padding-right: 0; padding-left: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .btn-block + .btn-block { margin-top: 5px; } input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { width: 100%; } .btn-primary.active, .btn-warning.active, .btn-danger.active, .btn-success.active, .btn-info.active, .btn-inverse.active { color: rgba(255, 255, 255, 0.75); } .btn-primary { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #006dcc; *background-color: #0044cc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(to bottom, #0088cc, #0044cc); background-repeat: repeat-x; border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] { color: #ffffff; background-color: #0044cc; *background-color: #003bb3; } .btn-primary:active, .btn-primary.active { background-color: #003399 \9; } .btn-warning { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #faa732; *background-color: #f89406; background-image: -moz-linear-gradient(top, #fbb450, #f89406); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); background-image: -webkit-linear-gradient(top, #fbb450, #f89406); background-image: -o-linear-gradient(top, #fbb450, #f89406); background-image: linear-gradient(to bottom, #fbb450, #f89406); background-repeat: repeat-x; border-color: #f89406 #f89406 #ad6704; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .btn-warning.disabled, .btn-warning[disabled] { color: #ffffff; background-color: #f89406; *background-color: #df8505; } .btn-warning:active, .btn-warning.active { background-color: #c67605 \9; } .btn-danger { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #da4f49; *background-color: #bd362f; background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); background-repeat: repeat-x; border-color: #bd362f #bd362f #802420; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .btn-danger.disabled, .btn-danger[disabled] { color: #ffffff; background-color: #bd362f; *background-color: #a9302a; } .btn-danger:active, .btn-danger.active { background-color: #942a25 \9; } .btn-success { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #5bb75b; *background-color: #51a351; background-image: -moz-linear-gradient(top, #62c462, #51a351); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); background-image: -webkit-linear-gradient(top, #62c462, #51a351); background-image: -o-linear-gradient(top, #62c462, #51a351); background-image: linear-gradient(to bottom, #62c462, #51a351); background-repeat: repeat-x; border-color: #51a351 #51a351 #387038; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .btn-success.disabled, .btn-success[disabled] { color: #ffffff; background-color: #51a351; *background-color: #499249; } .btn-success:active, .btn-success.active { background-color: #408140 \9; } .btn-info { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #49afcd; *background-color: #2f96b4; background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); background-repeat: repeat-x; border-color: #2f96b4 #2f96b4 #1f6377; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .btn-info.disabled, .btn-info[disabled] { color: #ffffff; background-color: #2f96b4; *background-color: #2a85a0; } .btn-info:active, .btn-info.active { background-color: #24748c \9; } .btn-inverse { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #363636; *background-color: #222222; background-image: -moz-linear-gradient(top, #444444, #222222); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); background-image: -webkit-linear-gradient(top, #444444, #222222); background-image: -o-linear-gradient(top, #444444, #222222); background-image: linear-gradient(to bottom, #444444, #222222); background-repeat: repeat-x; border-color: #222222 #222222 #000000; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .btn-inverse:hover, .btn-inverse:focus, .btn-inverse:active, .btn-inverse.active, .btn-inverse.disabled, .btn-inverse[disabled] { color: #ffffff; background-color: #222222; *background-color: #151515; } .btn-inverse:active, .btn-inverse.active { background-color: #080808 \9; } button.btn, input[type="submit"].btn { *padding-top: 3px; *padding-bottom: 3px; } button.btn::-moz-focus-inner, input[type="submit"].btn::-moz-focus-inner { padding: 0; border: 0; } button.btn.btn-large, input[type="submit"].btn.btn-large { *padding-top: 7px; *padding-bottom: 7px; } button.btn.btn-small, input[type="submit"].btn.btn-small { *padding-top: 3px; *padding-bottom: 3px; } button.btn.btn-mini, input[type="submit"].btn.btn-mini { *padding-top: 1px; *padding-bottom: 1px; } .btn-link, .btn-link:active, .btn-link[disabled] { background-color: transparent; background-image: none; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .btn-link { color: #0088cc; cursor: pointer; border-color: transparent; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .btn-link:hover, .btn-link:focus { color: #005580; text-decoration: underline; background-color: transparent; } .btn-link[disabled]:hover, .btn-link[disabled]:focus { color: #333333; text-decoration: none; } .btn-group { position: relative; display: inline-block; *display: inline; *margin-left: .3em; font-size: 0; white-space: nowrap; vertical-align: middle; *zoom: 1; } .btn-group:first-child { *margin-left: 0; } .btn-group + .btn-group { margin-left: 5px; } .btn-toolbar { margin-top: 10px; margin-bottom: 10px; font-size: 0; } .btn-toolbar > .btn + .btn, .btn-toolbar > .btn-group + .btn, .btn-toolbar > .btn + .btn-group { margin-left: 5px; } .btn-group > .btn { position: relative; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .btn-group > .btn + .btn { margin-left: -1px; } .btn-group > .btn, .btn-group > .dropdown-menu, .btn-group > .popover { font-size: 14px; } .btn-group > .btn-mini { font-size: 10.5px; } .btn-group > .btn-small { font-size: 11.9px; } .btn-group > .btn-large { font-size: 17.5px; } .btn-group > .btn:first-child { margin-left: 0; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-topleft: 4px; } .btn-group > .btn:last-child, .btn-group > .dropdown-toggle { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-bottomright: 4px; } .btn-group > .btn.large:first-child { margin-left: 0; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -moz-border-radius-topleft: 6px; } .btn-group > .btn.large:last-child, .btn-group > .large.dropdown-toggle { -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; -moz-border-radius-topright: 6px; -moz-border-radius-bottomright: 6px; } .btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active { z-index: 2; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } .btn-group > .btn + .dropdown-toggle { *padding-top: 5px; padding-right: 8px; *padding-bottom: 5px; padding-left: 8px; -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .btn-group > .btn-mini + .dropdown-toggle { *padding-top: 2px; padding-right: 5px; *padding-bottom: 2px; padding-left: 5px; } .btn-group > .btn-small + .dropdown-toggle { *padding-top: 5px; *padding-bottom: 4px; } .btn-group > .btn-large + .dropdown-toggle { *padding-top: 7px; padding-right: 12px; *padding-bottom: 7px; padding-left: 12px; } .btn-group.open .dropdown-toggle { background-image: none; -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); } .btn-group.open .btn.dropdown-toggle { background-color: #e6e6e6; } .btn-group.open .btn-primary.dropdown-toggle { background-color: #0044cc; } .btn-group.open .btn-warning.dropdown-toggle { background-color: #f89406; } .btn-group.open .btn-danger.dropdown-toggle { background-color: #bd362f; } .btn-group.open .btn-success.dropdown-toggle { background-color: #51a351; } .btn-group.open .btn-info.dropdown-toggle { background-color: #2f96b4; } .btn-group.open .btn-inverse.dropdown-toggle { background-color: #222222; } .btn .caret { margin-top: 8px; margin-left: 0; } .btn-large .caret { margin-top: 6px; } .btn-large .caret { border-top-width: 5px; border-right-width: 5px; border-left-width: 5px; } .btn-mini .caret, .btn-small .caret { margin-top: 8px; } .dropup .btn-large .caret { border-bottom-width: 5px; } .btn-primary .caret, .btn-warning .caret, .btn-danger .caret, .btn-info .caret, .btn-success .caret, .btn-inverse .caret { border-top-color: #ffffff; border-bottom-color: #ffffff; } .btn-group-vertical { display: inline-block; *display: inline; /* IE7 inline-block hack */ *zoom: 1; } .btn-group-vertical > .btn { display: block; float: none; max-width: 100%; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .btn-group-vertical > .btn + .btn { margin-top: -1px; margin-left: 0; } .btn-group-vertical > .btn:first-child { -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } .btn-group-vertical > .btn:last-child { -webkit-border-radius: 0 0 4px 4px; -moz-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px; } .btn-group-vertical > .btn-large:first-child { -webkit-border-radius: 6px 6px 0 0; -moz-border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0; } .btn-group-vertical > .btn-large:last-child { -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; } .alert { padding: 8px 35px 8px 14px; margin-bottom: 20px; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); background-color: #fcf8e3; border: 1px solid #fbeed5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .alert, .alert h4 { color: #c09853; } .alert h4 { margin: 0; } .alert .close { position: relative; top: -2px; right: -21px; line-height: 20px; } .alert-success { color: #468847; background-color: #dff0d8; border-color: #d6e9c6; } .alert-success h4 { color: #468847; } .alert-danger, .alert-error { color: #b94a48; background-color: #f2dede; border-color: #eed3d7; } .alert-danger h4, .alert-error h4 { color: #b94a48; } .alert-info { color: #3a87ad; background-color: #d9edf7; border-color: #bce8f1; } .alert-info h4 { color: #3a87ad; } .alert-block { padding-top: 14px; padding-bottom: 14px; } .alert-block > p, .alert-block > ul { margin-bottom: 0; } .alert-block p + p { margin-top: 5px; } .nav { margin-bottom: 20px; margin-left: 0; list-style: none; } .nav > li > a { display: block; } .nav > li > a:hover, .nav > li > a:focus { text-decoration: none; background-color: #eeeeee; } .nav > li > a > img { max-width: none; } .nav > .pull-right { float: right; } .nav-header { display: block; padding: 3px 15px; font-size: 11px; font-weight: bold; line-height: 20px; color: #999999; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); text-transform: uppercase; } .nav li + .nav-header { margin-top: 9px; } .nav-list { padding-right: 15px; padding-left: 15px; margin-bottom: 0; } .nav-list > li > a, .nav-list .nav-header { margin-right: -15px; margin-left: -15px; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } .nav-list > li > a { padding: 3px 15px; } .nav-list > .active > a, .nav-list > .active > a:hover, .nav-list > .active > a:focus { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); background-color: #0088cc; } .nav-list [class^="icon-"], .nav-list [class*=" icon-"] { margin-right: 2px; } .nav-list .divider { *width: 100%; height: 1px; margin: 9px 1px; *margin: -5px 0 5px; overflow: hidden; background-color: #e5e5e5; border-bottom: 1px solid #ffffff; } .nav-tabs, .nav-pills { *zoom: 1; } .nav-tabs:before, .nav-pills:before, .nav-tabs:after, .nav-pills:after { display: table; line-height: 0; content: ""; } .nav-tabs:after, .nav-pills:after { clear: both; } .nav-tabs > li, .nav-pills > li { float: left; } .nav-tabs > li > a, .nav-pills > li > a { padding-right: 12px; padding-left: 12px; margin-right: 2px; line-height: 14px; } .nav-tabs { border-bottom: 1px solid #ddd; } .nav-tabs > li { margin-bottom: -1px; } .nav-tabs > li > a { padding-top: 8px; padding-bottom: 8px; line-height: 20px; border: 1px solid transparent; -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } .nav-tabs > li > a:hover, .nav-tabs > li > a:focus { border-color: #eeeeee #eeeeee #dddddd; } .nav-tabs > .active > a, .nav-tabs > .active > a:hover, .nav-tabs > .active > a:focus { color: #555555; cursor: default; background-color: #ffffff; border: 1px solid #ddd; border-bottom-color: transparent; } .nav-pills > li > a { padding-top: 8px; padding-bottom: 8px; margin-top: 2px; margin-bottom: 2px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .nav-pills > .active > a, .nav-pills > .active > a:hover, .nav-pills > .active > a:focus { color: #ffffff; background-color: #0088cc; } .nav-stacked > li { float: none; } .nav-stacked > li > a { margin-right: 0; } .nav-tabs.nav-stacked { border-bottom: 0; } .nav-tabs.nav-stacked > li > a { border: 1px solid #ddd; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .nav-tabs.nav-stacked > li:first-child > a { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-topleft: 4px; } .nav-tabs.nav-stacked > li:last-child > a { -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -moz-border-radius-bottomleft: 4px; } .nav-tabs.nav-stacked > li > a:hover, .nav-tabs.nav-stacked > li > a:focus { z-index: 2; border-color: #ddd; } .nav-pills.nav-stacked > li > a { margin-bottom: 3px; } .nav-pills.nav-stacked > li:last-child > a { margin-bottom: 1px; } .nav-tabs .dropdown-menu { -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; } .nav-pills .dropdown-menu { -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .nav .dropdown-toggle .caret { margin-top: 6px; border-top-color: #0088cc; border-bottom-color: #0088cc; } .nav .dropdown-toggle:hover .caret, .nav .dropdown-toggle:focus .caret { border-top-color: #005580; border-bottom-color: #005580; } /* move down carets for tabs */ .nav-tabs .dropdown-toggle .caret { margin-top: 8px; } .nav .active .dropdown-toggle .caret { border-top-color: #fff; border-bottom-color: #fff; } .nav-tabs .active .dropdown-toggle .caret { border-top-color: #555555; border-bottom-color: #555555; } .nav > .dropdown.active > a:hover, .nav > .dropdown.active > a:focus { cursor: pointer; } .nav-tabs .open .dropdown-toggle, .nav-pills .open .dropdown-toggle, .nav > li.dropdown.open.active > a:hover, .nav > li.dropdown.open.active > a:focus { color: #ffffff; background-color: #999999; border-color: #999999; } .nav li.dropdown.open .caret, .nav li.dropdown.open.active .caret, .nav li.dropdown.open a:hover .caret, .nav li.dropdown.open a:focus .caret { border-top-color: #ffffff; border-bottom-color: #ffffff; opacity: 1; filter: alpha(opacity=100); } .tabs-stacked .open > a:hover, .tabs-stacked .open > a:focus { border-color: #999999; } .tabbable { *zoom: 1; } .tabbable:before, .tabbable:after { display: table; line-height: 0; content: ""; } .tabbable:after { clear: both; } .tab-content { overflow: auto; } .tabs-below > .nav-tabs, .tabs-right > .nav-tabs, .tabs-left > .nav-tabs { border-bottom: 0; } .tab-content > .tab-pane, .pill-content > .pill-pane { display: none; } .tab-content > .active, .pill-content > .active { display: block; } .tabs-below > .nav-tabs { border-top: 1px solid #ddd; } .tabs-below > .nav-tabs > li { margin-top: -1px; margin-bottom: 0; } .tabs-below > .nav-tabs > li > a { -webkit-border-radius: 0 0 4px 4px; -moz-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px; } .tabs-below > .nav-tabs > li > a:hover, .tabs-below > .nav-tabs > li > a:focus { border-top-color: #ddd; border-bottom-color: transparent; } .tabs-below > .nav-tabs > .active > a, .tabs-below > .nav-tabs > .active > a:hover, .tabs-below > .nav-tabs > .active > a:focus { border-color: transparent #ddd #ddd #ddd; } .tabs-left > .nav-tabs > li, .tabs-right > .nav-tabs > li { float: none; } .tabs-left > .nav-tabs > li > a, .tabs-right > .nav-tabs > li > a { min-width: 74px; margin-right: 0; margin-bottom: 3px; } .tabs-left > .nav-tabs { float: left; margin-right: 19px; border-right: 1px solid #ddd; } .tabs-left > .nav-tabs > li > a { margin-right: -1px; -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px; } .tabs-left > .nav-tabs > li > a:hover, .tabs-left > .nav-tabs > li > a:focus { border-color: #eeeeee #dddddd #eeeeee #eeeeee; } .tabs-left > .nav-tabs .active > a, .tabs-left > .nav-tabs .active > a:hover, .tabs-left > .nav-tabs .active > a:focus { border-color: #ddd transparent #ddd #ddd; *border-right-color: #ffffff; } .tabs-right > .nav-tabs { float: right; margin-left: 19px; border-left: 1px solid #ddd; } .tabs-right > .nav-tabs > li > a { margin-left: -1px; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; } .tabs-right > .nav-tabs > li > a:hover, .tabs-right > .nav-tabs > li > a:focus { border-color: #eeeeee #eeeeee #eeeeee #dddddd; } .tabs-right > .nav-tabs .active > a, .tabs-right > .nav-tabs .active > a:hover, .tabs-right > .nav-tabs .active > a:focus { border-color: #ddd #ddd #ddd transparent; *border-left-color: #ffffff; } .nav > .disabled > a { color: #999999; } .nav > .disabled > a:hover, .nav > .disabled > a:focus { text-decoration: none; cursor: default; background-color: transparent; } .navbar { *position: relative; *z-index: 2; margin-bottom: 20px; overflow: visible; } .navbar-inner { min-height: 40px; padding-right: 20px; padding-left: 20px; background-color: #fafafa; background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); background-repeat: repeat-x; border: 1px solid #d4d4d4; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); *zoom: 1; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); } .navbar-inner:before, .navbar-inner:after { display: table; line-height: 0; content: ""; } .navbar-inner:after { clear: both; } .navbar .container { width: auto; } .nav-collapse.collapse { height: auto; overflow: visible; } .navbar .brand { display: block; float: left; padding: 10px 20px 10px; margin-left: -20px; font-size: 20px; font-weight: 200; color: #777777; text-shadow: 0 1px 0 #ffffff; } .navbar .brand:hover, .navbar .brand:focus { text-decoration: none; } .navbar-text { margin-bottom: 0; line-height: 40px; color: #777777; } .navbar-link { color: #777777; } .navbar-link:hover, .navbar-link:focus { color: #333333; } .navbar .divider-vertical { height: 40px; margin: 0 9px; border-right: 1px solid #ffffff; border-left: 1px solid #f2f2f2; } .navbar .btn, .navbar .btn-group { margin-top: 5px; } .navbar .btn-group .btn, .navbar .input-prepend .btn, .navbar .input-append .btn, .navbar .input-prepend .btn-group, .navbar .input-append .btn-group { margin-top: 0; } .navbar-form { margin-bottom: 0; *zoom: 1; } .navbar-form:before, .navbar-form:after { display: table; line-height: 0; content: ""; } .navbar-form:after { clear: both; } .navbar-form input, .navbar-form select, .navbar-form .radio, .navbar-form .checkbox { margin-top: 5px; } .navbar-form input, .navbar-form select, .navbar-form .btn { display: inline-block; margin-bottom: 0; } .navbar-form input[type="image"], .navbar-form input[type="checkbox"], .navbar-form input[type="radio"] { margin-top: 3px; } .navbar-form .input-append, .navbar-form .input-prepend { margin-top: 5px; white-space: nowrap; } .navbar-form .input-append input, .navbar-form .input-prepend input { margin-top: 0; } .navbar-search { position: relative; float: left; margin-top: 5px; margin-bottom: 0; } .navbar-search .search-query { padding: 4px 14px; margin-bottom: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: normal; line-height: 1; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } .navbar-static-top { position: static; margin-bottom: 0; } .navbar-static-top .navbar-inner { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .navbar-fixed-top, .navbar-fixed-bottom { position: fixed; right: 0; left: 0; z-index: 1030; margin-bottom: 0; } .navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { border-width: 0 0 1px; } .navbar-fixed-bottom .navbar-inner { border-width: 1px 0 0; } .navbar-fixed-top .navbar-inner, .navbar-fixed-bottom .navbar-inner { padding-right: 0; padding-left: 0; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; } .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container { width: 940px; } .navbar-fixed-top { top: 0; } .navbar-fixed-top .navbar-inner, .navbar-static-top .navbar-inner { -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); } .navbar-fixed-bottom { bottom: 0; } .navbar-fixed-bottom .navbar-inner { -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); } .navbar .nav { position: relative; left: 0; display: block; float: left; margin: 0 10px 0 0; } .navbar .nav.pull-right { float: right; margin-right: 0; } .navbar .nav > li { float: left; } .navbar .nav > li > a { float: none; padding: 10px 15px 10px; color: #777777; text-decoration: none; text-shadow: 0 1px 0 #ffffff; } .navbar .nav .dropdown-toggle .caret { margin-top: 8px; } .navbar .nav > li > a:focus, .navbar .nav > li > a:hover { color: #333333; text-decoration: none; background-color: transparent; } .navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus { color: #555555; text-decoration: none; background-color: #e5e5e5; -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); } .navbar .btn-navbar { display: none; float: right; padding: 7px 10px; margin-right: 5px; margin-left: 5px; color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #ededed; *background-color: #e5e5e5; background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); background-repeat: repeat-x; border-color: #e5e5e5 #e5e5e5 #bfbfbf; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); } .navbar .btn-navbar:hover, .navbar .btn-navbar:focus, .navbar .btn-navbar:active, .navbar .btn-navbar.active, .navbar .btn-navbar.disabled, .navbar .btn-navbar[disabled] { color: #ffffff; background-color: #e5e5e5; *background-color: #d9d9d9; } .navbar .btn-navbar:active, .navbar .btn-navbar.active { background-color: #cccccc \9; } .navbar .btn-navbar .icon-bar { display: block; width: 18px; height: 2px; background-color: #f5f5f5; -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); } .btn-navbar .icon-bar + .icon-bar { margin-top: 3px; } .navbar .nav > li > .dropdown-menu:before { position: absolute; top: -7px; left: 9px; display: inline-block; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-left: 7px solid transparent; border-bottom-color: rgba(0, 0, 0, 0.2); content: ''; } .navbar .nav > li > .dropdown-menu:after { position: absolute; top: -6px; left: 10px; display: inline-block; border-right: 6px solid transparent; border-bottom: 6px solid #ffffff; border-left: 6px solid transparent; content: ''; } .navbar-fixed-bottom .nav > li > .dropdown-menu:before { top: auto; bottom: -7px; border-top: 7px solid #ccc; border-bottom: 0; border-top-color: rgba(0, 0, 0, 0.2); } .navbar-fixed-bottom .nav > li > .dropdown-menu:after { top: auto; bottom: -6px; border-top: 6px solid #ffffff; border-bottom: 0; } .navbar .nav li.dropdown > a:hover .caret, .navbar .nav li.dropdown > a:focus .caret { border-top-color: #333333; border-bottom-color: #333333; } .navbar .nav li.dropdown.open > .dropdown-toggle, .navbar .nav li.dropdown.active > .dropdown-toggle, .navbar .nav li.dropdown.open.active > .dropdown-toggle { color: #555555; background-color: #e5e5e5; } .navbar .nav li.dropdown > .dropdown-toggle .caret { border-top-color: #777777; border-bottom-color: #777777; } .navbar .nav li.dropdown.open > .dropdown-toggle .caret, .navbar .nav li.dropdown.active > .dropdown-toggle .caret, .navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { border-top-color: #555555; border-bottom-color: #555555; } .navbar .pull-right > li > .dropdown-menu, .navbar .nav > li > .dropdown-menu.pull-right { right: 0; left: auto; } .navbar .pull-right > li > .dropdown-menu:before, .navbar .nav > li > .dropdown-menu.pull-right:before { right: 12px; left: auto; } .navbar .pull-right > li > .dropdown-menu:after, .navbar .nav > li > .dropdown-menu.pull-right:after { right: 13px; left: auto; } .navbar .pull-right > li > .dropdown-menu .dropdown-menu, .navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { right: 100%; left: auto; margin-right: -1px; margin-left: 0; -webkit-border-radius: 6px 0 6px 6px; -moz-border-radius: 6px 0 6px 6px; border-radius: 6px 0 6px 6px; } .navbar-inverse .navbar-inner { background-color: #1b1b1b; background-image: -moz-linear-gradient(top, #222222, #111111); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); background-image: -webkit-linear-gradient(top, #222222, #111111); background-image: -o-linear-gradient(top, #222222, #111111); background-image: linear-gradient(to bottom, #222222, #111111); background-repeat: repeat-x; border-color: #252525; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); } .navbar-inverse .brand, .navbar-inverse .nav > li > a { color: #999999; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .navbar-inverse .brand:hover, .navbar-inverse .nav > li > a:hover, .navbar-inverse .brand:focus, .navbar-inverse .nav > li > a:focus { color: #ffffff; } .navbar-inverse .brand { color: #999999; } .navbar-inverse .navbar-text { color: #999999; } .navbar-inverse .nav > li > a:focus, .navbar-inverse .nav > li > a:hover { color: #ffffff; background-color: transparent; } .navbar-inverse .nav .active > a, .navbar-inverse .nav .active > a:hover, .navbar-inverse .nav .active > a:focus { color: #ffffff; background-color: #111111; } .navbar-inverse .navbar-link { color: #999999; } .navbar-inverse .navbar-link:hover, .navbar-inverse .navbar-link:focus { color: #ffffff; } .navbar-inverse .divider-vertical { border-right-color: #222222; border-left-color: #111111; } .navbar-inverse .nav li.dropdown.open > .dropdown-toggle, .navbar-inverse .nav li.dropdown.active > .dropdown-toggle, .navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { color: #ffffff; background-color: #111111; } .navbar-inverse .nav li.dropdown > a:hover .caret, .navbar-inverse .nav li.dropdown > a:focus .caret { border-top-color: #ffffff; border-bottom-color: #ffffff; } .navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { border-top-color: #999999; border-bottom-color: #999999; } .navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, .navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, .navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { border-top-color: #ffffff; border-bottom-color: #ffffff; } .navbar-inverse .navbar-search .search-query { color: #ffffff; background-color: #515151; border-color: #111111; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); -webkit-transition: none; -moz-transition: none; -o-transition: none; transition: none; } .navbar-inverse .navbar-search .search-query:-moz-placeholder { color: #cccccc; } .navbar-inverse .navbar-search .search-query:-ms-input-placeholder { color: #cccccc; } .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { color: #cccccc; } .navbar-inverse .navbar-search .search-query:focus, .navbar-inverse .navbar-search .search-query.focused { padding: 5px 15px; color: #333333; text-shadow: 0 1px 0 #ffffff; background-color: #ffffff; border: 0; outline: 0; -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); } .navbar-inverse .btn-navbar { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #0e0e0e; *background-color: #040404; background-image: -moz-linear-gradient(top, #151515, #040404); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); background-image: -webkit-linear-gradient(top, #151515, #040404); background-image: -o-linear-gradient(top, #151515, #040404); background-image: linear-gradient(to bottom, #151515, #040404); background-repeat: repeat-x; border-color: #040404 #040404 #000000; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .navbar-inverse .btn-navbar:hover, .navbar-inverse .btn-navbar:focus, .navbar-inverse .btn-navbar:active, .navbar-inverse .btn-navbar.active, .navbar-inverse .btn-navbar.disabled, .navbar-inverse .btn-navbar[disabled] { color: #ffffff; background-color: #040404; *background-color: #000000; } .navbar-inverse .btn-navbar:active, .navbar-inverse .btn-navbar.active { background-color: #000000 \9; } .breadcrumb { padding: 8px 15px; margin: 0 0 20px; list-style: none; background-color: #f5f5f5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .breadcrumb > li { display: inline-block; *display: inline; text-shadow: 0 1px 0 #ffffff; *zoom: 1; } .breadcrumb > li > .divider { padding: 0 5px; color: #ccc; } .breadcrumb > .active { color: #999999; } .pagination { margin: 20px 0; } .pagination ul { display: inline-block; *display: inline; margin-bottom: 0; margin-left: 0; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; *zoom: 1; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); } .pagination ul > li { display: inline; } .pagination ul > li > a, .pagination ul > li > span { float: left; padding: 4px 12px; line-height: 20px; text-decoration: none; background-color: #ffffff; border: 1px solid #dddddd; border-left-width: 0; } .pagination ul > li > a:hover, .pagination ul > li > a:focus, .pagination ul > .active > a, .pagination ul > .active > span { background-color: #f5f5f5; } .pagination ul > .active > a, .pagination ul > .active > span { color: #999999; cursor: default; } .pagination ul > .disabled > span, .pagination ul > .disabled > a, .pagination ul > .disabled > a:hover, .pagination ul > .disabled > a:focus { color: #999999; cursor: default; background-color: transparent; } .pagination ul > li:first-child > a, .pagination ul > li:first-child > span { border-left-width: 1px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-topleft: 4px; } .pagination ul > li:last-child > a, .pagination ul > li:last-child > span { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-bottomright: 4px; } .pagination-centered { text-align: center; } .pagination-right { text-align: right; } .pagination-large ul > li > a, .pagination-large ul > li > span { padding: 11px 19px; font-size: 17.5px; } .pagination-large ul > li:first-child > a, .pagination-large ul > li:first-child > span { -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -moz-border-radius-topleft: 6px; } .pagination-large ul > li:last-child > a, .pagination-large ul > li:last-child > span { -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; -moz-border-radius-topright: 6px; -moz-border-radius-bottomright: 6px; } .pagination-mini ul > li:first-child > a, .pagination-small ul > li:first-child > a, .pagination-mini ul > li:first-child > span, .pagination-small ul > li:first-child > span { -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-bottomleft: 3px; -moz-border-radius-topleft: 3px; } .pagination-mini ul > li:last-child > a, .pagination-small ul > li:last-child > a, .pagination-mini ul > li:last-child > span, .pagination-small ul > li:last-child > span { -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; -moz-border-radius-topright: 3px; -moz-border-radius-bottomright: 3px; } .pagination-small ul > li > a, .pagination-small ul > li > span { padding: 2px 10px; font-size: 11.9px; } .pagination-mini ul > li > a, .pagination-mini ul > li > span { padding: 0 6px; font-size: 10.5px; } .pager { margin: 20px 0; text-align: center; list-style: none; *zoom: 1; } .pager:before, .pager:after { display: table; line-height: 0; content: ""; } .pager:after { clear: both; } .pager li { display: inline; } .pager li > a, .pager li > span { display: inline-block; padding: 5px 14px; background-color: #fff; border: 1px solid #ddd; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { text-decoration: none; background-color: #f5f5f5; } .pager .next > a, .pager .next > span { float: right; } .pager .previous > a, .pager .previous > span { float: left; } .pager .disabled > a, .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { color: #999999; cursor: default; background-color: #fff; } .modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000000; } .modal-backdrop.fade { opacity: 0; } .modal-backdrop, .modal-backdrop.fade.in { opacity: 0.8; filter: alpha(opacity=80); } .modal { position: fixed; top: 10%; left: 50%; z-index: 1050; width: 560px; margin-left: -280px; background-color: #ffffff; border: 1px solid #999; border: 1px solid rgba(0, 0, 0, 0.3); *border: 1px solid #999; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; outline: none; -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); -webkit-background-clip: padding-box; -moz-background-clip: padding-box; background-clip: padding-box; } .modal.fade { top: -25%; -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; -moz-transition: opacity 0.3s linear, top 0.3s ease-out; -o-transition: opacity 0.3s linear, top 0.3s ease-out; transition: opacity 0.3s linear, top 0.3s ease-out; } .modal.fade.in { top: 10%; } .modal-header { padding: 9px 15px; border-bottom: 1px solid #eee; } .modal-header .close { margin-top: 2px; } .modal-header h3 { margin: 0; line-height: 30px; } .modal-body { position: relative; max-height: 400px; padding: 15px; overflow-y: auto; } .modal-form { margin-bottom: 0; } .modal-footer { padding: 14px 15px 15px; margin-bottom: 0; text-align: right; background-color: #f5f5f5; border-top: 1px solid #ddd; -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; *zoom: 1; -webkit-box-shadow: inset 0 1px 0 #ffffff; -moz-box-shadow: inset 0 1px 0 #ffffff; box-shadow: inset 0 1px 0 #ffffff; } .modal-footer:before, .modal-footer:after { display: table; line-height: 0; content: ""; } .modal-footer:after { clear: both; } .modal-footer .btn + .btn { margin-bottom: 0; margin-left: 5px; } .modal-footer .btn-group .btn + .btn { margin-left: -1px; } .modal-footer .btn-block + .btn-block { margin-left: 0; } .tooltip { position: absolute; z-index: 1030; display: block; font-size: 11px; line-height: 1.4; opacity: 0; filter: alpha(opacity=0); visibility: visible; } .tooltip.in { opacity: 0.8; filter: alpha(opacity=80); } .tooltip.top { padding: 5px 0; margin-top: -3px; } .tooltip.right { padding: 0 5px; margin-left: 3px; } .tooltip.bottom { padding: 5px 0; margin-top: 3px; } .tooltip.left { padding: 0 5px; margin-left: -3px; } .tooltip-inner { max-width: 200px; padding: 8px; color: #ffffff; text-align: center; text-decoration: none; background-color: #000000; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid; } .tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-color: #000000; border-width: 5px 5px 0; } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-right-color: #000000; border-width: 5px 5px 5px 0; } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-left-color: #000000; border-width: 5px 0 5px 5px; } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-bottom-color: #000000; border-width: 0 5px 5px; } .popover { position: absolute; top: 0; left: 0; z-index: 1010; display: none; max-width: 276px; padding: 1px; text-align: left; white-space: normal; background-color: #ffffff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box; } .popover.top { margin-top: -10px; } .popover.right { margin-left: 10px; } .popover.bottom { margin-top: 10px; } .popover.left { margin-left: -10px; } .popover-title { padding: 8px 14px; margin: 0; font-size: 14px; font-weight: normal; line-height: 18px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; -webkit-border-radius: 5px 5px 0 0; -moz-border-radius: 5px 5px 0 0; border-radius: 5px 5px 0 0; } .popover-title:empty { display: none; } .popover-content { padding: 9px 14px; } .popover .arrow, .popover .arrow:after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popover .arrow { border-width: 11px; } .popover .arrow:after { border-width: 10px; content: ""; } .popover.top .arrow { bottom: -11px; left: 50%; margin-left: -11px; border-top-color: #999; border-top-color: rgba(0, 0, 0, 0.25); border-bottom-width: 0; } .popover.top .arrow:after { bottom: 1px; margin-left: -10px; border-top-color: #ffffff; border-bottom-width: 0; } .popover.right .arrow { top: 50%; left: -11px; margin-top: -11px; border-right-color: #999; border-right-color: rgba(0, 0, 0, 0.25); border-left-width: 0; } .popover.right .arrow:after { bottom: -10px; left: 1px; border-right-color: #ffffff; border-left-width: 0; } .popover.bottom .arrow { top: -11px; left: 50%; margin-left: -11px; border-bottom-color: #999; border-bottom-color: rgba(0, 0, 0, 0.25); border-top-width: 0; } .popover.bottom .arrow:after { top: 1px; margin-left: -10px; border-bottom-color: #ffffff; border-top-width: 0; } .popover.left .arrow { top: 50%; right: -11px; margin-top: -11px; border-left-color: #999; border-left-color: rgba(0, 0, 0, 0.25); border-right-width: 0; } .popover.left .arrow:after { right: 1px; bottom: -10px; border-left-color: #ffffff; border-right-width: 0; } .thumbnails { margin-left: -20px; list-style: none; *zoom: 1; } .thumbnails:before, .thumbnails:after { display: table; line-height: 0; content: ""; } .thumbnails:after { clear: both; } .row-fluid .thumbnails { margin-left: 0; } .thumbnails > li { float: left; margin-bottom: 20px; margin-left: 20px; } .thumbnail { display: block; padding: 4px; line-height: 20px; border: 1px solid #ddd; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); -webkit-transition: all 0.2s ease-in-out; -moz-transition: all 0.2s ease-in-out; -o-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } a.thumbnail:hover, a.thumbnail:focus { border-color: #0088cc; -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); } .thumbnail > img { display: block; max-width: 100%; margin-right: auto; margin-left: auto; } .thumbnail .caption { padding: 9px; color: #555555; } .media, .media-body { overflow: hidden; *overflow: visible; zoom: 1; } .media, .media .media { margin-top: 15px; } .media:first-child { margin-top: 0; } .media-object { display: block; } .media-heading { margin: 0 0 5px; } .media > .pull-left { margin-right: 10px; } .media > .pull-right { margin-left: 10px; } .media-list { margin-left: 0; list-style: none; } .label, .badge { display: inline-block; padding: 2px 4px; font-size: 11.844px; font-weight: bold; line-height: 14px; color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); white-space: nowrap; vertical-align: baseline; background-color: #999999; } .label { -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .badge { padding-right: 9px; padding-left: 9px; -webkit-border-radius: 9px; -moz-border-radius: 9px; border-radius: 9px; } .label:empty, .badge:empty { display: none; } a.label:hover, a.label:focus, a.badge:hover, a.badge:focus { color: #ffffff; text-decoration: none; cursor: pointer; } .label-important, .badge-important { background-color: #b94a48; } .label-important[href], .badge-important[href] { background-color: #953b39; } .label-warning, .badge-warning { background-color: #f89406; } .label-warning[href], .badge-warning[href] { background-color: #c67605; } .label-success, .badge-success { background-color: #468847; } .label-success[href], .badge-success[href] { background-color: #356635; } .label-info, .badge-info { background-color: #3a87ad; } .label-info[href], .badge-info[href] { background-color: #2d6987; } .label-inverse, .badge-inverse { background-color: #333333; } .label-inverse[href], .badge-inverse[href] { background-color: #1a1a1a; } .btn .label, .btn .badge { position: relative; top: -1px; } .btn-mini .label, .btn-mini .badge { top: 0; } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @-moz-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @-ms-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @-o-keyframes progress-bar-stripes { from { background-position: 0 0; } to { background-position: 40px 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } .progress { height: 20px; margin-bottom: 20px; overflow: hidden; background-color: #f7f7f7; background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); background-repeat: repeat-x; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } .progress .bar { float: left; width: 0; height: 100%; font-size: 12px; color: #ffffff; text-align: center; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #0e90d2; background-image: -moz-linear-gradient(top, #149bdf, #0480be); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); background-image: -webkit-linear-gradient(top, #149bdf, #0480be); background-image: -o-linear-gradient(top, #149bdf, #0480be); background-image: linear-gradient(to bottom, #149bdf, #0480be); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-transition: width 0.6s ease; -moz-transition: width 0.6s ease; -o-transition: width 0.6s ease; transition: width 0.6s ease; } .progress .bar + .bar { -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); } .progress-striped .bar { background-color: #149bdf; background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -webkit-background-size: 40px 40px; -moz-background-size: 40px 40px; -o-background-size: 40px 40px; background-size: 40px 40px; } .progress.active .bar { -webkit-animation: progress-bar-stripes 2s linear infinite; -moz-animation: progress-bar-stripes 2s linear infinite; -ms-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } .progress-danger .bar, .progress .bar-danger { background-color: #dd514c; background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); } .progress-danger.progress-striped .bar, .progress-striped .bar-danger { background-color: #ee5f5b; background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-success .bar, .progress .bar-success { background-color: #5eb95e; background-image: -moz-linear-gradient(top, #62c462, #57a957); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); background-image: -webkit-linear-gradient(top, #62c462, #57a957); background-image: -o-linear-gradient(top, #62c462, #57a957); background-image: linear-gradient(to bottom, #62c462, #57a957); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); } .progress-success.progress-striped .bar, .progress-striped .bar-success { background-color: #62c462; background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-info .bar, .progress .bar-info { background-color: #4bb1cf; background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); background-image: -o-linear-gradient(top, #5bc0de, #339bb9); background-image: linear-gradient(to bottom, #5bc0de, #339bb9); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); } .progress-info.progress-striped .bar, .progress-striped .bar-info { background-color: #5bc0de; background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-warning .bar, .progress .bar-warning { background-color: #faa732; background-image: -moz-linear-gradient(top, #fbb450, #f89406); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); background-image: -webkit-linear-gradient(top, #fbb450, #f89406); background-image: -o-linear-gradient(top, #fbb450, #f89406); background-image: linear-gradient(to bottom, #fbb450, #f89406); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); } .progress-warning.progress-striped .bar, .progress-striped .bar-warning { background-color: #fbb450; background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .accordion { margin-bottom: 20px; } .accordion-group { margin-bottom: 2px; border: 1px solid #e5e5e5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .accordion-heading { border-bottom: 0; } .accordion-heading .accordion-toggle { display: block; padding: 8px 15px; } .accordion-toggle { cursor: pointer; } .accordion-inner { padding: 9px 15px; border-top: 1px solid #e5e5e5; } .carousel { position: relative; margin-bottom: 20px; line-height: 1; } .carousel-inner { position: relative; width: 100%; overflow: hidden; } .carousel-inner > .item { position: relative; display: none; -webkit-transition: 0.6s ease-in-out left; -moz-transition: 0.6s ease-in-out left; -o-transition: 0.6s ease-in-out left; transition: 0.6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { display: block; line-height: 1; } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { display: block; } .carousel-inner > .active { left: 0; } .carousel-inner > .next, .carousel-inner > .prev { position: absolute; top: 0; width: 100%; } .carousel-inner > .next { left: 100%; } .carousel-inner > .prev { left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { left: 0; } .carousel-inner > .active.left { left: -100%; } .carousel-inner > .active.right { left: 100%; } .carousel-control { position: absolute; top: 40%; left: 15px; width: 40px; height: 40px; margin-top: -20px; font-size: 60px; font-weight: 100; line-height: 30px; color: #ffffff; text-align: center; background: #222222; border: 3px solid #ffffff; -webkit-border-radius: 23px; -moz-border-radius: 23px; border-radius: 23px; opacity: 0.5; filter: alpha(opacity=50); } .carousel-control.right { right: 15px; left: auto; } .carousel-control:hover, .carousel-control:focus { color: #ffffff; text-decoration: none; opacity: 0.9; filter: alpha(opacity=90); } .carousel-indicators { position: absolute; top: 15px; right: 15px; z-index: 5; margin: 0; list-style: none; } .carousel-indicators li { display: block; float: left; width: 10px; height: 10px; margin-left: 5px; text-indent: -999px; background-color: #ccc; background-color: rgba(255, 255, 255, 0.25); border-radius: 5px; } .carousel-indicators .active { background-color: #fff; } .carousel-caption { position: absolute; right: 0; bottom: 0; left: 0; padding: 15px; background: #333333; background: rgba(0, 0, 0, 0.75); } .carousel-caption h4, .carousel-caption p { line-height: 20px; color: #ffffff; } .carousel-caption h4 { margin: 0 0 5px; } .carousel-caption p { margin-bottom: 0; } .hero-unit { padding: 60px; margin-bottom: 30px; font-size: 18px; font-weight: 200; line-height: 30px; color: inherit; background-color: #eeeeee; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; } .hero-unit h1 { margin-bottom: 0; font-size: 60px; line-height: 1; letter-spacing: -1px; color: inherit; } .hero-unit li { line-height: 30px; } .pull-right { float: right; } .pull-left { float: left; } .hide { display: none; } .show { display: block; } .invisible { visibility: hidden; } .affix { position: fixed; } vsmartcard-3.3/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css0000644000175000017500000004072113546304763025545 0ustar philphil/*! * Bootstrap Responsive v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} vsmartcard-3.3/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css0000644000175000017500000005313713546304763024770 0ustar philphil/*! * Bootstrap Responsive v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. */ .clearfix { *zoom: 1; } .clearfix:before, .clearfix:after { display: table; line-height: 0; content: ""; } .clearfix:after { clear: both; } .hide-text { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } .input-block-level { display: block; width: 100%; min-height: 30px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } @-ms-viewport { width: device-width; } .hidden { display: none; visibility: hidden; } .visible-phone { display: none !important; } .visible-tablet { display: none !important; } .hidden-desktop { display: none !important; } .visible-desktop { display: inherit !important; } @media (min-width: 768px) and (max-width: 979px) { .hidden-desktop { display: inherit !important; } .visible-desktop { display: none !important ; } .visible-tablet { display: inherit !important; } .hidden-tablet { display: none !important; } } @media (max-width: 767px) { .hidden-desktop { display: inherit !important; } .visible-desktop { display: none !important; } .visible-phone { display: inherit !important; } .hidden-phone { display: none !important; } } .visible-print { display: none !important; } @media print { .visible-print { display: inherit !important; } .hidden-print { display: none !important; } } @media (min-width: 1200px) { .row { margin-left: -30px; *zoom: 1; } .row:before, .row:after { display: table; line-height: 0; content: ""; } .row:after { clear: both; } [class*="span"] { float: left; min-height: 1px; margin-left: 30px; } .container, .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container { width: 1170px; } .span12 { width: 1170px; } .span11 { width: 1070px; } .span10 { width: 970px; } .span9 { width: 870px; } .span8 { width: 770px; } .span7 { width: 670px; } .span6 { width: 570px; } .span5 { width: 470px; } .span4 { width: 370px; } .span3 { width: 270px; } .span2 { width: 170px; } .span1 { width: 70px; } .offset12 { margin-left: 1230px; } .offset11 { margin-left: 1130px; } .offset10 { margin-left: 1030px; } .offset9 { margin-left: 930px; } .offset8 { margin-left: 830px; } .offset7 { margin-left: 730px; } .offset6 { margin-left: 630px; } .offset5 { margin-left: 530px; } .offset4 { margin-left: 430px; } .offset3 { margin-left: 330px; } .offset2 { margin-left: 230px; } .offset1 { margin-left: 130px; } .row-fluid { width: 100%; *zoom: 1; } .row-fluid:before, .row-fluid:after { display: table; line-height: 0; content: ""; } .row-fluid:after { clear: both; } .row-fluid [class*="span"] { display: block; float: left; width: 100%; min-height: 30px; margin-left: 2.564102564102564%; *margin-left: 2.5109110747408616%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .row-fluid [class*="span"]:first-child { margin-left: 0; } .row-fluid .controls-row [class*="span"] + [class*="span"] { margin-left: 2.564102564102564%; } .row-fluid .span12 { width: 100%; *width: 99.94680851063829%; } .row-fluid .span11 { width: 91.45299145299145%; *width: 91.39979996362975%; } .row-fluid .span10 { width: 82.90598290598291%; *width: 82.8527914166212%; } .row-fluid .span9 { width: 74.35897435897436%; *width: 74.30578286961266%; } .row-fluid .span8 { width: 65.81196581196582%; *width: 65.75877432260411%; } .row-fluid .span7 { width: 57.26495726495726%; *width: 57.21176577559556%; } .row-fluid .span6 { width: 48.717948717948715%; *width: 48.664757228587014%; } .row-fluid .span5 { width: 40.17094017094017%; *width: 40.11774868157847%; } .row-fluid .span4 { width: 31.623931623931625%; *width: 31.570740134569924%; } .row-fluid .span3 { width: 23.076923076923077%; *width: 23.023731587561375%; } .row-fluid .span2 { width: 14.52991452991453%; *width: 14.476723040552828%; } .row-fluid .span1 { width: 5.982905982905983%; *width: 5.929714493544281%; } .row-fluid .offset12 { margin-left: 105.12820512820512%; *margin-left: 105.02182214948171%; } .row-fluid .offset12:first-child { margin-left: 102.56410256410257%; *margin-left: 102.45771958537915%; } .row-fluid .offset11 { margin-left: 96.58119658119658%; *margin-left: 96.47481360247316%; } .row-fluid .offset11:first-child { margin-left: 94.01709401709402%; *margin-left: 93.91071103837061%; } .row-fluid .offset10 { margin-left: 88.03418803418803%; *margin-left: 87.92780505546462%; } .row-fluid .offset10:first-child { margin-left: 85.47008547008548%; *margin-left: 85.36370249136206%; } .row-fluid .offset9 { margin-left: 79.48717948717949%; *margin-left: 79.38079650845607%; } .row-fluid .offset9:first-child { margin-left: 76.92307692307693%; *margin-left: 76.81669394435352%; } .row-fluid .offset8 { margin-left: 70.94017094017094%; *margin-left: 70.83378796144753%; } .row-fluid .offset8:first-child { margin-left: 68.37606837606839%; *margin-left: 68.26968539734497%; } .row-fluid .offset7 { margin-left: 62.393162393162385%; *margin-left: 62.28677941443899%; } .row-fluid .offset7:first-child { margin-left: 59.82905982905982%; *margin-left: 59.72267685033642%; } .row-fluid .offset6 { margin-left: 53.84615384615384%; *margin-left: 53.739770867430444%; } .row-fluid .offset6:first-child { margin-left: 51.28205128205128%; *margin-left: 51.175668303327875%; } .row-fluid .offset5 { margin-left: 45.299145299145295%; *margin-left: 45.1927623204219%; } .row-fluid .offset5:first-child { margin-left: 42.73504273504273%; *margin-left: 42.62865975631933%; } .row-fluid .offset4 { margin-left: 36.75213675213675%; *margin-left: 36.645753773413354%; } .row-fluid .offset4:first-child { margin-left: 34.18803418803419%; *margin-left: 34.081651209310785%; } .row-fluid .offset3 { margin-left: 28.205128205128204%; *margin-left: 28.0987452264048%; } .row-fluid .offset3:first-child { margin-left: 25.641025641025642%; *margin-left: 25.53464266230224%; } .row-fluid .offset2 { margin-left: 19.65811965811966%; *margin-left: 19.551736679396257%; } .row-fluid .offset2:first-child { margin-left: 17.094017094017094%; *margin-left: 16.98763411529369%; } .row-fluid .offset1 { margin-left: 11.11111111111111%; *margin-left: 11.004728132387708%; } .row-fluid .offset1:first-child { margin-left: 8.547008547008547%; *margin-left: 8.440625568285142%; } input, textarea, .uneditable-input { margin-left: 0; } .controls-row [class*="span"] + [class*="span"] { margin-left: 30px; } input.span12, textarea.span12, .uneditable-input.span12 { width: 1156px; } input.span11, textarea.span11, .uneditable-input.span11 { width: 1056px; } input.span10, textarea.span10, .uneditable-input.span10 { width: 956px; } input.span9, textarea.span9, .uneditable-input.span9 { width: 856px; } input.span8, textarea.span8, .uneditable-input.span8 { width: 756px; } input.span7, textarea.span7, .uneditable-input.span7 { width: 656px; } input.span6, textarea.span6, .uneditable-input.span6 { width: 556px; } input.span5, textarea.span5, .uneditable-input.span5 { width: 456px; } input.span4, textarea.span4, .uneditable-input.span4 { width: 356px; } input.span3, textarea.span3, .uneditable-input.span3 { width: 256px; } input.span2, textarea.span2, .uneditable-input.span2 { width: 156px; } input.span1, textarea.span1, .uneditable-input.span1 { width: 56px; } .thumbnails { margin-left: -30px; } .thumbnails > li { margin-left: 30px; } .row-fluid .thumbnails { margin-left: 0; } } @media (min-width: 768px) and (max-width: 979px) { .row { margin-left: -20px; *zoom: 1; } .row:before, .row:after { display: table; line-height: 0; content: ""; } .row:after { clear: both; } [class*="span"] { float: left; min-height: 1px; margin-left: 20px; } .container, .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container { width: 724px; } .span12 { width: 724px; } .span11 { width: 662px; } .span10 { width: 600px; } .span9 { width: 538px; } .span8 { width: 476px; } .span7 { width: 414px; } .span6 { width: 352px; } .span5 { width: 290px; } .span4 { width: 228px; } .span3 { width: 166px; } .span2 { width: 104px; } .span1 { width: 42px; } .offset12 { margin-left: 764px; } .offset11 { margin-left: 702px; } .offset10 { margin-left: 640px; } .offset9 { margin-left: 578px; } .offset8 { margin-left: 516px; } .offset7 { margin-left: 454px; } .offset6 { margin-left: 392px; } .offset5 { margin-left: 330px; } .offset4 { margin-left: 268px; } .offset3 { margin-left: 206px; } .offset2 { margin-left: 144px; } .offset1 { margin-left: 82px; } .row-fluid { width: 100%; *zoom: 1; } .row-fluid:before, .row-fluid:after { display: table; line-height: 0; content: ""; } .row-fluid:after { clear: both; } .row-fluid [class*="span"] { display: block; float: left; width: 100%; min-height: 30px; margin-left: 2.7624309392265194%; *margin-left: 2.709239449864817%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .row-fluid [class*="span"]:first-child { margin-left: 0; } .row-fluid .controls-row [class*="span"] + [class*="span"] { margin-left: 2.7624309392265194%; } .row-fluid .span12 { width: 100%; *width: 99.94680851063829%; } .row-fluid .span11 { width: 91.43646408839778%; *width: 91.38327259903608%; } .row-fluid .span10 { width: 82.87292817679558%; *width: 82.81973668743387%; } .row-fluid .span9 { width: 74.30939226519337%; *width: 74.25620077583166%; } .row-fluid .span8 { width: 65.74585635359117%; *width: 65.69266486422946%; } .row-fluid .span7 { width: 57.18232044198895%; *width: 57.12912895262725%; } .row-fluid .span6 { width: 48.61878453038674%; *width: 48.56559304102504%; } .row-fluid .span5 { width: 40.05524861878453%; *width: 40.00205712942283%; } .row-fluid .span4 { width: 31.491712707182323%; *width: 31.43852121782062%; } .row-fluid .span3 { width: 22.92817679558011%; *width: 22.87498530621841%; } .row-fluid .span2 { width: 14.3646408839779%; *width: 14.311449394616199%; } .row-fluid .span1 { width: 5.801104972375691%; *width: 5.747913483013988%; } .row-fluid .offset12 { margin-left: 105.52486187845304%; *margin-left: 105.41847889972962%; } .row-fluid .offset12:first-child { margin-left: 102.76243093922652%; *margin-left: 102.6560479605031%; } .row-fluid .offset11 { margin-left: 96.96132596685082%; *margin-left: 96.8549429881274%; } .row-fluid .offset11:first-child { margin-left: 94.1988950276243%; *margin-left: 94.09251204890089%; } .row-fluid .offset10 { margin-left: 88.39779005524862%; *margin-left: 88.2914070765252%; } .row-fluid .offset10:first-child { margin-left: 85.6353591160221%; *margin-left: 85.52897613729868%; } .row-fluid .offset9 { margin-left: 79.8342541436464%; *margin-left: 79.72787116492299%; } .row-fluid .offset9:first-child { margin-left: 77.07182320441989%; *margin-left: 76.96544022569647%; } .row-fluid .offset8 { margin-left: 71.2707182320442%; *margin-left: 71.16433525332079%; } .row-fluid .offset8:first-child { margin-left: 68.50828729281768%; *margin-left: 68.40190431409427%; } .row-fluid .offset7 { margin-left: 62.70718232044199%; *margin-left: 62.600799341718584%; } .row-fluid .offset7:first-child { margin-left: 59.94475138121547%; *margin-left: 59.838368402492065%; } .row-fluid .offset6 { margin-left: 54.14364640883978%; *margin-left: 54.037263430116376%; } .row-fluid .offset6:first-child { margin-left: 51.38121546961326%; *margin-left: 51.27483249088986%; } .row-fluid .offset5 { margin-left: 45.58011049723757%; *margin-left: 45.47372751851417%; } .row-fluid .offset5:first-child { margin-left: 42.81767955801105%; *margin-left: 42.71129657928765%; } .row-fluid .offset4 { margin-left: 37.01657458563536%; *margin-left: 36.91019160691196%; } .row-fluid .offset4:first-child { margin-left: 34.25414364640884%; *margin-left: 34.14776066768544%; } .row-fluid .offset3 { margin-left: 28.45303867403315%; *margin-left: 28.346655695309746%; } .row-fluid .offset3:first-child { margin-left: 25.69060773480663%; *margin-left: 25.584224756083227%; } .row-fluid .offset2 { margin-left: 19.88950276243094%; *margin-left: 19.783119783707537%; } .row-fluid .offset2:first-child { margin-left: 17.12707182320442%; *margin-left: 17.02068884448102%; } .row-fluid .offset1 { margin-left: 11.32596685082873%; *margin-left: 11.219583872105325%; } .row-fluid .offset1:first-child { margin-left: 8.56353591160221%; *margin-left: 8.457152932878806%; } input, textarea, .uneditable-input { margin-left: 0; } .controls-row [class*="span"] + [class*="span"] { margin-left: 20px; } input.span12, textarea.span12, .uneditable-input.span12 { width: 710px; } input.span11, textarea.span11, .uneditable-input.span11 { width: 648px; } input.span10, textarea.span10, .uneditable-input.span10 { width: 586px; } input.span9, textarea.span9, .uneditable-input.span9 { width: 524px; } input.span8, textarea.span8, .uneditable-input.span8 { width: 462px; } input.span7, textarea.span7, .uneditable-input.span7 { width: 400px; } input.span6, textarea.span6, .uneditable-input.span6 { width: 338px; } input.span5, textarea.span5, .uneditable-input.span5 { width: 276px; } input.span4, textarea.span4, .uneditable-input.span4 { width: 214px; } input.span3, textarea.span3, .uneditable-input.span3 { width: 152px; } input.span2, textarea.span2, .uneditable-input.span2 { width: 90px; } input.span1, textarea.span1, .uneditable-input.span1 { width: 28px; } } @media (max-width: 767px) { body { padding-right: 20px; padding-left: 20px; } .navbar-fixed-top, .navbar-fixed-bottom, .navbar-static-top { margin-right: -20px; margin-left: -20px; } .container-fluid { padding: 0; } .dl-horizontal dt { float: none; width: auto; clear: none; text-align: left; } .dl-horizontal dd { margin-left: 0; } .container { width: auto; } .row-fluid { width: 100%; } .row, .thumbnails { margin-left: 0; } .thumbnails > li { float: none; margin-left: 0; } [class*="span"], .uneditable-input[class*="span"], .row-fluid [class*="span"] { display: block; float: none; width: 100%; margin-left: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .span12, .row-fluid .span12 { width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .row-fluid [class*="offset"]:first-child { margin-left: 0; } .input-large, .input-xlarge, .input-xxlarge, input[class*="span"], select[class*="span"], textarea[class*="span"], .uneditable-input { display: block; width: 100%; min-height: 30px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .input-prepend input, .input-append input, .input-prepend input[class*="span"], .input-append input[class*="span"] { display: inline-block; width: auto; } .controls-row [class*="span"] + [class*="span"] { margin-left: 0; } .modal { position: fixed; top: 20px; right: 20px; left: 20px; width: auto; margin: 0; } .modal.fade { top: -100px; } .modal.fade.in { top: 20px; } } @media (max-width: 480px) { .nav-collapse { -webkit-transform: translate3d(0, 0, 0); } .page-header h1 small { display: block; line-height: 20px; } input[type="checkbox"], input[type="radio"] { border: 1px solid #ccc; } .form-horizontal .control-label { float: none; width: auto; padding-top: 0; text-align: left; } .form-horizontal .controls { margin-left: 0; } .form-horizontal .control-list { padding-top: 0; } .form-horizontal .form-actions { padding-right: 10px; padding-left: 10px; } .media .pull-left, .media .pull-right { display: block; float: none; margin-bottom: 10px; } .media-object { margin-right: 0; margin-left: 0; } .modal { top: 10px; right: 10px; left: 10px; } .modal-header .close { padding: 10px; margin: -10px; } .carousel-caption { position: static; } } @media (max-width: 979px) { body { padding-top: 0; } .navbar-fixed-top, .navbar-fixed-bottom { position: static; } .navbar-fixed-top { margin-bottom: 20px; } .navbar-fixed-bottom { margin-top: 20px; } .navbar-fixed-top .navbar-inner, .navbar-fixed-bottom .navbar-inner { padding: 5px; } .navbar .container { width: auto; padding: 0; } .navbar .brand { padding-right: 10px; padding-left: 10px; margin: 0 0 0 -5px; } .nav-collapse { clear: both; } .nav-collapse .nav { float: none; margin: 0 0 10px; } .nav-collapse .nav > li { float: none; } .nav-collapse .nav > li > a { margin-bottom: 2px; } .nav-collapse .nav > .divider-vertical { display: none; } .nav-collapse .nav .nav-header { color: #777777; text-shadow: none; } .nav-collapse .nav > li > a, .nav-collapse .dropdown-menu a { padding: 9px 15px; font-weight: bold; color: #777777; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .nav-collapse .btn { padding: 4px 10px 4px; font-weight: normal; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .nav-collapse .dropdown-menu li + li a { margin-bottom: 2px; } .nav-collapse .nav > li > a:hover, .nav-collapse .nav > li > a:focus, .nav-collapse .dropdown-menu a:hover, .nav-collapse .dropdown-menu a:focus { background-color: #f2f2f2; } .navbar-inverse .nav-collapse .nav > li > a, .navbar-inverse .nav-collapse .dropdown-menu a { color: #999999; } .navbar-inverse .nav-collapse .nav > li > a:hover, .navbar-inverse .nav-collapse .nav > li > a:focus, .navbar-inverse .nav-collapse .dropdown-menu a:hover, .navbar-inverse .nav-collapse .dropdown-menu a:focus { background-color: #111111; } .nav-collapse.in .btn-group { padding: 0; margin-top: 5px; } .nav-collapse .dropdown-menu { position: static; top: auto; left: auto; display: none; float: none; max-width: none; padding: 0; margin: 0 15px; background-color: transparent; border: none; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .nav-collapse .open > .dropdown-menu { display: block; } .nav-collapse .dropdown-menu:before, .nav-collapse .dropdown-menu:after { display: none; } .nav-collapse .dropdown-menu .divider { display: none; } .nav-collapse .nav > li > .dropdown-menu:before, .nav-collapse .nav > li > .dropdown-menu:after { display: none; } .nav-collapse .navbar-form, .nav-collapse .navbar-search { float: none; padding: 10px 15px; margin: 10px 0; border-top: 1px solid #f2f2f2; border-bottom: 1px solid #f2f2f2; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); } .navbar-inverse .nav-collapse .navbar-form, .navbar-inverse .nav-collapse .navbar-search { border-top-color: #111111; border-bottom-color: #111111; } .navbar .nav-collapse .nav.pull-right { float: none; margin-left: 0; } .nav-collapse, .nav-collapse.collapse { height: 0; overflow: hidden; } .navbar .btn-navbar { display: block; } .navbar-static .navbar-inner { padding-right: 10px; padding-left: 10px; } } @media (min-width: 980px) { .nav-collapse.collapse { height: auto !important; overflow: visible !important; } } vsmartcard-3.3/docs/_static/bootstrap-2.3.2/js/0000755000175000017500000000000013546304763017661 5ustar philphilvsmartcard-3.3/docs/_static/bootstrap-2.3.2/js/bootstrap.min.js0000644000175000017500000007027313546304763023027 0ustar philphil/** * Bootstrap.js v2.3.2 by @fat & @mdo * Copyright 2012 Twitter, Inc. * http://www.apache.org/licenses/LICENSE-2.0.txt */ !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.$jqTheme||window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('