1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Development</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Quanta Plus">
</HEAD>
<BODY BACKGROUND="pics/chipcards.jpg">
<h1><A NAME=0>Development</A></h1>
<h2>Table of Content</h2>
<ol>
<li>
<A HREF="#1">How Can I Add Libchipcard Support to My Own Applications ?</A>
</li>
<li>
<A HREF="#2">How Can I Use Libchipcard ?</A>
</li>
<li>
<A HREF="#3">Data Organization On Chip Cards</A>
</li>
<li>
<A HREF="#4">Sending Your Own Command to the Chipcard</A>
</li>
</ol>
<br>
<hr>
<br>
<h2><A NAME="1"></A>1. How Can I Add Libchipcard Support to My Own Applications ?</h2>
Well, the easiest way is to use the automake/autoconf family of tools. To add libchipcard into your project
your <i>./configure.in</i> script should include these lines:<br>
<br>
<table BORDER="1">
<tr>
<td>
<font face="fixed">
<b>AC_LIBCHIPCARD(0.8.0)</b><br>
if test -n "$libchipcard_dir"; then<br>
all_libraries="$all_libraries $libchipcard_libs"<br>
all_includes="$all_includes $libchipcard_includes"<br>
AC_DEFINE(HAS_LIBCHIPCARD)<br>
define_has_libchipcard="#define HAS_LIBCHIPCARD"<br>
fi<br>
AC_SUBST(define_has_libchipcard)<br>
</font>
</td>
</tr>
</table>
<font size="-1">Table: Lines to be included in <i>configure.in</i></font><br>
<br>
You'll need to add a line saying <b>#undef HAS_LIBCHIPCARD</b> to your <i>acconfig.h</i> file, otherwise
<i>aclocal</i>/<i>autoconf</i>/<i>automake</i> will complain about <i>HAS_LIBCHIPCARD</i> not being covered
by <i>config.h</i>.<br>
<br>
Your <i>Makefile.am</i> files could then look like this (taken from tutorial subdir):<br>
<br>
<table BORDER="1">
<tr>
<td>
<font face="fixed">
noinst_PROGRAMS=tutorial1<br>
INCLUDES=<b>@all_includes@</b><br>
<br>
tutorial1_SOURCES = tutorial1.cpp<br>
tutorial1_LDADD = <b>@all_libraries@</b><br>
</font>
</td>
</tr>
</table>
<font size="-1">Table: Example <i>.Makefile.am</i></font><br>
<br>
If you want <i>optional</i> support for libchipcard then you can use this in your *.cpp/*.c/*.h files:<br>
<br>
<table BORDER="1">
<tr>
<td>
<font face="fixed">
#ifdef HAVE_CONFIG_H<br>
# include <config.h> // need this to define HAS_LIBCHIPCARD<br>
#endif<br>
<br>
#ifdef <b>HAS_LIBCHIPCARD</b><br>
# include <<b>chipcard.h</b>><br>
// insert code that uses libchipcard<br>
#endif<br>
</font>
</td>
</tr>
</table>
<font size="-1">Table: Example <i>test.cpp</i></font><br>
<br>
With this in your program files you can use LibChipCard if available or exclude chipcard support if
LibChipCard is missing. This is the way OpenHBCI handles it.<br>
<br><div align="right"><A HREF="#0">Top</A></div><HR><BR>
<h2><A NAME="2"></A>2. How Can I Use Libchipcard ? </h2>
Below is a simple graph which shows the most interesting classes.<br>
<br>
<IMG SRC="pics/ctcard01.gif" ALT="CTCard inheritance" WIDTH=373 HEIGHT=187 ALIGN="middle" BORDER=1>
<p>
From the developers point of view the class <b>CTCard</b> (and its children) is the most important
one. This in fact is the only class you have to deal with. Therfore we'll have a look at this
one and will later discuss the inheriting classes.
</p>
<h3>Introduction Into Communication With Chipcards</h3>
Generally, a program sends some specific commands to the chipcard via the reader (terminal), this
is the so called <b>APDU</b>. It contains at least:
<table BORDER="1">
<tr>
<th>
Name
</th>
<th>
Description
</th>
</tr>
<tr>
<td>
<b>CLA</b>
</td>
<td>
this is the command class byte (in most cases this is <i>0</i>)
</td>
</tr>
<tr>
<td>
<b>INS</b>
</td>
<td>
the instruction byte, specifiying what the card is supposed to do
</td>
</tr>
<tr>
<td>
<b>P1</b>
</td>
<td>
first parameter byte, depends on the instruction the card has to perform
</td>
</tr>
<tr>
<td>
<b>P2</b>
</td>
<td>
second parameter byte, depends on the instruction, too
</td>
</tr>
</table>
<br>
<p>
This APDU (plus some other control and data bytes) is all packed into a <i>struct</i> called <b>CTCommand</b>
(please refer to the API documentation for it's content) and send to the card via the reader.<br>
After the cards response Libchipcard returns the answer and the result code in the very same struct. <br>
As you can see <i>CTCommand</i> is the central object in a dialog with a chip card.
</p>
<h3>CTCard</h3>
<p>
Now, to communicate with the card, you need to setup the described <i>CTCommand</i> struct and feed it
to <b>CTCard</b>'s method <b>execCommand</b>. This method actually sends the APDU from this struct to
the card and retrieves its answer.
</p>
<p>
Well, before you can send anything to the card you must prepare it by calling CTCard::<b>openCard</b>().
This method loads the appropriate driver library (CTAPI), initializes the card reader (if it not already
is) and connects the card to the reader. If this succeeds you can start sending commands.
</p>
<p>
After you have finished working with the card you may want to release it, thus allowing the user to remove
the card safely from the reader. This can be achieved by calling CTCard::<b>closeCard</b>().
</p>
<p>
There are some other interesting methods in this class, but these are the most important ones.
Please refer to the api documentation (downloadable in a separate package from the project page, see this site's
<A HREF="download.html">download</A> section).
</p>
<h3>CTMemoryCard</h3>
<p>
Since there are two basic types of chipcards - memory cards and processor cards - <i>libchipcard</i> offers one
class for each of them.
</p>
<b>This</b> class provides some basic methods which simplify accessing memory cards (like German health insurance
cards). These methods allow you to
<ul>
<li>
select files on the card
</li>
<li>
read data from the card
</li>
<li>
write data onto the card
</li>
</ul>
<p>
The implementation is simple: These methods all create <i>CTCommand</i> objects, fill them with appropriate
data for the corresponding instruction, send this command to the card via <i>execCommand</i>() and return
the result in a <b>CTError</b> object. If you want to check for an error simply call the method <i>isOk()</i>
of this CTError object.
</p>
<p>
You should look at the source of this class to see how simple it is to implement new commands.
</p>
<h3>CTProcessorCard</h3>
<p>
This is the other basic class, it works on processor cards (like EC cards and HBCI cards).<br>
You can:
</p>
<ul>
<li>
select files on the card (there are more variants in selection than with memory cards, again, see apidoc)
</li>
<li>
read data from files on the card
</li>
<li>
write data to files on the card
</li>
</ul>
<h3>Support For Special Cards</h3>
<p>
Generally, libchipcard offers <i>basic</i> support for chip cards.<br>
However, there are two kinds of special chip cards this library supports directly:
</p>
<ul>
<li>
<b>German health insurance cards</b> (<i>Krankenversichertenkarte</i>). There is even a program that dumps
the content of such a card, called <i>qkvk</i>.
</li>
<li>
<b>HBCI cards</b> (home banking cards, the project
<A HREF="http://openhbci.sf.net" TARGET="_top">openHBCI</A> uses libchipcard to access those cards).
</li>
<li>
<b>Memory Cards</b> they are mentioned here again, because LibChipCard provides a file system for storage
of files on an ordinary memory card.
</li>
</ul>
This support is indicated by the existence of the classes
<ul>
<li>
<b>CTKVKCard</b> (for health insurance cards)
</li>
<li>
<b>HBCICard</b> (guess what)
</li>
<li>
<b>CTCardMedium</b> provides the file system. You should have a look at <b>CTFile</b> and <b>CTDirectory</b>,
too.
</li>
<li>
<b>RSACard</b> (for RSA HBCI cards)
</li>
<li>
<b>CTGeldKarte</b> (for German <i>Geldkarten</i> used to digitally store small amounts of money)
</li>
</ul>
<br>
<br><div align="right"><A HREF="#0">Top</A></div><HR><BR>
<h2><A NAME="3"></A>3. Data Organization On Chip Cards</h2>
A chip card normally has the following structure:<br>
<IMG SRC="pics/mf-df-ef.gif" ALT="mf-df-ef" WIDTH=382 HEIGHT=260 BORDER=0>
<h4>Master File</h4>
<p>The master file is the root of the data on the chip card (referred to as "MF"
throughout the api documentation). As with The Highlander there can only be
ONE master file.
This master file may have some "dedicated files"("DF") and "element files"
("EF").
</p>
<h4>Dedicated File</h4>
<p>This is best described as a kind of directoy, which includes element files.
A dedicated file itself does not contain data.
You can select such a data file using the various "selectXX" methods of the
card classes.
</p>
<h4>Element File</h4>
<p>An element file now finally contains the data.
You can select such an element file using the various "selectXX" methods of
the card classes.
</p>
<p>To make it more complicated some cards (mostly memory cards, like German
health insureance cards) do not have data files or element files at all.
They store their data directly in the master file. And these cards do NOT
allow calling the "selectFile" method with other values than "0x3f00", which
specifies the master file.
</p>
<p>But that looks more complicated than it really is, because you rarely try to
read cards you don't have the slightest piece of information for.
In most cases the documentation for the card you want to read tells you if
there are some data/element files to select.
</p>
<p>For example the German health insureance card does NOT have those files
and therefore you can read the data directly from the master file after and even without
selecting it (with selectFile(0x3f00)).
</p>
<br><div align="right"><A HREF="#0">Top</A></div><HR><BR>
<h2><A NAME="4"></A>4. Sending Your Own Command to the Chipcard</h2>
<p>
Now that you know how data is stored on a chip card and how commands are send to the card we can play
around with it. Let's create an example that selects a file on a memory card. To make this example be of use
in any case we simply select the Master File which is accessable on nearly all memory cards (remember, the
simplest memory card is the German medical card, so you can use it for this example).
Well, of course, selecting a file can be done more easily with the already existing methods of CTProcessorCard and
CTMemoryCard, but hey, it's just an example ;-)<br>
This code assumes to be part of a class which inherits CTCard, so the method <i>execCommand()</i> is
available. Another assumption is that the card has already been openend via <i>openCard()</i>.<br>
We'll see the code first and discuss later.
</p>
<table BORDER="1">
<tr>
<td>
<table>
<tr>
<td>
CTCommand cmd;
</td>
<td>
// we need this to send a command to the card
</td>
</tr>
<tr>
<td>
CTError err;
</td>
<td>
// this object will receive the error code our command returns
</td>
</tr>
<tr>
<td>
cmd.setCla(0x00);
</td>
<td>
// class the command belongs to
</td>
</tr>
<tr>
<td>
cmd.setIns(0xa4);
</td>
<td>
// the code of the command <i>Select File</i>
</td>
</tr>
<tr>
<td>
cmd.setP1(0x00);
</td>
<td>
</td>
</tr>
<tr>
<td>
cmd.setP2(0x0);
</td>
<td>
</td>
</tr>
<tr>
<td>
cmd.setLr(255);
</td>
<td>
// expected length of the answer from card
</td>
</tr>
<tr>
<td>
cmd.setData((char) 0x3f);
</td>
<td>
// file id (High byte first)
</td>
</tr>
<tr>
<td>
cmd.addData((char) 0xff);
</td>
<td>
// file id (Low byte)
</td>
</tr>
<tr>
<td>
err=execCommand(cmd);
</td>
</tr>
<tr>
<td>
if (err.isOk()) return true;
</td>
<td>
// return if there was no error
</td>
</tr>
<tr>
<td>
printf("Error was: %s\n",err.errorString().c_str());
</td>
<td>
// show the error code if there was an error
</td>
</tr>
</table>
</td>
</tr>
</table>
<br>
Ok, let's now discuss the code line by line.
<ul>
<li>
<b>CTCommand cmd;</b><br>
<b>CTError err;</b><br>
We need an object of the class CTCommand to send to the card. It will be filled with data in the following
lines. The other object <i>err</i> will receive the result code returned by the method which really executes
our command (<i>CTCard::execCommand()</i>).
</li>
<li>
<b>cmd.setCla(0x00);</b><br>
Commands to the chip card are grouped into command classes.<br>
Since the command to select a file on a card is a standard chip card command defined in <b>ISO 7816-4</b>
the command class is 0x00. Most of the other commands you could possibly send to a chip card fall into this
class.
</li>
<li>
<b>cmd.setIns(0xa4);</b><br>
The command we want to send is <i>Select File</i>. It's ISO code is 0xa4, so this is the instruction code
to store here.
</li>
<li>
<b>cmd.setP1(0x00);</b><br>
<b>cmd.setP2(0x00);</b><br>
As you read above a Chip Card Command has two fixed arguments, called <b>p1</b> and <b>p2</b>. For some
commands these have no special meaning. This is the case with our command. Well, in fact, these parameters
<b>do</b> have a meaning for <i>Select File</i>, but for now we simply ignore that.
</li>
<li>
<b>cmd.setLr(255);</b><br>
This member of CTCommand tells the chip card how many bytes of data we want it to return upon execution
of our command. You might ask what data could possibly be returned upon selecting a file ?<br>
Well, some cards - especially processor cards - return a data block called <i>File Control Information</i>.
We don't need this information now, but for the curious among you: have a look into the class <b>CTTLV_FCI</b>.
When looking at the members of that class you will see what this block contains.
</li>
<li>
<b>cmd.setData((char) 0x3f);</b><br>
<b>cmd.addData((char) 0xff);</b><br>
The real arguments to most interesting commands are transmitted in the data area of the <b>APDU</b>.
The argument to <i>Select File</i> is the identifier of the file we want to select. This id is a 16-bit
number. To store 16 bit we need two bytes, so the data area contains those two bytes stored in
<i>Big Endian</i> (which simply means: most significant byte first, the other mode called <i>Little Endian</i>
is used on intels ix86 architecture. Anyway, the chip cards want the big guy).
</li>
<li>
<b>err=execCommand(cmd);</b><br>
Now that we have setup the whole command object we can give it to the method <i>CTCard::execCommand()</i>
which will send it to the chip card and return it's answer in the very same object.<br>
</li>
<li>
<b>if (err.isOk()) return true;</b><br>
Well, not all days are good days so our command - even if it is that good prepared like ours - can fail.
And that's where <b>CTError</b> comes around. It serves as an extended <i>bool</i> variable. If you simply
want to know if there <b>was</b> an error simply call CTError::isOk().
</li>
<li>
<b>printf("Error was: %s\n",err.errorString().c_str());</b><br>
This shows an informative error message. You might want to look at the API cocumentation of the class
<i>CTError</i> because this class has some usefull members and methods.
</li>
</ul>
What I did not show in this example was that the command may have returned some data. If you are interested
in that data you can find it in the member <i>CTCommand::data</i> (in our case this is <i>cmd.data</i>).<br>
<br>
Well, isn't it easy to send a command to the card ? This is the way other classes implement new commands.
As you already know the class CTCard only contains very basic commands which are encapsulated int some methods,
like CTCard::openCard() and so on.<br>
Inheriting classes simply define new methods which themselves send commands to the chip card by exactly the way
described above.<br>
So the command you see above is derived from a fragment of the method <i>CTMemoryCard::selectFile()</i>.<br>
In fact you should never call the method <i>CTCard::execCommand()</i> directly, better write a class which
inherits <i>CTCard</i> and place the command execution there, thus encapsulating access to the chip card.<br>
<br>
<b>If you have written a class that includes commands usefull for a special card type (like cell phone cards) I
would absolutely appreciate if you send them to <A HREF="mailto:martin@libchipcard.de">me</A>.</b><br>
I would gladly incorporate these classes into future versions of libchipcard after testing them and name you as
<b>the author</b> of that class.
<br>
<br>
</BODY>
</HTML>
|