January 27, 2014

PIV card and Linux

Goal: 
  1. Program a blank Gelmalto PIV card ( Protiva PIV CARD v1.55 DL) so that it contains a certificate, using the RSA keypair generated by the card
  2. Have Linux wpa_supplicant use the certificate in the card to perform EAP-TLS authentication

Card Programming:
Approach 1: Use the NIST PIV card test software
  1. Download the software from: http://csrc.nist.gov/groups/SNS/piv/download.html
    1. You need both the “SP 800-73 Reference Implementation” and the “PIV Data Generator and PIV Data Loader”
  2. Get Java JRE if you don’t have
  3. unzip both of them to a folder, in my case c:\tools\pivcard
    1. Open a “Cmd” windows as Administrator,
    2. cd \tools\pivcard\PIV Middleware\Binaries
    3. install.bat
    4. copy c:\windows\system32\piv.dll  ..\..\ PIV_Test_Data_Software\Binaries
  4. Now you can run the program PIV_Test_Data_Software\Binaries\ PIV Data Loader.exe to write to the card; and use the program JPIV Test Data Generator.jar to generate the data
  5. To piv data loader needs the data from the data generator. Some data generator tips:
    1. Goto “Crypto Provider”, and point it to your root keystore. If you don’t have one, you can use “keystore explorer” software (open source) to create one, and then create a key-pair, and make it a self-signed root CA. (use standard JKS format).
    2. The CA Alias is your CA’s name
    3. The content signer’s alias can be the same as your CA’s alias.
    4. Now put something random in fields of tab CHUID. GUID has to be 16 chars
    5. Under “Certificates tab”, pick “piv auth cert”, “valid from” and “valid to” is in the format of “YYYYMMDDHHMMSS”.
    6. Choose “get public key from file”. This file should be generated by the piv loader program, under “asymmetric key pair”.
    7. Now hit generate, and check console there is no error, and then “Save”
  6. The saved certificate format is weird. It adds a header and footer around the standard “DER” format.
    1. It adds 0x “30 82 LEN1 LEN2” as header. 0x30 in DER format means “sequence of”.  “82 LEN1 LEN2” is the “long form” of the “definite form” encoding of the length.  For “Signature Certificate”, the header is “70 82”.
    2. It also adds a footer of 5 bytes “71 01 00 fe 00”, means “application” tag, “set or set of”, length of 1, content of 00. Then another tag “fe”, meaning “private tag” of 0 byte.
    3. If you want to generate your own certificate instead of using the data generator, I suppose you could generate a DER format certificate, and then wrapper it with header and footer above, then burn to the card using the data loader application. I have not tried this yet.

Approach 2: Use piv-tool inside opensc-tools (piv-tool itself did not work well for me)

  1. Use opensc-tools 0.12.2 or newer
  2. To read the certificate of the card, use:
    1. pkcs11-tool --module=/usr/lib/i386-linux-gnu/opensc-pkcs11.so -r -y cert -a "Certificate for PIV Authentication" > mycert.der (using label to read)
    2. OR, pkcs11-tool --module=/usr/lib/i386-linux-gnu/opensc-pkcs11.so -r -y cert -d 01 -o my.cert (using id to read)
    3. To list all the data objects, use: pkcs11-tool --module=/usr/lib/i386-linux-gnu/opensc-pkcs11.so –O

Wpa_supplicant
# OpenSSL Engine support
# These options can be used to load OpenSSL engines.
# The two engines that are supported currently are shown below:
# They are both from the opensc project (http://www.opensc.org/)
# By default no engines are loaded.
# make the opensc engine available
#opensc_engine_path=/usr/lib/opensc/engine_opensc.so
# make the pkcs11 engine available
#pkcs11_engine_path=/usr/lib/opensc/engine_pkcs11.so
# configure the path to the pkcs11 module required by the pkcs11 engine
#pkcs11_module_path=/usr/lib/pkcs11/opensc-pkcs11.so

It seems that engine_opensc is the old version. The current version should be pkcs11_engine. Opensc-pkcs11.so is the PKCS11 library to access the smartcard.

OpenSC installation under GNU|Linux

  • Communication with smartcard reader is managed by pcsc + libccid.
  • Smartcard drivers and PKCS#11 library is managed by opensc

installing pcsc + libccid + opensc

Modern smartcard readers are CCID compliant.  GNU/Linux can only handle CCID readers. It is recommended to use libccid >= 1.4.5.
$ apt-get install pcscd libccid libpcsclite1 opensc
 
Some important files:
/usr/lib/i386-linux-gnu/opensc-pkcs11.so uses
/usr/lib/i386-linux-gnu/libopensc.so.3, which uses
/usr/lib/i386-linux-gnu/libpcsclite.so.1.0.0
Make sure to add your own user to the pcscd group:
$ adduser foo pcscd

January 24, 2014

PIV CAC card list of certificates

Question:
SP 800-73 Part 1 defines four X.509 certificate data objects and there are key references for asymmetric keys given. One assumes that:

Key Reference 9A <==> X.509 Certificate for PIV Authenication
Key Reference 9B <==> X.509 Certificate for Card Authentication
Key Reference 9C <==> X.509 Certificate for Digital Signature
Key Reference 9D <==> X.509 Certificate for Key Management

is this correct?

Furthermore, it is not stated for which of these key pairs the private key is resident on the card and for which key pairs the private key is held outside the card.
Answer:
The correct relationship is as follows:

Key Reference 9A <==> X.509 Certificate for PIV Authentication. The 9A private key is held on the card.

Key Reference 9B: The Card Management Key (aka Card Application Administration Key) is a symmetric key and has no certificate. The 9B symmetric key is held on the card.

Key Reference 9C <==> X.509 Certificate for Digital Signature. The 9B private key is held on the card.

Key Reference 9D <==> X.509 Certificate for Key Management. The 9D private key is held on the card.

Key Reference 9E <==> X.509 Certificate for Card Authentication Key. Note that the Card Authentication Key may be asymmetric or symmetric. It has a certificate only if it is asymmetric. The private or secret 9E key is held on the card.

January 20, 2014

The novel way to build cross compiler tools

http://www.cis.upenn.edu/~milom/cross-compile.html

The reason it is novel is because it takes the target header file and library directly without recompiling them. Therefore this approach is much simpler than the regular from scratch method.

How to Cross-Compile GCC for SPARC Solaris

Computer and Information Sciences Department
University of Pennsylvania
January 2010
To make it easier for my CIS534 students to compile code for our one and only SPARC machine (a 128-thread Niagara T2 box, generously donated by Sun Microsystems), I created a cross-compiler for GCC on x86/Linux to SPARC/Solaris. This page documents how I did it. I'm putting it on-line in case anyone else finds it helpful.

Overview

There are three steps to building the cross compiler:
  1. Specifying the configuration and paths
  2. Finding and installing the proper system header files and libraries
  3. Cross-compiling GNU binutils and GCC

Definitions and Configuration

  • The "host" is the machine on which the compiler executes (x86/Linux in my case). By default, the configure scripts will automatically figure this out.
  • The "target" is the machine on which the output binaries will execute (for SPARC/Solaris in my case, it should be sparc-sun-solaris2.10). This needs to be set explicitly. You can find out the proper target string by executing gcc -dumpmachine.
  • The "prefix" is the instalation prefix where the cross-compiler will be installed.
  • The "sysroot" is the location the cross compiler will look for header files and libraries. The sysroot directory acts as if it is the root of the system,. So, for example, header files go in $SYSROOT/usr/include/ and library files go in $SYSROOT/usr/lib/, etc.
I set these options using environment variables:
setenv TARGET sparc-sun-solaris2.10
setenv PREFIX /mnt/castor/seas_home/c/cis534/public/cross/
setenv SYSROOT $PREFIX/sysroot/
set path = ( $path $PREFIX/bin )

mkdir $PREFIX
mkdir $SYSROOT

System Headers and Libraries

To be able to build and link applications, the cross-compiler needs access to the system header files. As building the compiler also uses some of these files, installing these files needs to be done first. If you have access to the target machine, you can just copy the files into $SYSROOT. Otherwise, you'll need to download the files from the proper distribution. To copy the files, I piped tar through SSH to the SPARC machine (arachnid, in our case), as I could not find an option to get SCP to preserve symbolic links:
cd $SYSROOT
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/local/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/local/lib" | tar -xvf -
Copying the above directories worked for what I needed to do, but you might also considering copying additional headers and libraries:
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/openwin/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/dt/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/X11/include" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/openwin/lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/dt/lib" | tar -xvf -
ssh milom@arachnid.seas.upenn.edu "tar -cf - /usr/X11/lib" | tar -xvf -

Cross-compiling GNU binutils and GCC

Building binutils and GCC is reasonable straightforward (if everything works), by downloading, unpacking, configuring, running make, and then make install for both:
mkdir /scratch/users/build
cd /scratch/users/build

wget http://ftp.gnu.org/gnu/binutils/binutils-2.20.tar.gz
tar -xvzf binutils-2.20.tar.gz
mkdir build-binutils
cd build-binutils/
../binutils-2.20/configure -target=$TARGET --prefix=$PREFIX -with-sysroot=$SYSROOT -v
make all; make install

wget http://ftp.gnu.org/gnu/gcc/gcc-4.4.2/gcc-4.4.2.tar.gz
tar -xvzf gcc-4.4.2.tar.gz
mkdir build-gcc
cd build-gcc
../gcc-4.4.2/configure --target=$TARGET --with-gnu-as --with-gnu-ld  --prefix=$PREFIX -with-sysroot=$SYSROOT --disable-libgcj --enable-languages=c,c++ -v
make all; make install
You can delete the build directories once the make install has been completed. Also, the above config for GCC will only build C and C++, but you can remove that option if you need to build GCC with support for other languages.

Testing

This will create two sets of binaries. The directory $PREFIX/bin/ will include executables of the form: sparc-sun-solaris2.10-gcc. You should be able to use this to compile a program:
$PREFIX/bin/sparc-sun-solaris2.10-gcc hello.c -o hello
Running file hello should return something like:
ELF 32-bit MSB executable, SPARC32PLUS, V8+ Required, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Then copy hello over to the SPARC box, and see if it runs. Although it shouldn't be necessary, if it gives dynamic linking errors, you could try setting the LD_LOAD_LIBRARY environment variable.
Update (April 2010): If you're getting dynamic linking errors, particularly with C++, you may need to use the "-R" option when compiling. This option specifies a path the dynamic loader on the target to look for the libraries:
$PREFIX/bin/sparc-sun-solaris2.10-gcc -R $PREFIX/$TARGET/lib/sparcv9/ hello.c -o hello
This assumes the -R path is mounted on the target machine. If not, you may need to copy over those files and adjust the -R path accordingly.

January 16, 2014

serial port to tcp redirection and terminal emulation

Usually, when you connect to a serial port, on Windows, you would use Tera Term, or Putty, (or secureCRT, etc), and on Linux you would use picocom, minicom, etc. All these program do at least two things:

1. connect to a serial device
2. emulate a terminal (VT100, etc)

Now if  you want to remotely access that serial port, and you can use a program to convert the serial data stream to TCP data stream (ser2net/remserial on Linux, com2tcp on Windows). The only thing is that you still need a "terminal emulator" to get full capability (vi, etc) from that console.

One way to do it to use "putty", and use "raw tcp" and make sure you set "local echo" to "off", and "local line editing" to off on the "Terminal" tab of the Settings.


Another way is to run a local tcp-to-com kind of program. On linux, you can use remserial to create a virtual com port, and on Windows I think you can use com2tcp/com0com to do it. But I think using putty  to access it directly is easier.

com2tcp tips

com2tcp can be used on Windows to redirect UART port to TCP port. Here is an example command to do that:

     com2tcp --baud 9600 --ignore-dsr \\.\com1 8888


Note that "--ignore-dsr" is needed most of the times, otherwise com2tcp may close tcp ports when it detects DSR off.

January 15, 2014

kermit file transfer and u-boot

I usually use "picocom" on Linux to talk through a serial line to U-boot. Of course I have used "minicom" before but it seems heavy. There is even "microcom". However, so far I have stayed away from "kermit" just because it seems to be so complicated and not totally free in license.

Now the authors in Columbia University has made it totally free (BSD license), and U-boot supports its file transfer protocol (loadb command) (u-boot does not support ZModem, only Ymodem). I take a look at it.

It looks like a nice serial terminal emulator with file transfer capability. The macro part is really handy. Below is my .kermrc file with two user-defined macros for uploading uboot and kernel images using the kermit protocol in a different baud rate than console baud

cat ~/.kermrc
set line /dev/ttyUSB1
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5
set delay 1
connect
define sendb {
        set speed 230400
        output \x0D
        output \x0D
        send u-boot.bin
        input 1 "NEVER"
        set speed 115200
        output \x1B
        output \x0D
}
define sendk {
        set speed 230400
        output \x0D
        output \x0D
        send uImage
        input 1 "NEVER"
        set speed 115200
        output \x1B
        output \x0D
}

January 10, 2014

Qt, embedded Linux, Keyboard map

If you happen to use Qt for your embedded Linux project, and need keyboard support. The following things may be useful.

1. Qt supports keyboard keymap since version 4.6. By default it uses the default keymap,  which has a bug (unfixed as of early 2014) that prevents CAPS LOCK and num lock to work. See details here: https://bugreports.qt-project.org/browse/QTBUG-9843 . You can either patch it using the patch file on that bug report , or use an external keymap file.

2. To use an external keymap file, you need to obtain the Linux keymap file package (http://lct.sourceforge.net/data.html click on "Download" on the left),  untar it, get "keymaps/i386/qwerty/us-latin1.kmap". This file is for the default US keyboard. Use the keymap that matches your keyboard.

3. Qt includes a tool named "kmap2qmap" to convert the above kmap file to a qmap file that Qt applications can uses. You may want to patch the "kmap2qmap" source code to prevent this bug. It's a simple patch. Then run it as "kmap2qmap us-latin1.kmap us.qmap", and you should get the new file "us.qmap". It is safe to ignore the warnings.

4. Put this qmap file in your system, let's assume "/opt/us.qmap", and set the following env variable:
export QWS_KEYBOARD="<driver>:keymap=/opt/us.qmap".  I use a qt keyboard driver plugin in my setup so I don't use the variable, but this is supposed to be how your run it. More details here.

That's it. Now your new keyboard should work. :-) I know, finally!

P.S. this website (and this one) provides good information on keyboard scan code (Set 1, Set 2, Set 3, USB HID, etc)

msed - multiple search and replace on a file from command line

msed is a simple command-line program that search and replace multiple words in a file. You put the words to be searched and replaced in the "Pattern" file, and the run msed with "msed Pattern-file Target-file".

msed does word boundary replacement. Therefore, when you ask it to replace "kit" to "kat", it will respect and not replace "kitty" or "kit0".
msed will output to standard output. You can redirect it to a file.
The code:


#!/usr/bin/php

# Perform multiple search and replace on the target file

function usage(){
    echo "\n" .
         "Usage:  msed   [-r]\n" .
         "pattern-file contains lines of Search and Replace, example\n" .
         "   Pig Dog\n" .
         "   Cat Kitty\n" .
         "-r: reversed pattern file, ie. Replace is first, Search is second\n";
}

if (count($argv)!=3 && count($argv)!=4){
    usage();
    exit(-1);
}

$pfile=$argv[1];
$tfile=$argv[2];
$reverse=false;
if (count($argv)==4){
    $reverse=true;
    fprintf(STDERR,"reversed serach and replace patterns\n");
}

## check files
$pat_str=file_get_contents($pfile);
if ($pat_str===FALSE){
    die("Error opening pattern file $pfile\n");
}
$t_str=file_get_contents($tfile);
if ($t_str===FALSE){
    die("Error opening target file $tfile\n");
}
$pat_arr=explode("\n",$pat_str);
if (count($pat_arr)<1){
    die("Error, no pattern found in file.\n");
}

## read patterns and sort by length
$pat=array("s"=>array(),"r"=>array());
foreach($pat_arr as $pline){
    $pline=trim($pline);
    if (strlen($pline)<1) continue;
    $parts=preg_split('/\s+/',$pline);
    if (count($parts)!=2){
        fprintf(STDERR,"skipping invalid pattern line:$pline\n");
        continue;
    }
    if ($reverse){
        $pat["s"][]="/\b$parts[1]\b/";
        $pat["r"][]=$parts[0];
    }else{
        $pat["s"][]="/\b$parts[0]\b/";
        $pat["r"][]=$parts[1];
    }
}

## do search and replacement
$t_str=preg_replace($pat["s"],$pat["r"],$t_str);
echo($t_str);
                

January 9, 2014

Linux USB and USB keyboard driver debugging tips

1. USBMON is your friend. It has very little dependency and is very useful in giving you low level USB packets.  The short but complete and helpful documentation is at: https://www.kernel.org/doc/Documentation/usb/usbmon.txt

2. The USB Made Simple website with details of how USB works. The articles are fairly short so you can read and understand how USB works. Very useful. Site: http://www.usbmadesimple.co.uk/ums_3.htm

3. Linux Device Driver boot (Rev 3) has a good chapter about USB Urbs and the architecture of the USB stack on Linux, giving you a good overall picture of how things work. Site: http://www.makelinux.net/ldd3/chp-13-sect-3

4. Linux Documentation input.txt provides very useful information on Linux handling of USB HID and events. Address: https://www.kernel.org/doc/Documentation/input/input.txt

5. freedesktop.org publishes a tool called 'evtest' that can read events to Linux device /dev/eventX. This can be really useful in viewing raw events. The package has only one C file and no lib dependency. So very easy to compile for your target. Site: http://cgit.freedesktop.org/evtest/

6. TI's Wiki has a good overview of how TI's USB stack fits into the Linux USB stack. Site: http://processors.wiki.ti.com/index.php/DM81xx_AM38XX_USB_User_Guide#Linux_USB_Stack_Architecture

January 2, 2014

RJ11 telephone cables

Technical term:
RJ11, RJ14, and RJ25 all use the same physical connector.

RJ11 has two wires.
RJ14 has 4 wires.
RJ25 has 6 wires.

If you want to buy RJ25 connector/cable, search for the term "6p6c" such as on amazon.com

Another theory:
RJ11 has 4 wires: 6p4c
RJ12 has 6 wires: 6p6c