# PCSC/Ada

PCSC/Ada provides an Ada binding to PC/SC-middleware. The library allows programs written in Ada to communicate with smart cards using the SCard API.

PC/SC is a specification for SmartCard integration in computing environment. PC/SC is implemented in Microsoft Windows 200x/XP and available under Microsoft Windows NT/9x. A free implementation of PC/SC, PC/SC Lite, is available under Linux and bundled with Mac OS X.

## Licence

    Copyright (C) 2008-2014 Reto Buerki

    PCSC/Ada 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.

## Download

### Release version

The current release version of PCSC/Ada is available at http://www.codelabs.ch/download/.

### Verify a Release

To verify the integrity and authenticity of the distribution tarball type the following commands:

    $ wget -q https://www.codelabs.ch/keys/0xDBF6D7E1095FD0D9.asc -O - | gpg --import
    $ gpg --verify libpcscada-{version}.tar.bz2.sig

The key fingerprint of the public key (0xDBF6D7E1095FD0D9) is:

    Key fingerprint = 298F 4B32 C3C4 1D88 5949  86F3 DBF6 D7E1 095F D0D9

### Development version

The current development version of PCSC/Ada is available through its git repository:

    $ git clone http://git.codelabs.ch/git/pcscada.git

A browsable version of the repository is available here: http://git.codelabs.ch/?p=pcscada.git

## Build

To compile PCSC/Ada on your system, you need the following libraries/frameworks installed:

- GNAT (version >= 4.1): http://www.gnu.org/software/gnat/gnat.html

- Ahven (Test-Framework, version >= 1.3): http://ahven.stronglytyped.org/

- PC/SC development files and libraries: e.g. pcsc-lite from http://pcsclite.alioth.debian.org (version >= 1.4.0)

The build process of PCSC/Ada is quite easy and straightforward. Just type in the following commands:

    $ tar xjf libpcscada-{revision}.tar.bz2
    $ cd libpcscada-{revision}
    $ make

If no errors occur during the build process, you have now successfully built the PCSC/Ada library from sources.

## Testing

Before you install PCSC/Ada on your system, you might want to test the library and verify that everything works as expected. PCSC/Ada contains both a unit test suite and an integration test application. To run the unit tests of PCSC/Ada, just type:

    $ make utests

This will run all Ahven based unit tests. All tests should be marked with PASS behind the test name. To run the integration tests of PCSC/Ada, you need to have at least one smart card reader and one smart card ready. Type the following command to run the integration tests:

    $ make itests

This will run an Ada implementation of the pcsc-lite `testpcsc` binary used to test the pcsc-lite framework. If no exception arises, you should be good to go. If you really want make sure everything is alright, compare the output of `make itests` with the output when running `testpcsc` for a given card / reader combination.

## Installation

To install PCSC/Ada on your system, type the following:

    $ make PREFIX=/usr/local install

You must be `root` to install the library system wide. If no `PREFIX` is specified, `$(HOME)/libraries` is used as install destination.

## Examples

The PCSC/Ada example code demonstrates the usage of the PCSC/Ada API. To build all example applications, type the following:

    $ make examples

You can start an example application like so: `obj/examples/pinpad`. The following paragraphs introduce each example application briefly. Also, a code snippet is presented on how to establish a PC/SC context, connect to the first reader of a system and then send some arbitrary command to the smart card.

### examples/cardd

This example application is a simple implementation of a reader monitor using the `Reader_Monitor` task provided by PCSC/Ada. After startup, `cardd` will observe all smart card readers of a system for status changes (e.g. card inserted, card removed). It will print out information if states of readers change.

### examples/pinvery/pinpad

This small application will perform a SPE (secure pin entry) operation with a given card / reader. It will first check if the reader supports this operation and will exit if not. If it does support SPE, the user is asked to enter the PIN of a given smart card by using the pinpad of the smart card reader. The result of the operation is displayed after completion.

### examples/thin

The thin_example binary (`obj/examples/thin_example`) can be used to test the thin binding of PCSC/Ada. You need to adopt the reader name `Reader_Name` in `examples/thin/thin_example.adb` to make this test app work.

### examples/simple

    with PCSC.SCard;

    use PCSC;

    procedure Sample is
       Context : SCard.Context;
       --  PC/SC context
       Card    : SCard.Card;
       --  Card handle
       Readers : SCard.Reader_ID_Set;
       --  Set of readers
    begin

       --  Establish context

       SCard.Establish_Context (Context => Context,
                                Scope   => SCard.Scope_System);

       --  List readers

       Readers := SCard.List_Readers (Context => Context);

       --  Connect to first reader

       SCard.Connect (Context => Context,
                      Card    => Card,
                      Reader  => Readers.First_Item,
                      Mode    => SCard.Share_Shared);

       --  Send APDU to card

       declare
          Recv_Buffer : SCard.Byte_Set (1 .. 10);
          Send_Buffer : constant SCard.Byte_Set
            := (16#00#, 16#A4#, 16#00#, 16#00#, 16#02#, 16#3F#, 16#00#);
          Recv_Length : Natural := 0;
          Recv_PCI    : SCard.IO_Request;
       begin
          SCard.Transmit (Card        => Card,
                          Send_Buffer => Send_Buffer,
                          Recv_Pci    => Recv_PCI,
                          Recv_Buffer => Recv_Buffer,
                          Recv_Len    => Recv_Length);
       end;

       --  Disconnect

       SCard.Disconnect (Card   => Card,
                         Action => SCard.Reset_Card);

       --  Release context

       SCard.Release_Context (Context => Context);
    end Sample;