| 1 | Chip Card Interface Device (CCID) |
| 2 | ================================= |
| 3 | |
| 4 | USB CCID device |
| 5 | --------------- |
| 6 | The USB CCID device is a USB device implementing the CCID specification, which |
| 7 | lets one connect smart card readers that implement the same spec. For more |
| 8 | information see the specification:: |
| 9 | |
| 10 | Universal Serial Bus |
| 11 | Device Class: Smart Card |
| 12 | CCID |
| 13 | Specification for |
| 14 | Integrated Circuit(s) Cards Interface Devices |
| 15 | Revision 1.1 |
| 16 | April 22rd, 2005 |
| 17 | |
| 18 | Smartcards are used for authentication, single sign on, decryption in |
| 19 | public/private schemes and digital signatures. A smartcard reader on the client |
| 20 | cannot be used on a guest with simple usb passthrough since it will then not be |
| 21 | available on the client, possibly locking the computer when it is "removed". On |
| 22 | the other hand this device can let you use the smartcard on both the client and |
| 23 | the guest machine. It is also possible to have a completely virtual smart card |
| 24 | reader and smart card (i.e. not backed by a physical device) using this device. |
| 25 | |
| 26 | Building |
| 27 | -------- |
| 28 | The cryptographic functions and access to the physical card is done via the |
| 29 | libcacard library, whose development package must be installed prior to |
| 30 | building QEMU: |
| 31 | |
| 32 | In redhat/fedora:: |
| 33 | |
| 34 | yum install libcacard-devel |
| 35 | |
| 36 | In ubuntu:: |
| 37 | |
| 38 | apt-get install libcacard-dev |
| 39 | |
| 40 | Configuring and building:: |
| 41 | |
| 42 | ./configure --enable-smartcard && make |
| 43 | |
| 44 | Using ccid-card-emulated with hardware |
| 45 | -------------------------------------- |
| 46 | Assuming you have a working smartcard on the host with the current |
| 47 | user, using libcacard, QEMU acts as another client using ccid-card-emulated:: |
| 48 | |
| 49 | qemu -usb -device usb-ccid -device ccid-card-emulated |
| 50 | |
| 51 | Using ccid-card-emulated with certificates stored in files |
| 52 | ---------------------------------------------------------- |
| 53 | You must create the CA and card certificates. This is a one time process. |
| 54 | We use NSS certificates:: |
| 55 | |
| 56 | mkdir fake-smartcard |
| 57 | cd fake-smartcard |
| 58 | certutil -N -d sql:$PWD |
| 59 | certutil -S -d sql:$PWD -s "CN=Fake Smart Card CA" -x -t TC,TC,TC -n fake-smartcard-ca |
| 60 | certutil -S -d sql:$PWD -t ,, -s "CN=John Doe" -n id-cert -c fake-smartcard-ca |
| 61 | certutil -S -d sql:$PWD -t ,, -s "CN=John Doe (signing)" --nsCertType smime -n signing-cert -c fake-smartcard-ca |
| 62 | certutil -S -d sql:$PWD -t ,, -s "CN=John Doe (encryption)" --nsCertType sslClient -n encryption-cert -c fake-smartcard-ca |
| 63 | |
| 64 | Note: you must have exactly three certificates. |
| 65 | |
| 66 | You can use the emulated card type with the certificates backend:: |
| 67 | |
| 68 | qemu -usb -device usb-ccid -device ccid-card-emulated,backend=certificates,db=sql:$PWD,cert1=id-cert,cert2=signing-cert,cert3=encryption-cert |
| 69 | |
| 70 | To use the certificates in the guest, export the CA certificate:: |
| 71 | |
| 72 | certutil -L -r -d sql:$PWD -o fake-smartcard-ca.cer -n fake-smartcard-ca |
| 73 | |
| 74 | and import it in the guest:: |
| 75 | |
| 76 | certutil -A -d /etc/pki/nssdb -i fake-smartcard-ca.cer -t TC,TC,TC -n fake-smartcard-ca |
| 77 | |
| 78 | In a Linux guest you can then use the CoolKey PKCS #11 module to access |
| 79 | the card:: |
| 80 | |
| 81 | certutil -d /etc/pki/nssdb -L -h all |
| 82 | |
| 83 | It will prompt you for the PIN (which is the password you assigned to the |
| 84 | certificate database early on), and then show you all three certificates |
| 85 | together with the manually imported CA cert:: |
| 86 | |
| 87 | Certificate Nickname Trust Attributes |
| 88 | fake-smartcard-ca CT,C,C |
| 89 | John Doe:CAC ID Certificate u,u,u |
| 90 | John Doe:CAC Email Signature Certificate u,u,u |
| 91 | John Doe:CAC Email Encryption Certificate u,u,u |
| 92 | |
| 93 | If this does not happen, CoolKey is not installed or not registered with |
| 94 | NSS. Registration can be done from Firefox or the command line:: |
| 95 | |
| 96 | modutil -dbdir /etc/pki/nssdb -add "CAC Module" -libfile /usr/lib64/pkcs11/libcoolkeypk11.so |
| 97 | modutil -dbdir /etc/pki/nssdb -list |
| 98 | |
| 99 | Using ccid-card-passthru with client side hardware |
| 100 | -------------------------------------------------- |
| 101 | On the host specify the ccid-card-passthru device with a suitable chardev:: |
| 102 | |
| 103 | qemu -chardev socket,server=on,host=0.0.0.0,port=2001,id=ccid,wait=off \ |
| 104 | -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid |
| 105 | |
| 106 | On the client run vscclient, built when you built QEMU:: |
| 107 | |
| 108 | vscclient <qemu-host> 2001 |
| 109 | |
| 110 | Using ccid-card-passthru with client side certificates |
| 111 | ------------------------------------------------------ |
| 112 | This case is not particularly useful, but you can use it to debug |
| 113 | your setup. |
| 114 | |
| 115 | Follow instructions above, except run QEMU and vscclient as follows. |
| 116 | |
| 117 | Run qemu as per above, and run vscclient from the "fake-smartcard" |
| 118 | directory as follows:: |
| 119 | |
| 120 | qemu -chardev socket,server=on,host=0.0.0.0,port=2001,id=ccid,wait=off \ |
| 121 | -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid |
| 122 | vscclient -e "db=\"sql:$PWD\" use_hw=no soft=(,Test,CAC,,id-cert,signing-cert,encryption-cert)" <qemu-host> 2001 |
| 123 | |
| 124 | |
| 125 | Passthrough protocol scenario |
| 126 | ----------------------------- |
| 127 | This is a typical interchange of messages when using the passthru card device. |
| 128 | usb-ccid is a usb device. It defaults to an unattached usb device on startup. |
| 129 | usb-ccid expects a chardev and expects the protocol defined in |
| 130 | cac_card/vscard_common.h to be passed over that. |
| 131 | The usb-ccid device can be in one of three modes: |
| 132 | |
| 133 | * detached |
| 134 | * attached with no card |
| 135 | * attached with card |
| 136 | |
| 137 | A typical interchange is (the arrow shows who started each exchange, it can be client |
| 138 | originated or guest originated):: |
| 139 | |
| 140 | client event | vscclient | passthru | usb-ccid | guest event |
| 141 | ------------------------------------------------------------------------------------------------ |
| 142 | | VSC_Init | | | |
| 143 | | VSC_ReaderAdd | | attach | |
| 144 | | | | | sees new usb device. |
| 145 | card inserted -> | | | | |
| 146 | | VSC_ATR | insert | insert | see new card |
| 147 | | | | | |
| 148 | | VSC_APDU | VSC_APDU | | <- guest sends APDU |
| 149 | client <-> physical | | | | |
| 150 | card APDU exchange | | | | |
| 151 | client response -> | VSC_APDU | VSC_APDU | | receive APDU response |
| 152 | ... |
| 153 | [APDU<->APDU repeats several times] |
| 154 | ... |
| 155 | card removed -> | | | | |
| 156 | | VSC_CardRemove | remove | remove | card removed |
| 157 | ... |
| 158 | [(card insert, apdu's, card remove) repeat] |
| 159 | ... |
| 160 | kill/quit | | | | |
| 161 | vscclient | | | | |
| 162 | | VSC_ReaderRemove | | detach | |
| 163 | | | | | usb device removed. |
| 164 | |
| 165 | libcacard |
| 166 | --------- |
| 167 | Both ccid-card-emulated and vscclient use libcacard as the card emulator. |
| 168 | libcacard implements a completely virtual CAC (DoD standard for smart |
| 169 | cards) compliant card and uses NSS to retrieve certificates and do |
| 170 | any encryption. The backend can then be a real reader and card, or |
| 171 | certificates stored in files. |