1 #+TITLE: Using an OpenPGP card in the UbuntuPhone BQ E4.5
4 #+DATE: October 5, 2017
6 ** Using an OpenPGP card in the UbuntuPhone BQ E4.5
8 #+CAPTION: The device BQ E4.5 with the attached OpenPGP card
9 #+ATTR_HTML: :class right :style max-width: 350px
10 [[file:img/UbuntuPhone-GnuPG-card.png]]
12 This small tutorial describes how to setup and use GnuPG together with
13 an OpenPGP card in the mobile device BQ E4.5, running Ubuntu 15-04. The device
14 root file system is for good reason mounted read-only. I.e. one can not
15 just install any other piece of software into it. The way used here is
16 an additional Linux system inside the phones system and *chroot*-ing into it
17 for the to be installed software, and later calling the software from outside
18 the chroot'ed file system.
20 When you login into the phone, either by SSH or via the terminal-app, your
21 ~HOME~ directory is ~/home/phablet~. ~phablet~ is the default user in the
22 phone. I have created there an additional directory ~/home/phablet/myRoot~
23 and below this untar'ed a complete Debian based Linux.
24 How to do this is described in a small
25 [[https://gurucubano.gitbooks.io/bq-aquaris-e-4-5-ubuntu-phone/content/en/chapter27.html][Gitbook about the BQ E4.5]].
27 In the following text as naming convention the shell
28 prompt =$= means, we are in the phones file system and something
29 like =root@ubuntu-phablet:/#= or
30 =phablet@ubuntu-phablet:~$= means,
31 we are in the chroot'ed file system, best to understand with these commands:
34 $ ssh phablet@10.42.0.1
36 Welcome to Ubuntu 15.04 (GNU/Linux 3.4.67 armv7l)
38 Last login: Mon Sep 25 07:45:37 2017 from 10.42.0.152
40 phablet@ubuntu-phablet-bq:~$
42 phablet@ubuntu-phablet-bq:~$ PS1='$ '
44 $ sudo chroot /home/phablet/myRoot
45 [sudo] password for phablet:
46 root@ubuntu-phablet:/# su phablet
47 phablet@ubuntu-phablet:/$ cd
48 phablet@ubuntu-phablet:~$ pwd
50 phablet@ubuntu-phablet:~$
53 *** Installing GnuPG 2.2.1 into the 'myRoot' system
55 In the chroot'ed system we install some additional packages:
58 phablet@ubuntu-phablet:~$ sudo apt-get install pinentry-curses
59 phablet@ubuntu-phablet:~$ sudo apt-get install pass
60 phablet@ubuntu-phablet:~$ sudo apt-get install libudev-dev
61 phablet@ubuntu-phablet:~$ sudo apt-get install libusb-dev
62 phablet@ubuntu-phablet:~$ sudo apt-get install libusb-1.0-0-dev
65 ~pass~ is a small password-storage manager which we will later use for our
66 GnuPG encrypted tree of password, for example for websites or any other
67 purpose, bank account PIN, ...
69 ~pinentry-curses~ is used by the ~gpg-agent~ to ask for the OpenPGP card
70 PIN, i.e. all the usage is later done or in a SSH session or in the
73 We now compile the following pieces of GnuPG software in that order:
84 always with ~./configure && make && sudo make install~ The compiled
85 software ends up below ~/usr/local~ (i.e. below
86 ~/home/phablet/myRoot/usr/local~ when one looks from outside the
87 chroot'ed phone system);
89 Now in the phone system we configure for GnuPG the following config
97 agent-program /home/phablet/myRoot/usr/local/bin/gpg-agent
99 $ cat .gnupg/gpg-agent.conf
100 pinentry-program /home/phablet/myRoot/usr/bin/pinentry-curses
101 scdaemon-program /home/phablet/myRoot/usr/local/libexec/scdaemon
102 log-file /home/phablet/gpg-agent.log
107 Due to the nature of the installation in the chroot'ed system we
108 need small wrapper scripts to set ~PATH~, ~LD_LIBRARY_PATH~, ... and
114 LD_LIBRARY_PATH=/home/phablet/myRoot/usr/local/lib export LD_LIBRARY_PATH
115 PATH=/home/phablet/myRoot/usr/local/bin:$PATH export PATH
116 GNUPGHOME=/home/phablet/.gnupg export GNUPGHOME
117 GPG_TTY=$(tty) export GPG_TTY
118 /home/phablet/myRoot/usr/local/bin/gpg-agent \
119 --homedir /home/phablet/.gnupg \
121 --pinentry-program /home/phablet/myRoot/usr/bin/pinentry-curses
122 /home/phablet/myRoot/usr/local/bin/gpg-connect-agent /bye
123 /home/phablet/myRoot/usr/local/bin/gpg $*
126 run and create for test a key pair (later we want to use the OpenPGP card key pair
130 $ ~/gpg.sh --full-generate-key
131 gpg-agent[2973]: enabled debug flags: mpi crypto memory cache memstat hashing ipc
132 gpg (GnuPG) 2.2.1; Copyright (C) 2017 Free Software Foundation, Inc.
133 This is free software: you are free to change and redistribute it.
134 There is NO WARRANTY, to the extent permitted by law.
136 Please select what kind of key you want:
137 (1) RSA and RSA (default)
145 This starts the gpg-agent as:
149 2974 ? Ss 0:00 /home/phablet/myRoot/usr/local/bin/gpg-agent --homedir /home/phablet/.gnupg --daemon --pinentry-program /home/phablet/myRoot/usr/bin/pinentry-curses
153 Now we can use the 'pass' command we installed in the chroot'es system
159 LD_LIBRARY_PATH=/home/phablet/myRoot/usr/local/lib export LD_LIBRARY_PATH
160 PATH=/home/phablet/myRoot/usr/local/bin:$PATH export PATH
161 GNUPGHOME=/home/phablet/.gnupg export GNUPGHOME
162 GPG_TTY=$(tty) export GPG_TTY
164 /home/phablet/myRoot/usr/bin/pass $*
168 Init the pass storage as:
171 $ ./pass.sh init Matthias
173 ┌────────────────────────────────────────────────────────────────┐
174 │ Please enter the passphrase to unlock the OpenPGP secret key: │
175 │ "Matthias Apitz (test) <guru@sisis.de>" │
176 │ 2048-bit RSA key, ID 93A6FBF52FA76DB0, │
177 │ created 2017-09-22 (main key ID 3FECB79DDDA409E4). │
180 │ Passphrase: ***_______________________________________________ │
183 └────────────────────────────────────────────────────────────────┘
185 $ find .password-store/
187 .password-store/.gpg-id
190 Insert some password for test:
193 $ ./pass.sh insert -m web/bla
194 Enter contents of web/bla and press Ctrl+D when finished:
205 Final step is getting support for the OpenPGP card. We need the 'pcscd' daemon.
206 Its build is a bit tricky because it must later, on start from outside the
207 chroot'ed syste, find the ccid driver.
209 We compile the following pieces inside the chroot'ed system:
214 with the following options set on ~./configure~ ...
217 phablet@ubuntu-phablet-bq:~$ cd pcsc-lite-1.8.20
218 phablet@ubuntu-phablet-bq:~/pcsc-lite-1.8.20$ ./configure --enable-usbdropdir=/home/phablet/myRoot/usr/local/lib/pcsc/drivers --enable-confdir=/home/phablet/myRoot/etc/reader.conf.d
221 PC/SC lite has been configured with following options:
224 System binaries: /usr/local/sbin
225 Configuration dir: /usr/local/etc/reader.conf.d
228 Host: armv7l-unknown-linux-gnueabihf
230 Preprocessor flags: -I${top_srcdir}/src
231 Compiler flags: -Wall -fno-common -g -O2
232 Preprocessor flags: -I${top_srcdir}/src
236 PTHREAD_CFLAGS: -pthread
240 pcscd binary /usr/local/sbin/pcscd
245 USB drop directory: /home/phablet/myRoot/usr/local/lib/pcsc/drivers
246 ATR parsing messages: false
247 ipcdir: /var/run/pcscd
250 systemd unit directory: /lib/systemd/system
251 serial config dir.: /home/phablet/myRoot/etc/reader.conf.d
254 PCSCLITE_FEATURES: Linux armv7l-unknown-linux-gnueabihf serial usb libudev usbdropdir=/home/phablet/myRoot/usr/local/lib/pcsc/drivers ipcdir=/var/run/pcscd configdir=/home/phablet/myRoot/etc/reader.conf.d
256 checking that generated files are newer than configure... done
259 phablet@ubuntu-phablet-bq:~/ccid-1.4.25$ make
260 phablet@ubuntu-phablet-bq:~/ccid-1.4.25$ sudo make install
264 ok, now the 'ccid' driver, installed (copied) to be seen by the daemon:
268 phablet@ubuntu-phablet-bq:~$ cd ccid-1.4.25
269 phablet@ubuntu-phablet:~/ccid-1.4.25$ ./configure -enable-usbdropdir=/home/phablet/myRoot/usr/local/lib/pcsc/drivers
271 libccid has been configured with following options:
274 User binaries: /usr/local/bin
275 Configuration files: /usr/local/etc
278 Host: armv7l-unknown-linux-gnueabihf
281 Compiler flags: -g -O2
286 PCSC_CFLAGS: -pthread -I/usr/local/include/PCSC
287 PCSC_LIBS: -L/usr/local/lib -lpcsclite
288 PTHREAD_CFLAGS: -pthread
292 LIBUSB_CFLAGS: -I/usr/include/libusb-1.0
293 LIBUSB_LIBS: -lusb-1.0
294 SYMBOL_VISIBILITY: -fvisibility=hidden
298 composite as multislot: no
300 bundle directory name: ifd-ccid.bundle
301 USB drop directory: /home/phablet/myRoot/usr/local/lib/pcsc/drivers
302 serial Twin support: no
303 serial twin install dir: /home/phablet/myRoot/usr/local/lib/pcsc/drivers/serial
304 serial config directory: /home/phablet/myRoot/etc/reader.conf.d
305 compiled for pcsc-lite: yes
311 phablet@ubuntu-phablet:~/ccid-1.4.25$ make
312 phablet@ubuntu-phablet:~/ccid-1.4.25$ sudo make install
315 the driver ~libccid.so~ and its control file ~Info.plist~ ended up as configured in:
318 phablet@ubuntu-phablet:~$ find /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/
319 /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/
320 /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux
321 /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux/libccid.so
322 /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
326 but if we run the daemon from outside the chroot'ed system, the files must be in
327 some other place because ~/home/phablet/myRoot~ is added in front; so
328 we copy them over to the correct place:
331 phablet@ubuntu-phablet:~$ sudo mkdir -p /usr/local/lib/pcsc/drivers/ifd-ccid.bundle
332 phablet@ubuntu-phablet:~$ sudo cp -rp /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents /usr/local/lib/pcsc/drivers/ifd-ccid.bundle
333 phablet@ubuntu-phablet:~$ find /usr/local/lib/pcsc/drivers/ifd-ccid.bundle
334 /usr/local/lib/pcsc/drivers/ifd-ccid.bundle
335 /usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents
336 /usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux
337 /usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux/libccid.so
338 /usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
341 From outside the chroot'ed system we can now start the daemon as:
344 $ sudo /home/phablet/myRoot/usr/local/sbin/pcscd --foreground --debug | tee pcscd.log
347 and check the log file ~pcscd.log~ to see if it sees the card attaching (see at the very
348 end of the write-up);
350 Now we start in the phone the pcscd daemon as:
353 $ sudo /home/phablet/myRoot/usr/local/sbin/pcscd
355 31669 pts/53 Sl 0:00 /home/phablet/myRoot/usr/local/sbin/pcscd
358 and run the gpg --card-status to see if it finds the card on attach:
361 $ ./gpg.sh --card-status
362 gpg-agent[20254]: enabled debug flags: mpi crypto memory cache memstat hashing ipc
363 gpg-agent: a gpg-agent is already running - not starting a new one
364 gpg-agent: random usage: poolsize=600 mixed=0 polls=0/0 added=0/0
365 outmix=0 getlvl1=0/0 getlvl2=0/0
366 gpg-agent: secmem usage: 0/32768 bytes in 0 blocks
367 Reader ...........: Identiv uTrust 3512 SAM slot Token [CCID Interface] (55511514602745) 00 00
368 Application ID ...: D27600012401020100050000532B0000
369 Version ..........: 2.1
370 Manufacturer .....: ZeitControl
371 Serial number ....: 0000532B
372 Name of cardholder: Matthias Apitz
373 Language prefs ...: en
374 Sex ..............: unspecified
375 URL of public key : http://www.unixarea.de/ccid--export-key-guru.pub
376 Login data .......: [not set]
377 Signature PIN ....: not forced
378 Key attributes ...: rsa4096 rsa4096 rsa4096
379 Max. PIN lengths .: 32 32 32
380 PIN retry counter : 3 0 3
381 Signature counter : 457
382 Signature key ....: 5E69 FBAC 1618 562C B3CB FBC1 47CC F7E4 76FE 9D11
383 created ....: 2017-05-14 18:20:07
384 Encryption key....: EB62 00DA 13A1 9E80 679B 1A13 61F1 ECB6 25C9 A6C3
385 created ....: 2017-05-14 18:20:07
386 Authentication key: E51D D2D6 C727 35D6 651D EA4B 6AA5 C5C4 51A1 CD1C
387 created ....: 2017-05-14 18:20:07
388 General key info..: [none]
392 Now we removed ~/home/phablet/.gnupg~ (saving the ~*.conf~ files) and copied over from my
393 real netbook the ~/.password-store~ and the key material for the
395 let's see if 'pass' can unlock the card (via the gpg-agent) and decipher the
396 crypted information (uncrypted shown here as ~XXXXXXXX-XXXXXX~). The ~gpg-agent~
397 will first ask for the card to be inserted and then for its PIN.
400 $ ./pass.sh askubuntu.com/guru@unixarea.de
403 #+html: <div class="figure-left">
404 #+CAPTION: The request for the card
405 #+ATTR_HTML: :class center :style max-width: 400px
406 [[file:img/gnupg-card-insert-card.png]]
409 #+html: <p style="clear: both"/>
411 #+html: <div class="figure-left">
412 #+CAPTION: The request for the PIN
413 #+ATTR_HTML: :class center :style max-width: 400px
414 [[file:img/gnupg-card-insert-pin.png]]
417 #+html: <p style="clear: both"/>
425 on the 2nd run it does not need anymore the PIN:
428 $ ./pass.sh askubuntu.com/guru@unixarea.de
435 This is only the debug log of the pcscd daemon for reference.
438 00000000 debuglog.c:289:DebugLogSetLevel() debug level=debug
439 00001760 configfile.l:282:DBGetReaderListDir() Parsing conf directory: /home/phablet/myRoot/etc/reader.conf.d
440 00000840 configfile.l:319:DBGetReaderListDir() Skipping non regular file: .
441 00000349 configfile.l:319:DBGetReaderListDir() Skipping non regular file: ..
442 00000364 configfile.l:358:DBGetReaderList() Parsing conf file: /home/phablet/myRoot/etc/reader.conf.d/libccidtwin
443 00000568 pcscdaemon.c:655:main() pcsc-lite 1.8.20 daemon ready.
444 00007279 hotplug_libudev.c:294:get_driver() Looking for a driver for VID: 0x1D6B, PID: 0x0002, path: /dev/bus/usb/001/001
445 07475463 hotplug_libudev.c:648:HPEstablishUSBNotifications() USB Device add
446 00005501 hotplug_libudev.c:294:get_driver() Looking for a driver for VID: 0x04E6, PID: 0x5816, path: /dev/bus/usb/001/009
447 00000555 hotplug_libudev.c:433:HPAddDevice() Adding USB device: Identiv uTrust 3512 SAM slot Token
448 00000673 readerfactory.c:1079:RFInitializeReader() Attempting startup of Identiv uTrust 3512 SAM slot Token [CCID Interface] (55511514602745) 00 00 using /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux/libccid.so
449 00001129 readerfactory.c:954:RFBindFunctions() Loading IFD Handler 3.0
450 00013183 ifdhandler.c:1953:init_driver() Driver version: 1.4.25
451 00004027 ifdhandler.c:1970:init_driver() LogLevel: 0x0003
452 00004427 ifdhandler.c:1981:init_driver() DriverOptions: 0x0000
453 00001127 ifdhandler.c:110:CreateChannelByNameOrChannel() Lun: 0, device: usb:04e6/5816:libudev:0:/dev/bus/usb/001/009
454 00001212 ccid_usb.c:287:OpenUSBByName() Using: /home/phablet/myRoot/usr/local/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
455 00005565 ccid_usb.c:305:OpenUSBByName() ifdManufacturerString: Ludovic Rousseau (ludovic.rousseau@free.fr)
456 00001479 ccid_usb.c:306:OpenUSBByName() ifdProductString: Generic CCID driver
457 00000362 ccid_usb.c:307:OpenUSBByName() Copyright: This driver is protected by terms of the GNU Lesser General Public License version 2.1, or (at your option) any later version.
458 00003937 ccid_usb.c:621:OpenUSBByName() Found Vendor/Product: 04E6/5816 (Identiv uTrust 3512 SAM slot Token)
459 00000667 ccid_usb.c:623:OpenUSBByName() Using USB bus/device: 1/9
460 00000337 ccid_usb.c:680:OpenUSBByName() bNumDataRatesSupported is 0
461 00010195 ifdhandler.c:379:IFDHGetCapabilities() tag: 0xFB3, usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
462 00000626 readerfactory.c:395:RFAddReader() Using the reader polling thread
463 00000838 ifdhandler.c:379:IFDHGetCapabilities() tag: 0xFAE, usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
464 00000470 ifdhandler.c:470:IFDHGetCapabilities() Reader supports 1 slot(s)
465 00001264 ifdhandler.c:1146:IFDHPowerICC() action: PowerUp, usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
466 00032378 eventhandler.c:286:EHStatusHandlerThread() powerState: POWER_STATE_POWERED
467 00000596 Card ATR: 3B DA 18 FF 81 B1 FE 75 1F 03 00 31 C5 73 C0 01 40 00 90 00 0C
468 05001478 ifdhandler.c:1146:IFDHPowerICC() action: PowerDown, usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
469 00003148 eventhandler.c:479:EHStatusHandlerThread() powerState: POWER_STATE_UNPOWERED
470 14774363 hotplug_libudev.c:642:HPEstablishUSBNotifications() USB Device removed
471 00000796 hotplug_libudev.c:360:HPRemoveDevice() Removing USB device[0]: Identiv uTrust 3512 SAM slot Token [CCID Interface] (55511514602745) at /dev/bus/usb/001/009
472 00000053 readerfactory.c:608:RFRemoveReader() UnrefReader() count was: 1
473 00000024 eventhandler.c:176:EHDestroyEventHandler() Stomping thread.
474 00000026 ifdhandler.c:379:IFDHGetCapabilities() tag: 0xFB1, usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
475 00000024 ifdhandler.c:379:IFDHGetCapabilities() tag: 0xFB2, usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
476 00000018 eventhandler.c:201:EHDestroyEventHandler() Request stopping of polling thread
477 00000020 ifdhandler.c:344:IFDHStopPolling() usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
478 00397726 eventhandler.c:502:EHStatusHandlerThread() Die
479 00001909 eventhandler.c:216:EHDestroyEventHandler() Thread stomped.
480 00000049 readerfactory.c:1130:RFUnInitializeReader() Attempting shutdown of Identiv uTrust 3512 SAM slot Token [CCID Interface] (55511514602745) 00 00.
481 00000039 ifdhandler.c:282:IFDHCloseChannel() usb:04e6/5816:libudev:0:/dev/bus/usb/001/009 (lun: 0)
482 00000101 ccid_usb.c:797:WriteUSB() write failed (1/9): -4 LIBUSB_ERROR_NO_DEVICE
483 00000147 ccid_usb.c:189:close_libusb_if_needed() libusb_exit
484 00001864 readerfactory.c:991:RFUnloadReader() Unloading reader driver.