- Remove all references to usbtoken, use OpenCT instead

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1639 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aet 2003-11-25 11:17:02 +00:00
parent b6796d0404
commit d12b21f633
26 changed files with 4 additions and 3380 deletions

View File

@ -526,18 +526,6 @@ else
CFLAGS_PCSC=""
fi
dnl --enable-usbtoken option.
AC_ARG_ENABLE(usbtoken, AC_HELP_STRING(
[--enable-usbtoken], [enable the usbtoken reader backed. [default=no]]),
, enable_usbtoken=no)
if test "x$enable_usbtoken" = "xyes"; then
AC_DEFINE(HAVE_USBTOKEN, 1, [Enable usbtoken support])
USBTOKEN_MSG=yes
else
USBTOKEN_MSG=no
fi
AM_CONDITIONAL(HAVE_USBTOKEN, test "x$USBTOKEN_MSG" = "xyes")
OPENCT_MSG=no
openct_path=/usr
AC_SUBST(OPENCT_CFLAGS)
@ -868,7 +856,6 @@ src/sslengines/Makefile
src/tests/Makefile
src/tests/regression/Makefile
src/tools/Makefile
src/usbtoken/Makefile
win32/Makefile
])
@ -910,7 +897,6 @@ echo "Random number collection: ${RAND_MSG}"
echo "OpenSSL support: ${SSL_MSG}"
echo " with engine: ${ENGINE_MSG}"
echo "PC/SC support: ${PCSC_MSG}"
echo "USBToken support: ${USBTOKEN_MSG}"
echo "OpenCT support: ${OPENCT_MSG}"
echo "Assuan support: ${ASSUAN_MSG}"
echo "LDAP support: ${LDAP_MSG}"

View File

@ -24,4 +24,3 @@ Makefile.in
core
gmon.out
pkcs15-profile.5
usbtoken.html

View File

@ -1,8 +1,8 @@
# Process this file with automake to create Makefile.in
XSLTPROC = @XSLTPROC@
HTMLFILES = usbtoken.html opensc.html opensc.css
XMLFILES = usbtoken.xml opensc.xml opensc.xsl
HTMLFILES = opensc.html opensc.css
XMLFILES = opensc.xml opensc.xsl
MAINTAINERCLEANFILES = Makefile.in pkcs15-profile.5

View File

@ -964,52 +964,6 @@
<p></p>
<p>
Usbtoken is a small driver for usb crypto devices only.
It does not need any other helper software and is
included in OpenSC for convenience. However Usbtoken is
deprecated, the new OpenCT software is now the
recommended way to access usb crypto tokens. Usbtoken
is no longer actively developed, but bugs are still
fixed and help is provided on the OpenSC mailing list
at
<tt class="email">
&lt;
<a href="mailto:opensc-devel@opensc.org">
opensc-devel@opensc.org
</a>&gt;
</tt>.
</p>
<p>
If you still want to use OpenSC with Usbtoken, please
configure OpenSC like this:
</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
$ cd opensc-&lt;version&gt;
$ ./configure --enable-usbtoken
</pre>
</td>
</tr>
</table>
<p></p>
<p>
Documentation on Usbtoken is in the file
<a href="usbtoken.html" target="_top">
usbtoken.html
</a>.
</p>
<p>
CT-API is a standard format for drivers for smart card
readers. It was invented in the eighties for DOS

View File

@ -343,33 +343,6 @@ $ ./configure --with-openct=/path/to/openct
</screen>
</para>
<para>
Usbtoken is a small driver for usb crypto
devices only. It does not need any other helper
software and is included in OpenSC for
convenience. However Usbtoken is deprecated,
the new OpenCT software is now the recommended
way to access usb crypto tokens. Usbtoken
is no longer actively developed, but bugs are
still fixed and help is provided on the
OpenSC mailing list at
<email>opensc-devel@opensc.org</email>.
</para>
<para>
If you still want to use OpenSC with Usbtoken,
please configure OpenSC like this:
<screen>
$ cd opensc-&lt;version&gt;
$ ./configure --enable-usbtoken
</screen>
</para>
<para>
Documentation on Usbtoken is in the file
<ulink url="usbtoken.html" />.
</para>
<para>
CT-API is a standard format for
drivers for smart card readers. It was

View File

@ -1,475 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<title>Driver for USB Crypto Token</title>
<link rel="stylesheet" href="opensc.css" type="text/css" />
<meta name="generator"
content="DocBook XSL Stylesheets V1.60.1" />
</head>
<body>
<div class="article" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h1 class="title">
<a id="id2799405"></a>Driver for USB Crypto Token</h1>
</div>
<div>
<div class="author">
<h3 class="author">
<span class="firstname">Andreas</span>
<span class="surname">Jellinghaus</span>
</h3>
</div>
</div>
</div>
<div></div>
<hr />
</div>
<div class="toc">
<p>
<b>Table of Contents</b>
</p>
<dl>
<dt>
<a href="#id2799452">About usbtoken</a>
</dt>
<dt>
<a href="#id2799883">Status</a>
</dt>
<dt>
<a href="#id2799935">Compatibility</a>
</dt>
<dd>
<dl>
<dt>
<a href="#id2799997">Compatibility List</a>
</dt>
</dl>
</dd>
<dt>
<a href="#id2800018">Requirements</a>
</dt>
<dt>
<a href="#id2800062">Compiling OpenSC with USBtoken
support</a>
</dt>
<dt>
<a href="#id2800076">Installation without hotplug
utils</a>
</dt>
<dt>
<a href="#id2800125">Installation with hotplut
utils</a>
</dt>
<dt>
<a href="#id2800184">Security</a>
</dt>
<dt>
<a href="#id2800210">Debugging</a>
</dt>
<dt>
<a href="#id2800262">Porting</a>
</dt>
</dl>
</div>
<div class="warning"
style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Warning</h3>Usbtoken is obsolete. Please
use OpenCT, a new and much improved smartcard framework. You
can download OpenCT from
<a href="http://www.opensc.org/files/snapshots"
target="_top">http://www.opensc.org/files/snapshots</a></div>
<p>If you still want to use ustoken, you need to enable it
while configureing OpenSC. For example
<tt class="prompt">./configure --enable-usbtok</tt></p>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2799452"></a>About usbtoken</h2>
</div>
</div>
<div></div>
</div>
<p>This project implements a way for OpenSC to access usb
crypto tokens such as:</p>
<div class="orderedlist">
<ol type="1">
<li>Aladdin eToken PRO</li>
<li>Rainbow iKey 2032</li>
<li>Rainbow iKey 3000</li>
<li>Entron CryptoIdentity</li>
</ol>
</div>
<p>This project is the successor of the etoken project
which created an PC/SC ifdhandler for the Aladdin eToken
PRO. Interfacing directly with OpenSC is much easier than
using one of the old but well known interfaces like CT-API
or PC/SC.</p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2799883"></a>Status</h2>
</div>
</div>
<div></div>
</div>
<p>The Aladdin eToken PRO works fine. Beware: versions
older than 4.1.57 or so might have a problem with USB
controllers found on mainboards with VIA chipsets or any
uhci based USB controllers. I don't know the details.</p>
<p>The Eutron CryptoIdentity IT-Sec works fine.</p>
<p>The Eutron CryptoIdentity blue/grey has a smart card
operating system by Algorithmic Research. Documentation is
only available under a NDA. I'm to busy to sign it and
implement support for their driver right now. The usb layer
works fine, but I don't know the commands i could send or
how a valid response would look like.</p>
<p>The Rainbow iKey 2032 has a smart card operating system
by DataKey. Documentation is only available under a NDA:
I'm to busy to sign it and implement support for their
driver right now. The usb layer is supposed to work fine,
but I cannot test that without knowing the commands and
responses.</p>
<p>The Rainbow iKey 3000 has a smart card operating system
by Gersike and Devrient called StarCos SPK 2.3. The usb
layer is supposed to work fine, but not tested. Further
work on the card driver in OpenSC and pkcs11 and pkcs15
framework is currently done, please be patient.</p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2799935"></a>Compatibility</h2>
</div>
</div>
<div></div>
</div>
<p>PKCS#11 is an API standard. It allowes applications to
use any library that implements PKCS#11 without changeing
code.</p>
<p>PKCS#15 is a standard that describes how a PKCS#11
library should work. Smartcards have a filesystem, and
PKCS#15 makes sure every PCKS#11 library saves data in the
right directory, and reads from the right directory.</p>
<p>OpenSC offers library implementing the PKCS#11 API
according to the PKCS#15 standard. Compatibility has been
tested with cards that contain data according to PKCS#15
like the finish and swedish ID card.</p>
<p>However even if OpenSC can use the usbtoken driver to
access a smartcard in a usb token, it will only look in
directories where the certificates should be according to
PKCS#15.</p>
<p>Problem is: most vendors do not install the certificates
and keys in the right place, they do not implement PKCS#15
in their drivers and libraries.</p>
<p>The result is this: you can create a PKCS#15 structure
under linux, can put certifiactes and keys and data in it,
but when using the vendors drivers you will not see it.
Also if you use the vendors driver to store keys,
certificates and data, OpenSC will not see it.</p>
<p>Using OpenSC on Windows and Linux could solve the
situation, but I have no experience with OpenSC under
Windows, sorry.</p>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title">
<a id="id2799997"></a>Compatibility List</h3>
</div>
</div>
<div></div>
</div>
<p>Aladdin: Their Windows and Unix drivers store keys and
certificates in the wrong place. (not compatible with
PKCS#15)</p>
<p>Eutron: Their Windows and Unix drivers store keys and
certificates in the wron place. (not compatible with
PKCS#15)</p>
</div>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800018"></a>Requirements</h2>
</div>
</div>
<div></div>
</div>
<p>Currently the usbtoken only works with linux (kernel
2.4.* series and kernel 2.5.* series were tested), but
ports to other operating systems should be possible. If you
want to port usbtoken, please contact: Andreas Jellinghaus
<tt class="email">&lt;
<a href="mailto:aj@dungeon.inka.de">
aj@dungeon.inka.de</a>&gt;</tt></p>
<p>You need a kernel compiled with CONFIG_HOTPLUG and
CONFIG_USB_DEVICEFS, and the usb device filesystem must be
mounted to
<tt class="filename">/proc/bus/usb</tt>. And of course
kernel support for your usb hub.</p>
<p>I guess any linux distribution with kernel 2.4 will be
allright and require no changes.</p>
<p>Users of other operating systems, please see the porting
section.</p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800062"></a>Compiling OpenSC with USBtoken
support</h2>
</div>
</div>
<div></div>
</div>
<p>Call configure with --enable-usbtoken and it compile ok.
No special libraries or stuff needed.</p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800076"></a>Installation without hotplug
utils</h2>
</div>
</div>
<div></div>
</div>
<p>
<b class="command">ls /sbin/hotplug</b>
</p>
<p>If there is no such file, the installation is very
easy:</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
ln -s /path/to/opensc/sbin/usbtoken /sbin/hotplug
mkdir /var/run/usbtoken
chmod 755 /var/run/usbtoken
</pre>
</td>
</tr>
</table>
<p></p>
<p>Now attach some usb token. The kernel will start
<tt class="filename">/sbin/hotplug</tt>, and you can see
some usbtoken running as daemon: you will find a pid file
in
<tt class="filename">/var/run</tt>and a socket in
<tt class="filename">/var/run/usbtoken/</tt>.</p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800125"></a>Installation with hotplut
utils</h2>
</div>
</div>
<div></div>
</div>
<p>First the general instructions, then the debian specific
instructions. As usual debian does everything a bit
different. That doesn't mean it is necessarily better or
worse.</p>
<p>Edit
<tt class="filename">/etc/hotplug/usb.usermap</tt>and add
these lines:</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
usbtoken 0x0003 0x0529 0x050c 0x0000 0x0001 0xff 0x00 0x00 0xff
0x00 0x00 0x00000000
usbtoken 0x0003 0x0529 0x0514 0x0000 0x0001 0xff 0x00 0x00 0xff
0x00 0x00 0x00000000
usbtoken 0x0003 0x04b9 0x1202 0x0000 0x0001 0xff 0x00 0x00 0xff
0x00 0x00 0x00000000
usbtoken 0x0003 0x04b9 0x1300 0x0000 0x0001 0xff 0x00 0x00 0xff
0x00 0x00 0x00000000
usbtoken 0x0003 0x073d 0x0005 0x0020 0x0001 0xff 0x00 0x00 0xff
0x00 0x00 0x00000000
</pre>
</td>
</tr>
</table>
<p></p>
<p>Create the directory
<tt class="filename">/etc/hotplug/usb</tt>and add a symlink
to usbtoken. Also create the directory
<tt class="filename">/var/run/usbtoken</tt>and set
permissions to 0755 (everyone can access that
directory):</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
ln -s /path/to/opensc/sbin/usbtoken /etc/hotplug/usb/
mkdir /var/run/usbtoken
chmod 0755 /var/run/usbtoken
</pre>
</td>
</tr>
</table>
<p></p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800184"></a>Security</h2>
</div>
</div>
<div></div>
</div>
<p>By default everyone can use the usbtokens. If you want
to limit this to a certain user:</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
chown user /var/run/usbtoken/
chmod 0700 /var/run/usbtoken/
</pre>
</td>
</tr>
</table>
<p>Or if you want to limit this to a certain group:</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
chgrp group /var/run/usbtoken/
chmod 0750 /var/run/usbtoken/
</pre>
</td>
</tr>
</table>
<p></p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800210"></a>Debugging</h2>
</div>
</div>
<div></div>
</div>
<p>TODO: send me problem reports and I will add advice
here.</p>
<p>Edit src/usbtoken/Makefile and Makefile.in and add
"-DUSB_DEBUG" to CFLAGS. make clean, make, make install.
Now it will dump all usb traffic to syslog. I should be
able to understand what is going wrong based on that log
file.</p>
<p>For development I use a special crafted
<tt class="filename">/sbin/hotplug</tt>shell script that
creates another script
<tt class="filename">/root/sim</tt>whis I invoke in an
xterm. That script spawns gdb so I can debug the whole
process. In gdb I usualy set a breakpoint, and run the
command with
<b class="command">r usb</b>. My hotplug script:</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
#!/bin/sh
if [ -n "$PRODUCT" ]
then
if [ "$ACTION" = "add" ]
then
export &gt; /root/sim
echo "echo $*" &gt;&gt; /root/sim
echo gdb /home/aj/opensc/sbin/usbtoken &gt;&gt;
/root/sim
fi
fi
exit 0
</pre>
</td>
</tr>
</table>
<p></p>
</div>
<div class="section" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a id="id2800262"></a>Porting</h2>
</div>
</div>
<div></div>
</div>
<p>To port usbtoken mainly
<tt class="filename">usb.c</tt>needs some changes. The core
sequence for linux is:</p>
<table border="0" bgcolor="#E0E0E0">
<tr>
<td>
<pre class="screen">
#include &lt;linux/usbdevice_fs.h&gt;
...
struct usbdevfs_ctrltransfer ctrl;
int rc;
ctrl.requesttype = type;
ctrl.request = req;
ctrl.value = value;
ctrl.index = index;
ctrl.length = size;
ctrl.data = buf;
ctrl.timeout = 10000;
rc = ioctl(usbtoken.usbfd, USBDEVFS_CONTROL, &amp;ctrl);
</pre>
</td>
</tr>
</table>
<p>rc now has the error (-1/errno/strerror) or the number
of bytes read/written on success. Change it to suit your
OS, or let me know how to do it, and usb should work.</p>
<p>Usbtoken also needs an usb device filesystem or some
device it can open and use with I/O controls. That should
be available with every OS.</p>
<p>Finaly usbtoken depends to be called by some hotplug
mechanism. Under linux the kernel executes
<tt class="filename">/sbin/hotplug</tt>everytime a device
is added (or removed, but I don't use that). If your OS has
no such service, you can write a daemon that somehow finds
out when a device is added and start usbtoken with the
required environment settings.</p>
<p>Windows? Ugh. I have no idea about windows, what we can
do, how it works, etc. Volunteers welcome.</p>
</div>
</div>
</body>
</html>

View File

@ -1,390 +0,0 @@
<?xml version="1.0" encoding="iso8859-1" ?>
<article ns="http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<articleinfo>
<author>
<firstname>Andreas</firstname>
<surname>Jellinghaus</surname>
</author>
<title>Driver for USB Crypto Token</title>
</articleinfo>
<warning>
Usbtoken is obsolete. Please use OpenCT, a new and
much improved smartcard framework. You can download
OpenCT from
<ulink url="http://www.opensc.org/files/snapshots" />
</warning>
<para>
If you still want to use ustoken, you need to enable it
while configureing OpenSC. For example
<prompt>./configure --enable-usbtoken</prompt>
</para>
<toc></toc>
<section>
<title>About usbtoken</title>
<para>
This project implements a way for OpenSC to access
usb crypto tokens such as:
</para>
<orderedlist>
<listitem>Aladdin eToken PRO</listitem>
<listitem>Rainbow iKey 2032</listitem>
<listitem>Rainbow iKey 3000</listitem>
<listitem>Entron CryptoIdentity</listitem>
</orderedlist>
<para>
This project is the successor of the etoken
project which created an PC/SC ifdhandler for the
Aladdin eToken PRO. Interfacing directly with
OpenSC is much easier than using one of the
old but well known interfaces like CT-API or PC/SC.
</para>
</section>
<section>
<title>Status</title>
<para>
The Aladdin eToken PRO works fine.
Beware: versions older than 4.1.57 or so
might have a problem with USB controllers
found on mainboards with VIA chipsets
or any uhci based USB controllers.
I don't know the details.
</para>
<para>
The Eutron CryptoIdentity IT-Sec works fine.
</para>
<para>
The Eutron CryptoIdentity blue/grey has a
smart card operating system by Algorithmic
Research. Documentation is only available
under a NDA. I'm to busy to sign it and
implement support for their driver right now.
The usb layer works fine, but I don't know
the commands i could send or how a valid
response would look like.
</para>
<para>
The Rainbow iKey 2032 has a smart card operating
system by DataKey. Documentation is only available
under a NDA: I'm to busy to sign it and
implement support for their driver right now.
The usb layer is supposed to work fine,
but I cannot test that without knowing
the commands and responses.
</para>
<para>
The Rainbow iKey 3000 has a smart card operating
system by Gersike and Devrient called StarCos
SPK 2.3. The usb layer is supposed to work fine,
but not tested. Further work on the card driver
in OpenSC and pkcs11 and pkcs15 framework
is currently done, please be patient.
</para>
</section>
<section>
<title>Compatibility</title>
<para>
PKCS#11 is an API standard. It allowes applications
to use any library that implements PKCS#11 without
changeing code.
</para>
<para>
PKCS#15 is a standard that describes how a PKCS#11
library should work. Smartcards have a filesystem,
and PKCS#15 makes sure every PCKS#11 library
saves data in the right directory, and reads
from the right directory.
</para>
<para>
OpenSC offers library implementing the PKCS#11 API
according to the PKCS#15 standard. Compatibility
has been tested with cards that contain data
according to PKCS#15 like the finish and swedish
ID card.
</para>
<para>
However even if OpenSC can use the usbtoken driver
to access a smartcard in a usb token, it will
only look in directories where the certificates
should be according to PKCS#15.
</para>
<para>
Problem is: most vendors do not install the
certificates and keys in the right place,
they do not implement PKCS#15 in their
drivers and libraries.
</para>
<para>
The result is this: you can create a PKCS#15
structure under linux, can put certifiactes
and keys and data in it, but when using the
vendors drivers you will not see it. Also
if you use the vendors driver to store keys,
certificates and data, OpenSC will not see it.
</para>
<para>
Using OpenSC on Windows and Linux could solve
the situation, but I have no experience with
OpenSC under Windows, sorry.
</para>
<section>
<title>Compatibility List</title>
<para>
Aladdin: Their Windows and Unix drivers store
keys and certificates in the wrong place.
(not compatible with PKCS#15)
</para>
<para>
Eutron: Their Windows and Unix drivers store
keys and certificates in the wron place.
(not compatible with PKCS#15)
</para>
</section>
</section>
<section>
<title>Requirements</title>
<para>
Currently the usbtoken only works with linux
(kernel 2.4.* series and kernel 2.5.* series
were tested), but ports to other operating
systems should be possible. If you want to
port usbtoken, please contact: Andreas Jellinghaus
<email>aj@dungeon.inka.de</email>
</para>
<para>
You need a kernel compiled with CONFIG_HOTPLUG
and CONFIG_USB_DEVICEFS, and the usb device filesystem
must be mounted to <filename>/proc/bus/usb</filename>.
And of course kernel support for your usb hub.
</para>
<para>
I guess any linux distribution with kernel 2.4
will be allright and require no changes.
</para>
<para>
Users of other operating systems, please see
the porting section.
</para>
</section>
<section>
<title>Compiling OpenSC with USBtoken support</title>
<para>
Call configure with --enable-usbtoken and it
compile ok. No special libraries or stuff needed.
</para>
</section>
<section>
<title>Installation without hotplug utils</title>
<para>
<command>ls /sbin/hotplug</command>
</para>
<para>
If there is no such file, the installation
is very easy:
<screen>
ln -s /path/to/opensc/sbin/usbtoken /sbin/hotplug
mkdir /var/run/usbtoken
chmod 755 /var/run/usbtoken
</screen>
</para>
<para>
Now attach some usb token. The kernel will start
<filename>/sbin/hotplug</filename>, and you can
see some usbtoken running as daemon: you will find
a pid file in <filename>/var/run</filename>
and a socket in <filename>/var/run/usbtoken/</filename>.
</para>
</section>
<section>
<title>Installation with hotplut utils</title>
<para>
First the general instructions, then the debian
specific instructions. As usual debian does
everything a bit different. That doesn't mean
it is necessarily better or worse.
</para>
<para>
Edit <filename>/etc/hotplug/usb.usermap</filename>
and add these lines:
<screen>
usbtoken 0x0003 0x0529 0x050c 0x0000 0x0001 0xff 0x00 0x00 0xff 0x00 0x00 0x00000000
usbtoken 0x0003 0x0529 0x0514 0x0000 0x0001 0xff 0x00 0x00 0xff 0x00 0x00 0x00000000
usbtoken 0x0003 0x04b9 0x1202 0x0000 0x0001 0xff 0x00 0x00 0xff 0x00 0x00 0x00000000
usbtoken 0x0003 0x04b9 0x1300 0x0000 0x0001 0xff 0x00 0x00 0xff 0x00 0x00 0x00000000
usbtoken 0x0003 0x073d 0x0005 0x0020 0x0001 0xff 0x00 0x00 0xff 0x00 0x00 0x00000000
</screen>
</para>
<para>
Create the directory
<filename>/etc/hotplug/usb</filename> and add a symlink
to usbtoken. Also create the directory
<filename>/var/run/usbtoken</filename> and set
permissions to 0755 (everyone can access that
directory):
<screen>
ln -s /path/to/opensc/sbin/usbtoken /etc/hotplug/usb/
mkdir /var/run/usbtoken
chmod 0755 /var/run/usbtoken
</screen>
</para>
</section>
<section>
<title>Security</title>
<para>
By default everyone can use the usbtokens. If you want
to limit this to a certain user:
<screen>
chown user /var/run/usbtoken/
chmod 0700 /var/run/usbtoken/
</screen>
Or if you want to limit this to a certain group:
<screen>
chgrp group /var/run/usbtoken/
chmod 0750 /var/run/usbtoken/
</screen>
</para>
</section>
<section>
<title>Debugging</title>
<para>
TODO: send me problem reports and I will add
advice here.
</para>
<para>
Edit src/usbtoken/Makefile and Makefile.in
and add "-DUSB_DEBUG" to CFLAGS. make clean,
make, make install. Now it will dump
all usb traffic to syslog. I should be able
to understand what is going wrong based
on that log file.
</para>
<para>
For development I use a special crafted
<filename>/sbin/hotplug</filename> shell script
that creates another script
<filename>/root/sim</filename> whis I invoke in
an xterm. That script spawns gdb so I can
debug the whole process. In gdb I usualy
set a breakpoint, and run the command with
<command>r usb</command>. My hotplug script:
<screen>
#!/bin/sh
if [ -n "$PRODUCT" ]
then
if [ "$ACTION" = "add" ]
then
export > /root/sim
echo "echo $*" >> /root/sim
echo gdb /home/aj/opensc/sbin/usbtoken >> /root/sim
fi
fi
exit 0
</screen>
</para>
</section>
<section>
<title>Porting</title>
<para>
To port usbtoken mainly <filename>usb.c</filename>
needs some changes. The core sequence for linux
is:
<screen><![CDATA[
#include <linux/usbdevice_fs.h>
...
struct usbdevfs_ctrltransfer ctrl;
int rc;
ctrl.requesttype = type;
ctrl.request = req;
ctrl.value = value;
ctrl.index = index;
ctrl.length = size;
ctrl.data = buf;
ctrl.timeout = 10000;
rc = ioctl(usbtoken.usbfd, USBDEVFS_CONTROL, &ctrl);
]]></screen>
rc now has the error (-1/errno/strerror) or the
number of bytes read/written on success.
Change it to suit your OS, or let me know
how to do it, and usb should work.
</para>
<para>
Usbtoken also needs an usb device filesystem
or some device it can open and use with I/O controls.
That should be available with every OS.
</para>
<para>
Finaly usbtoken depends to be called by some
hotplug mechanism. Under linux the kernel
executes <filename>/sbin/hotplug</filename>
everytime a device is added (or removed, but
I don't use that). If your OS has no such
service, you can write a daemon that
somehow finds out when a device is added
and start usbtoken with the required environment
settings.
</para>
<para>
Windows? Ugh. I have no idea about windows,
what we can do, how it works, etc. Volunteers
welcome.
</para>
</section>
</article>

View File

@ -6,4 +6,4 @@ EXTRA_DIST = Makefile.mak
# Order IS important
SUBDIRS = common include scconf scdl scldap scrandom libopensc pkcs15init pkcs11 \
tests tools openscd openssh scam pam sia signer usbtoken sslengines
tests tools openscd openssh scam pam sia signer sslengines

View File

@ -22,8 +22,7 @@ libopensc_la_SOURCES = \
\
emv.c \
\
ctbcs.c reader-ctapi.c reader-pcsc.c \
reader-openct.c reader-usbtoken.c \
ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c \
\
card-setcos.c card-miocos.c card-flex.c card-gpk.c \
card-etoken.c card-tcos.c card-emv.c card-default.c \

View File

@ -75,9 +75,6 @@ static const struct _sc_driver_entry internal_reader_drivers[] = {
#ifdef HAVE_OPENCT
{ "openct", (void *) sc_get_openct_driver, NULL },
#endif
#ifdef HAVE_USBTOKEN
{ "usbtoken", (void *) sc_get_usbtoken_driver, NULL },
#endif
#endif
{ NULL, NULL, NULL }
};

View File

@ -844,7 +844,6 @@ extern const char *sc_get_version(void);
extern const struct sc_reader_driver *sc_get_pcsc_driver(void);
extern const struct sc_reader_driver *sc_get_ctapi_driver(void);
extern const struct sc_reader_driver *sc_get_usbtoken_driver(void);
extern const struct sc_reader_driver *sc_get_openct_driver(void);
extern struct sc_card_driver *sc_get_default_driver(void);

View File

@ -1,351 +0,0 @@
/*
* reader-usbtoken.c: Reader driver for USBtoken
*
* Copyright (C) 2002 Andreas Jellinghaus <aj@dungeon.inka.de>
*/
#include "internal.h"
#ifdef HAVE_USBTOKEN
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* we will create that many usbtoken readers */
#define READERS 5
#define SRVSOCKET "/var/run/usbtoken/socket%d"
/* function declarations */
int usbtoken_reader_init(struct sc_context *ctx, void **priv_data);
int usbtoken_reader_finish(struct sc_context *ctx, void *priv_data);
int usbtoken_reader_release(struct sc_reader *reader);
int usbtoken_reader_detect_card_presence(struct sc_reader *reader,
struct sc_slot_info *slot);
int usbtoken_reader_connect(struct sc_reader *reader,
struct sc_slot_info *slot);
int usbtoken_reader_disconnect(struct sc_reader *reader,
struct sc_slot_info *slot, int action);
int usbtoken_reader_transmit(struct sc_reader *reader,
struct sc_slot_info *slot, const u8 * sendbuf,
size_t sendsize, u8 * recvbuf,
size_t * recvsize, int control);
int usbtoken_reader_lock(struct sc_reader *reader,
struct sc_slot_info *slot);
int usbtoken_reader_unlock(struct sc_reader *reader,
struct sc_slot_info *slot);
static struct sc_reader_operations usbtoken_ops;
static struct sc_reader_driver usbtoken_reader_driver = {
"USB Crypto Token Reader",
"usbtoken",
&usbtoken_ops
};
/* private data structures */
struct usbtoken_privslot {
struct sockaddr_un sa_un;
int slot, fd;
};
/* ok,lets start the real code */
int usbtoken_reader_init(struct sc_context *ctx, void **priv_data)
{
/* Called during sc_establish_context(), when the driver
* is loaded */
int i;
struct sc_reader *myreader;
struct usbtoken_privslot *myprivslot;
SC_FUNC_CALLED(ctx, 4);
for (i = 0; i < READERS; i++) {
myreader = malloc(sizeof(struct sc_reader));
bzero(myreader, sizeof(struct sc_reader));
myreader->driver = &usbtoken_reader_driver;
myreader->ops = &usbtoken_ops;
myreader->slot_count = 1;
myreader->name = strdup("USB Crypto Token %d");
snprintf(myreader->name, strlen(myreader->name),
myreader->name, i);
myprivslot = malloc(sizeof(struct usbtoken_privslot));
bzero(myprivslot, sizeof(struct usbtoken_privslot));
myreader->slot[0].drv_data = myprivslot;
myreader->slot[0].flags = SC_SLOT_CARD_PRESENT;
myprivslot->fd = -1;
myprivslot->sa_un.sun_family = AF_UNIX;
snprintf(myprivslot->sa_un.sun_path,
sizeof(myprivslot->sa_un.sun_path), SRVSOCKET, i);
if (_sc_add_reader(ctx, myreader) != 0) {
/* error */
free(myprivslot);
free(myreader->name);
free(myreader);
break;
}
}
return SC_NO_ERROR;
}
int usbtoken_reader_finish(struct sc_context *ctx, void *priv_data)
{
/* Called when the driver is being unloaded. finish() has to
* deallocate the private data and any resources. */
SC_FUNC_CALLED(ctx, 4);
return SC_NO_ERROR;
}
int usbtoken_reader_release(struct sc_reader *reader)
{
/* Called when releasing a reader. release() has to
* deallocate the private data. Other fields will be
* freed by OpenSC. */
struct usbtoken_privslot *myprivslot;
SC_FUNC_CALLED(reader->ctx, 4);
myprivslot = reader->slot[0].drv_data;
if (myprivslot) {
if (myprivslot->fd >= 0)
close(myprivslot->fd);
free(myprivslot);
}
return SC_NO_ERROR;
}
int usbtoken_reader_detect_card_presence(struct sc_reader *reader,
struct sc_slot_info *slot)
{
struct usbtoken_privslot *myprivslot;
struct stat statbuf;
int rc, newflags;
SC_FUNC_CALLED(reader->ctx, 4);
myprivslot = slot->drv_data;
newflags =
slot->flags & ~(SC_SLOT_CARD_PRESENT | SC_SLOT_CARD_CHANGED);
if (myprivslot->fd >= 0) {
struct pollfd pfd;
pfd.fd = myprivslot->fd;
pfd.events = 0;
rc = poll(&pfd, 1, 0);
if (pfd.revents & POLLHUP) { /* card removed, slot invalid */
newflags |= SC_SLOT_CARD_CHANGED;
usbtoken_reader_disconnect(reader, slot,
SC_DISCONNECT);
usbtoken_reader_connect(reader, slot);
}
}
rc = stat(myprivslot->sa_un.sun_path, &statbuf);
if (rc != -1)
newflags |= SC_SLOT_CARD_PRESENT;
if ((slot->flags & SC_SLOT_CARD_PRESENT) != newflags)
newflags |= SC_SLOT_CARD_CHANGED;
slot->flags = newflags;
return slot->flags;
}
int usbtoken_reader_unix_cmd(struct sc_reader *reader,
struct sc_slot_info *slot, u8 cmd)
{
struct usbtoken_privslot *myprivslot;
u8 msg;
int rc;
SC_FUNC_CALLED(reader->ctx, 4);
myprivslot = slot->drv_data;
assert(myprivslot->fd >= 0);
rc = write(myprivslot->fd, &cmd, sizeof(cmd));
if (rc != sizeof(cmd)) {
sc_error(reader->ctx,
"usbtoken_reader_unix_cmd write failed\n");
return SC_ERROR_READER;
}
rc = read(myprivslot->fd, &msg, sizeof(msg));
if (rc != 1 || msg != 0) {
sc_error(reader->ctx,
"usbtoken_reader_unix_cmd read failed\n");
return SC_ERROR_READER;
}
return SC_NO_ERROR;
}
int usbtoken_reader_connect(struct sc_reader *reader,
struct sc_slot_info *slot)
{
struct usbtoken_privslot *myprivslot;
int rc, len;
SC_FUNC_CALLED(reader->ctx, 4);
myprivslot = slot->drv_data;
rc = socket(AF_UNIX, SOCK_STREAM, 0);
if (rc < 0) {
sc_error(reader->ctx,
"usbtoken_reader_connect: socket() failed\n");
return SC_ERROR_READER;
}
myprivslot->fd = rc;
len = sizeof(myprivslot->sa_un.sun_family) +
strlen(myprivslot->sa_un.sun_path);
rc = connect(myprivslot->fd, (struct sockaddr *)
&(myprivslot->sa_un), len);
if (rc < 0) {
close(myprivslot->fd);
myprivslot->fd = -1;
sc_error(reader->ctx,
"usbtoken_reader_connect: connect(%s) failed\n",
myprivslot->sa_un.sun_path);
return SC_ERROR_CARD_NOT_PRESENT;
}
rc = read(myprivslot->fd, slot->atr, SC_MAX_ATR_SIZE);
if (rc == -1) {
sc_error(reader->ctx,
"usbtoken_reader_connect: read failed on %s\n",
myprivslot->sa_un.sun_path);
return SC_ERROR_READER;
}
if (rc == 0) {
sc_error(reader->ctx,
"usbtoken_reader_connect: read on %s recieved no data\n",
myprivslot->sa_un.sun_path);
return SC_ERROR_READER;
}
slot->atr_len = rc;
return SC_NO_ERROR;
}
int usbtoken_reader_disconnect(struct sc_reader *reader,
struct sc_slot_info *slot, int action)
{
struct usbtoken_privslot *myprivslot;
SC_FUNC_CALLED(reader->ctx, 4);
myprivslot = slot->drv_data;
if (myprivslot->fd >= 0) {
close(myprivslot->fd);
myprivslot->fd = -1;
}
return SC_NO_ERROR;
}
int usbtoken_reader_transmit(struct sc_reader *reader,
struct sc_slot_info *slot, const u8 * sendbuf,
size_t sendsize, u8 * recvbuf,
size_t * recvsize, int control)
{
struct usbtoken_privslot *myprivslot;
u8 buffer[1024];
int rc;
SC_FUNC_CALLED(reader->ctx, 4);
myprivslot = slot->drv_data;
assert(myprivslot->fd >= 0);
if (sendsize > 1023) {
sc_error(reader->ctx,
"usbtoken_reader_transmit sendsize %d too big\n",
sendsize);
return SC_ERROR_READER;
}
buffer[0] = 3;
memcpy(&buffer[1], sendbuf, sendsize);
rc = write(myprivslot->fd, buffer, sendsize + 1);
if (rc != sendsize + 1) {
sc_error(reader->ctx,
"usbtoken_reader_transmit write failed\n");
return SC_ERROR_READER;
}
rc = read(myprivslot->fd, buffer, sizeof(buffer));
if (rc == -1) {
sc_error(reader->ctx,
"usbtoken_reader_transmit read failed\n");
return SC_ERROR_READER;
}
if (rc == 0) {
sc_error(reader->ctx,
"usbtoken_reader_transmit recved no data\n");
return SC_ERROR_READER;
}
if (buffer[0] != 3) {
sc_error(reader->ctx,
"usbtoken_reader_transmit token failed\n");
return SC_ERROR_READER;
}
if (rc - 1 > *recvsize) {
sc_error(reader->ctx,
"usbtoken_reader_transmit recved too much (%d > %d)\n",
rc - 1, *recvsize);
return SC_ERROR_READER;
}
*recvsize = rc - 1;
memcpy(recvbuf, &buffer[1], rc - 1);
return SC_NO_ERROR;
}
int usbtoken_reader_lock(struct sc_reader *reader,
struct sc_slot_info *slot)
{
SC_FUNC_CALLED(reader->ctx, 4);
return usbtoken_reader_unix_cmd(reader, slot, 4);
}
int usbtoken_reader_unlock(struct sc_reader *reader,
struct sc_slot_info *slot)
{
SC_FUNC_CALLED(reader->ctx, 4);
return usbtoken_reader_unix_cmd(reader, slot, 5);
}
const struct sc_reader_driver *sc_get_usbtoken_driver(void)
{
usbtoken_ops.init = usbtoken_reader_init;
usbtoken_ops.finish = usbtoken_reader_finish;
usbtoken_ops.release = usbtoken_reader_release;
usbtoken_ops.detect_card_presence = usbtoken_reader_detect_card_presence;
usbtoken_ops.connect = usbtoken_reader_connect;
usbtoken_ops.disconnect = usbtoken_reader_disconnect;
usbtoken_ops.transmit = usbtoken_reader_transmit;
usbtoken_ops.lock = usbtoken_reader_lock;
usbtoken_ops.unlock = usbtoken_reader_unlock;
return &usbtoken_reader_driver;
}
#endif /* HAVE_USBTOKEN */

View File

@ -1,26 +0,0 @@
.deps
.libs
.#*#
.*.bak
.*.orig
.*.rej
.*~
#*#
*.bak
*.d
*.def
*.dll
*.exe
*.la
*.lib
*.lo
*.orig
*.pdb
*.rej
*.u
*~
Makefile
Makefile.in
core
gmon.out
usbtoken

View File

@ -1,12 +0,0 @@
usbtoken is no longer active developed.
Please use openct
http://www.opensc.org/files/
I will support usbtoken for a short while, and
fix any bugs reported. But most likely usbtoken
will be removed from opensc in 0.9.0. So the
sooner you migrate to openct the better.
Sorry for causing this inconvinience.
Regards, Andreas

View File

@ -1,12 +0,0 @@
# Process this file with automake to create Makefile.in
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = DEPRECATED
if HAVE_USBTOKEN
sbin_PROGRAMS = usbtoken
endif
usbtoken_SOURCES = atr.c eutron.c etoken.c ikey2k.c ikey3k.c main.c pid.c \
socket.c t1.c usb.c usbtoken.h
#usbtoken_CFLAGS = -DUSB_DEBUG

View File

@ -1,274 +0,0 @@
#include <stdint.h>
#include <syslog.h>
#include "usbtoken.h"
int is_atr_complete(uint8_t* buffer, int lr)
{
int hc, i, td, rc;
/* TS, T0 and checksum are always required */
if (lr < 3)
return USBTOKEN_INCOMPLETE;
if (buffer[0] != 0x3b) {
syslog(LOG_ERR,
"is_atr_complete fatal: atr not direct convention, TS %d",
buffer[0]);
return USBTOKEN_ERROR;
}
hc = buffer[1] & 0xf;
/* ok, first round, starting with byte 2, for T=0 */
i = 2;
td = buffer[1] >> 4;
while (td) {
if (td & 0x01)
i++; /* TAn */
if (td & 0x02)
i++; /* TBn */
if (td & 0x04)
i++; /* TCn */
if (td & 0x08) { /* TDn */
if (lr < i)
return USBTOKEN_INCOMPLETE;
td = buffer[i] >> 4;
i++;
} else {
td = 0;
}
}
if (lr < i + hc + 1)
return USBTOKEN_INCOMPLETE;
lr = i + hc + 1;
rc = 0;
for (i = 1; i < lr; i++) {
rc ^= buffer[i];
}
if (rc != 0) {
syslog(LOG_ERR, "is_atr_complete fatal: checksum invalid");
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
int parse_atr()
{
int hc, i, td, proto, rc;
if (usbtoken.atr == 0) {
syslog(LOG_ERR, "parse_atr fatal: no ATR received");
return USBTOKEN_ERROR;
}
if (usbtoken.atrlen < 1) {
syslog(LOG_ERR, "parse_atr fatal: TS missing");
return USBTOKEN_ERROR;
}
if (usbtoken.atr[0] != 0x3b) {
syslog(LOG_ERR,
"parse_atr fatal: atr not direct convention, TS %d",
usbtoken.atr[0]);
return USBTOKEN_ERROR;
}
if (usbtoken.atrlen < 2) {
syslog(LOG_ERR, "parse_atr fatal: T0 missing");
return USBTOKEN_ERROR;
}
hc = usbtoken.atr[1] & 0xf;
/* ok, first round, starting with byte 2, for T=0 */
i = 2;
proto = 0;
td = usbtoken.atr[1] >> 4;
if (td & 0x1) { /* TA1 */
/* timing stuff, i don't care */
i++;
}
if (td & 0x02) { /* TB1 */
/* vpp voltage, obsolete */
i++;
}
if (td & 0x04) { /* TC1 */
/* extra guard time, i don't care */
i++;
}
if (td & 0x08) { /* TD1 */
if (usbtoken.atrlen < i) {
syslog(LOG_ERR, "parse_atr fatal: TD1 missing");
return USBTOKEN_ERROR;
}
td = usbtoken.atr[i] >> 4;
proto = usbtoken.atr[i] & 0xf;
i++;
} else {
td = 0;
}
if (td & 0x01) { /* TA2 */
/* global interface character, for PTS */
i++;
}
if (td & 0x02) { /* TB2 */
/* vpp voltage */
i++;
}
if (td & 0x04) { /* TC2 */
/* work waiting time */
i++;
}
if (td & 0x08) { /* TD2 */
if (usbtoken.atrlen < i) {
syslog(LOG_ERR, "parse_atr fatal: TD2 missing");
return USBTOKEN_ERROR;
}
td = usbtoken.atr[i] >> 4;
proto = usbtoken.atr[i] & 0xf;
i++;
} else {
td = 0;
}
while (td) {
if (td & 0x01) { /* TAn */
/* ifsc */
if (usbtoken.atrlen < i) {
syslog(LOG_ERR,
"parse_atr fatal: TAn missing");
return USBTOKEN_ERROR;
}
if (proto == 1) {
usbtoken.ifsc = usbtoken.atr[i];
}
i++;
}
if (td & 0x02) { /* TBn */
/* character waiting time */
i++;
}
if (td & 0x04) { /* TCn */
/* lrc/crc */
if (usbtoken.atrlen < i) {
syslog(LOG_ERR,
"parse_atr fatal: TAn missing");
return USBTOKEN_ERROR;
}
if (proto == 1) {
usbtoken.rc = usbtoken.atr[i] & 0x1;
}
i++;
}
if (td & 0x08) { /* TDn */
if (usbtoken.atrlen < i) {
syslog(LOG_ERR,
"parse_atr fatal: TDn missing");
return USBTOKEN_ERROR;
}
td = usbtoken.atr[i] >> 4;
proto = usbtoken.atr[i] & 0xf;
i++;
} else {
td = 0;
}
}
if (usbtoken.atrlen != i + hc + 1) {
syslog(LOG_ERR,
"parse_atr fatal: length should be %d, is %d",
i + hc, usbtoken.atrlen);
return USBTOKEN_ERROR;
}
rc = 0;
for (i = 1; i < usbtoken.atrlen; i++) {
rc ^= usbtoken.atr[i];
}
if (rc != 0) {
syslog(LOG_ERR, "parse_atr fatal: checksum invalid");
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
int increase_ifsc()
{
uint8_t buf_send[256];
uint8_t buf_recv[256];
uint8_t max_ifsc;
int len_recv, rc;
int i;
max_ifsc = usbtoken.ifsc;
if (max_ifsc > usbtoken.drv.max_ifsc) {
max_ifsc = usbtoken.drv.max_ifsc;
}
usbtoken.ifsc = 0x20;
if (max_ifsc == 0x20) {
return USBTOKEN_OK;
};
buf_send[0] = 0x00;
buf_send[1] = 0xc1;
buf_send[2] = 0x01;
buf_send[3] = max_ifsc;
rc = 0;
for (i = 0; i < 4; i++) {
rc ^= buf_send[i];
}
buf_send[4] = rc;
len_recv = sizeof(buf_recv);
rc = usbtoken.drv.transmit(buf_send, 5, buf_recv, &len_recv);
if (rc != USBTOKEN_OK)
return rc;
if (len_recv < 5) {
syslog(LOG_ERR,
"increase_ifsc fatal: expected (at least) 5 byte answer, got %d",
len_recv);
return USBTOKEN_ERROR;
}
rc = 0;
for (i = 0; i < 4 + buf_recv[2]; i++) {
rc ^= buf_recv[i];
}
if (rc != 0) {
syslog(LOG_ERR, "increase_ifsc fatal: checksum mismatch");
return USBTOKEN_ERROR;
}
if (buf_recv[0] != 0x0 || buf_recv[1] != 0xe1
|| buf_recv[2] != 0x01) {
syslog(LOG_ERR,
"increase_ifsc fatal: did not get ifsc answer");
return USBTOKEN_ERROR;
}
usbtoken.ifsc = buf_recv[3];
return USBTOKEN_OK;
}

View File

@ -1,158 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "usbtoken.h"
int etoken_init();
int etoken_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv);
const struct token_drv etoken_drv = {
.init = etoken_init,
.transmit = etoken_transmit,
.max_ifsc = 32, /* higher ifsc causes etoken to crash */
.timeout = 10000,
.name = "Aladdin eToken PRO",
};
char *etoken_products[] = { "529/50c/100", "529/514/100", 0 };
int etoken_test(char *product)
{
char **p;
if (!product)
return USBTOKEN_ERROR;
for (p = etoken_products; *p; p++) {
if (strcmp(product, *p) == 0) {
usbtoken.drv = etoken_drv;
return USBTOKEN_OK;
}
}
return USBTOKEN_ERROR;
}
int etoken_init()
{
int rc, len;
uint8_t buffer[1024];
uint8_t cookie[] = { 0x00, 0x00, 0x01, 0x00, 0x88, 0x13 };
/* request atr */
rc = usb_control_xmit(0x40, 0x01, 0x0000, 0x0000, 0x0000, buffer);
/* receive atr */
rc = usb_control_xmit(0xc0, 0x81, 0x0000, 0x0000, 0x0023, buffer);
if ((rc == -1) || (rc == 0)) {
/* failed, we should get an atr */
syslog(LOG_ERR, "etoken fatal: no ATR received");
return USBTOKEN_ERROR;
}
len = buffer[0];
if (rc < len) {
/* failed, we need to get a whole atr */
syslog(LOG_ERR, "etoken fatal: wrong ATR");
return USBTOKEN_ERROR;
}
/* copy atr */
usbtoken.atr = malloc(len);
memcpy(usbtoken.atr, buffer + 1, len);
usbtoken.atrlen = len;
/* ask for something strange */
rc = usb_control_xmit(0x40, 0x03, 0x0000, 0x0000, 0x0000, buffer);
/* receive strange data */
rc = usb_control_xmit(0xc0, 0x83, 0x0000, 0x0000, 0x000d, buffer);
/* send something strange */
memcpy(buffer, cookie, sizeof(cookie));
rc = usb_control_xmit(0x40, 0x02, 0x0000, 0x0000, sizeof(cookie),
buffer);
if (rc != sizeof(cookie)) {
/* the whole cookie should have been send */
syslog(LOG_ERR, "etoken fatal: cookie not completly send: rc=%d", rc);
return USBTOKEN_ERROR;
}
/* get strange answer */
rc = usb_control_xmit(0xc0, 0x82, 0x0000, 0x0000, 0x0001, buffer);
if (rc != 1) {
/* we should have got one byte */
syslog(LOG_ERR, "etoken fatal: did not receive one byte response to cookie: rc=%d", rc);
return USBTOKEN_ERROR;
}
if (buffer[0] != 0) {
/* the answer should have bin 0x00 */
syslog(LOG_ERR, "etoken fatal: received one byte response to cookie but it is: %d!=0", buffer[0]);
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
int etoken_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv)
{
int rc;
uint8_t wtx_resp[] = { 0xe0, 0xc3, 0x01, 0x01, 0xc3 };
uint8_t wtx_send[] = { 0x00, 0x00, 0x01, 0x00, 0x10, 0x27 };
uint8_t wtx_recv[] = { 0x00 };
/* waiting time extension works without this,
* but the windows driver send a magic sequence first
* and asks for a magic answer, so we copied this */
if (len_send == sizeof(wtx_resp)
&& memcmp(buf_send, wtx_resp, sizeof(wtx_resp) == 0)) {
rc = usb_control_xmit(0x40, 0x02, 0x0000, 0x0000,
sizeof(wtx_send), wtx_send);
if (rc != sizeof(wtx_send)) {
syslog(LOG_ERR,
"etoken fatal: wtx special send'd wrong len %d",
rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc0, 0x82, 0x0000, 0x0000, 01,
buf_recv);
if (rc != sizeof(wtx_recv)) {
syslog(LOG_ERR,
"etoken fatal: wtx special recv'd wrong len %d",
rc);
return USBTOKEN_ERROR;
}
if (memcmp(buf_recv, wtx_recv, sizeof(wtx_recv) != 0)) {
syslog(LOG_ERR,
"etoken fatal: wtx special recv does not match");
return USBTOKEN_ERROR;
}
}
/* send via usb */
rc = usb_control_xmit(0x40, 0x06, 0x0000, 0x0000, len_send,
buf_send);
if (rc != len_send) {
syslog(LOG_ERR, "etoken fatal: received %d != %d",
rc, len_send);
return USBTOKEN_ERROR;
}
/* receive answer via usb */
rc = usb_control_xmit(0xc0, 0x86, 0x0000, 0x0000,
usbtoken.ifsc + 5, buf_recv);
if (rc == -1) {
syslog(LOG_ERR, "etoken fatal: receive answer rc %d", rc);
return USBTOKEN_ERROR;
}
*len_recv = rc;
return USBTOKEN_OK;
}

View File

@ -1,148 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include "usbtoken.h"
int eutron_init();
int eutron_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv);
const struct token_drv eutron_drv = {
.init = eutron_init,
.transmit = eutron_transmit,
.max_ifsc = 0x100,
.timeout = 2710,
.name = "Eutron CryptoIdentity",
};
char *eutron_products[] = { "73d/5/120", 0 };
int eutron_test(char *product)
{
char **p;
if (!product)
return USBTOKEN_ERROR;
for (p = eutron_products; *p; p++) {
if (strcmp(product, *p) == 0) {
usbtoken.drv = eutron_drv;
return USBTOKEN_OK;
}
}
return USBTOKEN_ERROR;
}
int eutron_init()
{
int rc, lr, c;
uint8_t buffer[1024];
uint8_t cookie[] = { 0xff, 0x11, 0x98, 0x76 };
rc = usb_control_xmit(0x41, 0xa3, 0x0000, 0x0000, 0x0000, buffer);
rc = usb_control_xmit(0x41, 0xa1, 0x0000, 0x0000, 0x0000, buffer);
rc = usb_control_xmit(0x41, 0xa2, 0x0000, 0x0000, 0x0000, buffer);
rc = usb_control_xmit(0x41, 0xa0, 0x0000, 0x0000, 0x0000, buffer);
rc = usb_control_xmit(0x41, 0x09, 0x0000, 0x0000, 0x0000, buffer);
lr = 0;
while (1) {
rc = usb_control_xmit(0xc1, 0x02, 0x0000, 0x0000, 0x0100,
&buffer[lr]);
if (rc == -1) {
syslog(LOG_ERR,
"eutron fatal: receive answer rc %d", rc);
return USBTOKEN_ERROR;
}
lr += rc;
rc = is_atr_complete(buffer, lr);
if (rc == USBTOKEN_OK)
break;
if (rc != USBTOKEN_INCOMPLETE)
return rc;
}
/* copy atr */
usbtoken.atr = malloc(lr);
memcpy(usbtoken.atr, buffer, lr);
usbtoken.atrlen = lr;
rc = usb_control_xmit(0x41, 0x01, 0x0000, 0x0000,
sizeof(cookie), cookie);
c = 0;
lr = 0;
while (1) {
rc = usb_control_xmit(0xc1, 0x02, 0x0000, 0x0000, 0x0100,
&buffer[lr]);
if (rc == -1) {
syslog(LOG_ERR,
"eutron fatal: receive answer rc %d", rc);
return USBTOKEN_ERROR;
}
lr += rc;
if (lr >= 4)
break;
c++;
if (c > 20) {
syslog(LOG_ERR, "eutron fatal: looping forever");
return USBTOKEN_ERROR;
}
}
rc = usb_control_xmit(0x41, 0x65, 0x98, 0x0000, 0x0000, buffer);
rc = usb_control_xmit(0x41, 0xa0, 0x0000, 0x0000, 0x0000, buffer);
return USBTOKEN_OK;
}
int eutron_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv)
{
int rc, lr, c;
rc = usb_control_xmit(0x42, 0x01, 0x0000, 0x0000, len_send,
buf_send);
if (rc != len_send) {
syslog(LOG_ERR, "eutron fatal: received %d != %d", rc,
len_send);
return USBTOKEN_ERROR;
}
lr = 0;
c = 0;
while (1) {
rc = usb_control_xmit(0xc1, 0x02, 0x0000, 0x0000, 0x0100,
&buf_recv[lr]);
syslog(LOG_DEBUG, "rc %d, lr %d, len %d",
rc, lr, buf_recv[2]);
if (rc == -1) {
syslog(LOG_ERR,
"eutron fatal: receive answer rc %d", rc);
return USBTOKEN_ERROR;
}
lr += rc;
if (lr >= 4 && lr >= buf_recv[2] + 4)
break;
c++;
if (c > 10000) {
syslog(LOG_ERR,
"eutron fatal: timeout after 100s");
return USBTOKEN_ERROR;
} else {
struct timespec x;
x.tv_sec = 0;
x.tv_nsec = 50000000;
nanosleep(&x, NULL);
}
}
*len_recv = lr;
return USBTOKEN_OK;
}

View File

@ -1,182 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "usbtoken.h"
int ikey2k_init();
int ikey2k_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv);
const struct token_drv ikey2k_drv = {
.init = ikey2k_init,
.transmit = ikey2k_transmit,
.max_ifsc = 0xb4, /* as used under windows */
.timeout = 10000,
.name = "Rainbow iKey 2000/2032",
};
char *ikey2k_products[] = { "4b9/1202/100", 0 };
int ikey2k_test(char *product)
{
char **p;
if (!product)
return USBTOKEN_ERROR;
for (p = ikey2k_products; *p; p++) {
if (strcmp(product, *p) == 0) {
usbtoken.drv = ikey2k_drv;
return USBTOKEN_OK;
}
}
return USBTOKEN_ERROR;
}
int ikey2k_init()
{
uint8_t buffer[1024];
uint8_t expect5[] = { 0x0d, 0x63, 0x00, 0x05, 0x2d, 0x2d, 0xc0,
0x80, 0x80, 0x60, 0x80, 0x01, 0x19
};
#ifdef MANUAL_IFSC
uint8_t expect17[] =
{ 0x00, 0xe1, 0x01, 0xb4, 0x54, 0x40, 0x98, 0xc1 };
#endif /* MANUAL_IFSC */
int rc;
rc = usb_control_xmit(0xc1, 0x00, 0x0000, 0x0000, 0x0040, buffer);
if (memcmp(buffer, expect5, sizeof(expect5)) != 0) {
syslog(LOG_ERR, "ikey2k fatal: ikey2k urb 5 bad match");
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x0000, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey2k fatal: urb 6 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0002, buffer);
if (rc != 1 || buffer[0] != 0) {
syslog(LOG_ERR,
"ikey2k fatal: urb 7 returned %d, first byte %hhx",
rc, buffer[0]);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x1901, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey2k fatal: urb 8 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0019, buffer);
if (rc != 25) {
syslog(LOG_ERR, "ikey2k fatal: urb 9 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x0000, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey2k fatal: urb 10 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0002, buffer);
if (rc != 1 || buffer[0] != 0) {
syslog(LOG_ERR,
"ikey2k fatal: urb 11 returned %d, first byte %hhx",
rc, buffer[0]);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x0000, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey2k fatal: urb 12 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0020, buffer);
if (rc != 1 || buffer[0] != 0) {
syslog(LOG_ERR,
"ikey2k fatal: urb 13 returned %d, first byte %hhx",
rc, buffer[0]);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x1901, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey2k fatal: urb 14 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0019, buffer);
if (rc != 25) {
syslog(LOG_ERR, "ikey2k fatal: urb 15 returned %d", rc);
return USBTOKEN_ERROR;
}
usbtoken.atr = malloc(rc);
if (!usbtoken.atr) {
syslog(LOG_ERR,
"fatal error: ikey2k could not malloc for atr");
return USBTOKEN_ERROR;
}
memcpy(usbtoken.atr, buffer, rc);
usbtoken.atrlen = rc;
#ifdef MANUAL_IFSC
buffer[0] = 0x74;
rc = usb_control_xmit(0x41, 0x17, 0xc100, 0xb401, 0x0001, buffer);
if (rc != 1) {
syslog(LOG_ERR, "ikey2k fatal: urb 16 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0008, buffer);
if (memcmp(buffer, expect17, sizeof(expect17)) != 0) {
syslog(LOG_ERR, "ikey2k fatal: urb 17 bad match");
return USBTOKEN_ERROR;
}
#endif /* MANUAL_IFSC */
return USBTOKEN_OK;
}
int ikey2k_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv)
{
int rc;
int value, index;
value = buf_send[1] << 8 | buf_send[0];
index = buf_send[3] << 8 | buf_send[2];
/* send via usb */
rc = usb_control_xmit(0x41, 0x17, value, index, len_send - 4,
&buf_send[4]);
if (rc != len_send - 4) {
syslog(LOG_ERR,
"ikey2k fatal: transfer sending failed rc %d len %d",
rc, len_send);
return USBTOKEN_ERROR;
}
/* receive answer via usb */
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, usbtoken.ifsc,
buf_recv);
if (rc == -1) {
syslog(LOG_ERR,
"ikey2k fatal: transfer receive failed rc %d", rc);
return USBTOKEN_ERROR;
}
*len_recv = rc;
return USBTOKEN_OK;
}

View File

@ -1,160 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "usbtoken.h"
int ikey3k_init();
int ikey3k_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv);
const struct token_drv ikey3k_drv = {
.init = ikey3k_init,
.transmit = ikey3k_transmit,
.max_ifsc = 0xb4, /* as used under windows */
.timeout = 10000,
.name = "Rainbow iKey 3000",
};
char *ikey3k_products[] = { "4b9/1300/100", 0 };
int ikey3k_test(char *product)
{
char **p;
if (!product)
return USBTOKEN_ERROR;
for (p = ikey3k_products; *p; p++) {
if (strcmp(product, *p) == 0) {
usbtoken.drv = ikey3k_drv;
return USBTOKEN_OK;
}
}
return USBTOKEN_ERROR;
}
int ikey3k_init()
{
uint8_t buffer[1024];
uint8_t expect5[] =
{ 0x0a, 0x61, 0x00, 0x07, 0x2d, 0x2d, 0xc0, 0x80, 0x80, 0x60 };
uint8_t expect11[] = { 0xff, 0x11, 0x11, 0xff };
#ifdef MANUAL_IFSC
uint8_t expect13[] =
{ 0x00, 0xe1, 0x01, 0xb4, 0x54, 0x40, 0x98, 0xc1 };
#endif /* MANUAL_IFSC */
int rc;
rc = usb_control_xmit(0xc1, 0x00, 0x0000, 0x0000, 0x0040, buffer);
if (memcmp(buffer, expect5, sizeof(expect5)) != 0) {
syslog(LOG_ERR, "ikey3k fatal: urb 5 bad match");
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x0000, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey3k fatal: urb 6 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0002, buffer);
if (rc != 1 || buffer[0] != 0) {
syslog(LOG_ERR,
"ikey3k fataiL: urb 7 returned %d, first byte %hhx",
rc, buffer[0]);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0x41, 0x16, 0x2005, 0x0000, 0x0000, buffer);
if (rc != 0) {
syslog(LOG_ERR, "ikey3k fatal: urb 8 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0020, buffer);
if (rc != 32) {
syslog(LOG_ERR, "ikey3k fatal: urb 9 returned %d", rc);
return USBTOKEN_ERROR;
}
if (rc < 1 || (rc < buffer[0])) {
syslog(LOG_ERR, "ikey3k fatal: atr incomplete (%d/%hhd)",
rc, buffer[0]);
return USBTOKEN_ERROR;
}
usbtoken.atr = malloc(buffer[0]);
if (!usbtoken.atr) {
syslog(LOG_ERR, "ikey3k fatal: could not malloc for atr");
return USBTOKEN_ERROR;
}
memcpy(usbtoken.atr, &buffer[1], buffer[0]);
usbtoken.atrlen = buffer[0];
buffer[0] = 0x74;
rc = usb_control_xmit(0x41, 0x16, 0x0002, 0x0000, 0x0001, buffer);
if (rc != 1) {
syslog(LOG_ERR, "ikey3k urb 10 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0004, buffer);
if (memcmp(buffer, expect11, sizeof(expect11)) != 0) {
syslog(LOG_ERR, "ikey3k fatal: urb 11 bad match");
return USBTOKEN_ERROR;
}
#ifdef MANUAL_IFSC
buffer[0] = 0x74;
rc = usb_control_xmit(0x41, 0x17, 0xc100, 0xb401, 0x0001, buffer);
if (rc != 1) {
syslog(LOG_ERR, "ikey3k fatal: urb 12 returned %d", rc);
return USBTOKEN_ERROR;
}
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, 0x0008, buffer);
if (memcmp(buffer, expect13, sizeof(expect13)) != 0) {
syslog(LOG_ERR, "ikey3k fatal: urb 13 bad match");
return USBTOKEN_ERROR;
}
#endif /* MANUAL_IFSC */
return USBTOKEN_OK;
}
int ikey3k_transmit(uint8_t * buf_send, int len_send,
uint8_t * buf_recv, int *len_recv)
{
int rc;
int value, index;
value = buf_send[1] << 8 | buf_send[0];
index = buf_send[3] << 8 | buf_send[2];
/* send via usb */
rc = usb_control_xmit(0x41, 0x17, value, index, len_send - 4,
&buf_send[4]);
if (rc != len_send - 4) {
syslog(LOG_ERR,
"ikey3k fatal: tranfer sending failed rc %d len %d",
rc, len_send);
return USBTOKEN_ERROR;
}
/* receive answer via usb */
rc = usb_control_xmit(0xc1, 0x01, 0x0000, 0x0000, usbtoken.ifsc,
buf_recv);
if (rc == -1) {
syslog(LOG_ERR,
"ikey3k fatal: tranfer receive failed rc %d", rc);
return USBTOKEN_ERROR;
}
*len_recv = rc;
return USBTOKEN_OK;
}

View File

@ -1,152 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <unistd.h>
#include "usbtoken.h"
struct token usbtoken;
int main(int argc, char** argv)
{
char *action, *device, *product;
int rc;
int pid;
/* action should be "add".
* we will notice removes ourself. */
action = getenv("ACTION");
if (!action || strcmp(action, "add") != 0) {
return 0;
}
if ((argc > 1) && (strcmp(argv[1], "nofork") == 0)) {
fprintf(stderr,"not forking to easy debugging");
} else {
pid = fork();
if (pid == -1) {
fprintf(stderr, "fork failed: %s (%d)", strerror(errno), errno);
return 1;
}
if (pid) {
/* parent process */
return 0;
}
/* child: continue */
}
openlog(SYSLOG_NAME, LOG_CONS | LOG_PERROR | LOG_PID, LOG_KERN);
product = getenv("PRODUCT");
{
if (eutron_test(product) == USBTOKEN_OK ||
etoken_test(product) == USBTOKEN_OK ||
ikey2k_test(product) == USBTOKEN_OK ||
ikey3k_test(product) == USBTOKEN_OK) {
syslog(LOG_DEBUG,
"found product : %s", usbtoken.drv.name);
} else {
syslog(LOG_ERR, "unknown product %s", product);
return 1;
}
}
/* DEVICE should hold the path to the device file we need. */
device = getenv("DEVICE");
if (!device) {
syslog(LOG_ERR, "device not found, aborting!\n");
return 1;
}
/* the device might not be there right now. wait one second */
sleep(1);
usbtoken.usbfd = open(device, O_EXCL | O_RDWR);
if (usbtoken.usbfd == -1) {
syslog(LOG_ERR, "open device %s failed: %s, aborting!\n",
device, strerror(errno));
return 1;
}
if (usbtoken.drv.init() != USBTOKEN_OK) {
return 1;
}
if (parse_atr() != USBTOKEN_OK) {
return 1;
}
if (increase_ifsc() != USBTOKEN_OK) {
return 1;
}
if (pid_init() != USBTOKEN_OK) {
syslog(LOG_DEBUG,
"all slots in use. increased MAXTOKEN, recompile");
return 1;
}
if (socket_init() != USBTOKEN_OK) {
return 1;
}
while (1) {
struct pollfd pollfd[3];
pollfd[0].fd = usbtoken.usbfd;
pollfd[0].events = POLLIN | POLLPRI | POLLOUT;
pollfd[1].fd = usbtoken.unixfd;
pollfd[1].events = POLLIN | POLLPRI;
if (usbtoken.connfd) {
pollfd[2].fd = usbtoken.connfd;
pollfd[2].events = POLLIN | POLLPRI;
rc = poll(pollfd, 3, 1000);
} else {
rc = poll(pollfd, 2, 1000);
}
if (rc == -1 && errno == EINTR)
continue;
if (rc == -1) {
syslog(LOG_ERR,
"poll returned error, aborting: %s!\n",
strerror(errno));
return 1;
}
if (pollfd[0].revents) {
if ((pollfd[0].revents & 0x18) == 0x18) {
syslog(LOG_DEBUG,
"device removed. exiting.\n");
return 0;
}
/* handle usb stuff */
}
if (usbtoken.connfd && (pollfd[2].revents & POLLHUP)) {
socket_hangup();
continue;
}
if (pollfd[1].revents) {
/* handle unix socket (listen()ing) */
socket_accept();
continue;
}
if (usbtoken.connfd && pollfd[2].revents) {
if (socket_xmit() != USBTOKEN_OK)
return 1;
}
/* ignore other poll results */
}
return 0;
}

View File

@ -1,50 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include <unistd.h>
#include "usbtoken.h"
char *pidfile;
void pid_exit()
{
if (pidfile) {
unlink(pidfile);
free(pidfile);
}
}
int pid_init()
{
int i;
for (i = 0; i < MAXTOKEN - 1; i++) {
char buffer[1024];
int fd;
snprintf(buffer, sizeof(buffer), PIDFILE, i);
fd = open(buffer, O_CREAT|O_EXCL|O_WRONLY, 0644);
if (fd == -1) {
continue;
}
pidfile = strdup(buffer);
snprintf(buffer, sizeof(buffer), "%d\n", getpid());
write(fd, buffer, strlen(buffer));
close(fd);
usbtoken.slot = i;
atexit(pid_exit);
return USBTOKEN_OK;
}
return USBTOKEN_ERROR;
}

View File

@ -1,184 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "usbtoken.h"
#define MSG_ERROR -1
#define MSG_OK 0
#define MSG_TRANSMIT 3
#define MSG_LOCK 4
#define MSG_UNLOCK 5
char *socketpath;
void socket_exit()
{
if (socketpath) {
unlink(socketpath);
free(socketpath);
}
}
int socket_init()
{
int rc;
struct sockaddr_un ua;
int ualen;
mode_t oldmask;
usbtoken.unixfd = socket(PF_UNIX, SOCK_STREAM, 0);
if (usbtoken.unixfd == -1) {
syslog(LOG_ERR,
"socket_init: socket failed: %s, aborting!\n",
strerror(errno));
return USBTOKEN_ERROR;
}
bzero(&ua, sizeof(ua));
ua.sun_family = AF_UNIX;
snprintf(ua.sun_path, sizeof(ua.sun_path), SOCKET, usbtoken.slot);
socketpath = strdup(ua.sun_path);
unlink(socketpath);
atexit(socket_exit);
ualen = sizeof(ua.sun_family) + strlen(ua.sun_path);
oldmask = umask(0);
rc = bind(usbtoken.unixfd, (struct sockaddr *) &ua, ualen);
umask(oldmask);
/* some error */
if (rc == -1) {
syslog(LOG_DEBUG,
"socket_init: bind on %s failed: %s(%d), aborting!\n",
ua.sun_path, strerror(errno), errno);
return USBTOKEN_ERROR;
}
rc = listen(usbtoken.unixfd, 1);
if (rc == -1) {
syslog(LOG_DEBUG,
"socket_init: listen failed: %s(%d), aborting!\n",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
rc = fcntl(usbtoken.unixfd, F_SETFL, O_NONBLOCK);
if (rc == -1) {
syslog(LOG_DEBUG,
"socket_init: fcntl failed: %s(%d), aborting!\n",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
int socket_accept()
{
int rc;
rc = accept(usbtoken.unixfd, NULL, 0);
if (rc == -1) {
syslog(LOG_ERR, "socket_accept: accept failed: %s(%d)",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
if (usbtoken.connfd) {
close(rc);
return USBTOKEN_OK;
}
usbtoken.connfd = rc;
rc = write(usbtoken.connfd, usbtoken.atr, usbtoken.atrlen);
if (rc == -1) {
syslog(LOG_ERR,
"socket_accept: write failed: %s(%d)",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
int socket_hangup()
{
int rc;
rc = close(usbtoken.connfd);
usbtoken.connfd = 0;
return USBTOKEN_OK;
}
int unix_write(uint8_t msg, int size)
{
int rc;
rc = write(usbtoken.connfd, &msg, size);
if (rc == -1) {
syslog(LOG_ERR, "unix_write: write failed: %s(%d)",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
int socket_xmit()
{
uint8_t buf_read[1024];
int rc, len_read;
rc = read(usbtoken.connfd, buf_read, sizeof(buf_read));
if (rc == -1) {
syslog(LOG_ERR, "socket_xmit: read failed: %s(%d)",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
len_read = rc;
if (buf_read[0] == MSG_TRANSMIT) {
uint8_t buf_write[1024];
int len_write;
len_write = sizeof(buf_write) - 1;
rc = t1_process(&buf_read[1], len_read - 1,
&buf_write[1], &len_write);
if (rc != USBTOKEN_OK)
return rc;
buf_write[0] = MSG_TRANSMIT;
rc = write(usbtoken.connfd, buf_write, len_write + 1);
if (rc == -1) {
syslog(LOG_ERR,
"socket_xmit: write failed: %s(%d)",
strerror(errno), errno);
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}
/* all other commands are single byte commands */
if (len_read != 1) {
syslog(LOG_ERR, "socket_xmit: recv returned: %d",
len_read);
return USBTOKEN_ERROR;
}
if (buf_read[0] == MSG_LOCK) {
return unix_write(MSG_OK, 1);
}
if (buf_read[0] == MSG_UNLOCK) {
return unix_write(MSG_OK, 1);
}
return unix_write(MSG_ERROR, 1);
}

View File

@ -1,545 +0,0 @@
/* imported from SCEZ chipcard library - T=1 routines
* This is probably the first full free/open source T=1 implementation.
* Copyright Matthias Bruestle 1999-2002
* For licensing, see the file LICENCE
*
* Copyright 2003 Andreas Jellinghaus <aj@dungeon.inka.de>
* Copyright 2003 Kevin Stefanik <kstef@mtppi.org>
*/
#include <string.h>
#include <syslog.h>
#include "usbtoken.h"
#define T1_CHECKSUM_LRC 0x00
#define T1_CHECKSUM_CRC 0x01
#define T1_MAX_BLKLEN 3+256+2+2
/* direction */
#define T1_TO_CARD 0x00
#define T1_FROM_CARD 0x01
#define PCB(x) (x[1])
static inline int is_t1_iblock(uint8_t pcb) { return (pcb & 0x80) == 0x00; }
static inline int is_t1_rblock(uint8_t pcb) { return (pcb & 0xC0) == 0x80; }
static inline int is_t1_sblock(uint8_t pcb) { return (pcb & 0xC0) == 0xC0; }
static inline int is_t1_other_error(uint8_t pcb) {return (pcb & 0xef) == 0x82;}
/* we send resync requests and get a response */
static inline int is_t1_resync_req(uint8_t pcb) { return pcb == 0xc0; }
static inline int is_t1_resync_res(uint8_t pcb) { return pcb == 0xe0; }
/* the card can request these */
static inline int is_t1_ifs_req(uint8_t pcb) { return pcb == 0xc1; }
static inline int is_t1_abort_req(uint8_t pcb) { return pcb == 0xc2; }
static inline int is_t1_wtx_req(uint8_t pcb) { return pcb == 0xc3; }
#define T1_PCB_IBLOCK 0x00
#define T1_PCB_RBLOCK 0x80
#define T1_PCB_SBLOCK 0xC0
#define T1_PCB_MASK 0xC0
/* S-Block parameter */
#define T1_S_RESYNCH 0x00
#define T1_S_IFS 0x01
#define T1_S_ABORT 0x02
#define T1_S_WTX 0x03
#define T1_S_REQUEST 0x00
#define T1_S_RESPONSE 0x20
/* R-Block parameter */
#define T1_R_OK 0x00
#define T1_R_EDC_ERROR 0x01
#define T1_R_OTHER_ERROR 0x02
/* ISO STD 3309 */
/* From: medin@catbyte.b30.ingr.com (Dave Medin)
* Subject: CCITT checksums
* Newsgroups: sci.electronics
* Date: Mon, 7 Dec 1992 17:33:39 GMT
*/
/* Correct Table? */
static unsigned short crctab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
/* Returns LRC of data */
uint8_t calculate_lrc(const uint8_t * data, int datalen)
{
uint8_t lrc = 0x00;
int i;
for (i = 0; i < datalen; i++)
lrc ^= data[i];
return lrc;
}
/* Calculates CRC of data */
void calculate_crc(const uint8_t * data, int datalen, uint8_t * crc)
{
int i;
unsigned short tmpcrc = 0xFFFF;
for (i = 0; i < datalen; i++)
tmpcrc =
((tmpcrc >> 8) & 0xFF) ^ crctab[(tmpcrc ^ *data++) &
0xFF];
crc[0] = (tmpcrc >> 8) & 0xFF;
crc[1] = tmpcrc & 0xFF;
}
/* Appends RC */
int append_rc(uint8_t * data, int *datalen)
{
if (usbtoken.rc == T1_CHECKSUM_LRC) {
data[*datalen] = calculate_lrc(data, *datalen);
*datalen += 1;
return USBTOKEN_OK;
} else if (usbtoken.rc == T1_CHECKSUM_CRC) {
calculate_crc(data, *datalen, data + *datalen);
*datalen += 2;
return USBTOKEN_OK;
}
return USBTOKEN_ERROR;
}
/* Checks RC. */
int check_rc(const uint8_t * data, int datalen)
{
uint8_t rc[2];
uint8_t cmp[2];
if (usbtoken.rc == T1_CHECKSUM_LRC) {
/* Check LEN. */
if ((data[2] + 3 + 1) > datalen)
return 0;
rc[1] = data[data[2] + 3];
cmp[1] = calculate_lrc(data, data[2] + 3);
return (rc[1] == cmp[1]);
} else if (usbtoken.rc == T1_CHECKSUM_CRC) {
/* Check LEN. */
if ((data[2] + 3 + 2) > datalen)
return 0;
calculate_crc(data, data[2] + 3, cmp);
return (memcmp(data + data[2] + 3, cmp, 2) == 0);
}
return 0;
}
/* Builds S-Block */
int build_neg_block(int type, int dir, int param, uint8_t * block,
int *len)
{
block[0] = usbtoken.nad;
switch (type) {
case T1_S_RESYNCH:
block[1] = T1_PCB_SBLOCK | dir | T1_S_RESYNCH;
block[2] = 0x00;
*len = 3;
break;
case T1_S_IFS:
block[1] = T1_PCB_SBLOCK | dir | T1_S_IFS;
block[2] = 0x01;
block[3] = (uint8_t) param;
*len = 4;
break;
case T1_S_ABORT:
block[1] = T1_PCB_SBLOCK | dir | T1_S_ABORT;
block[2] = 0x00;
*len = 3;
break;
case T1_S_WTX:
block[1] = T1_PCB_SBLOCK | dir | T1_S_WTX;
block[2] = 0x01;
block[3] = (uint8_t) param;
*len = 4;
break;
default:
return (USBTOKEN_ERROR);
}
return append_rc(block, len);
}
/* Builds R-Block */
int build_retry_block(int type, uint8_t * block, int *len)
{
block[0] = usbtoken.nad;
block[2] = 0x00;
switch (type) {
case T1_R_OK:
if (usbtoken.nr)
block[1] = 0x90;
else
block[1] = 0x80;
break;
case T1_R_EDC_ERROR:
if (usbtoken.nr)
block[1] = 0x91;
else
block[1] = 0x81;
break;
case T1_R_OTHER_ERROR:
if (usbtoken.nr)
block[1] = 0x92;
else
block[1] = 0x82;
break;
default:
return USBTOKEN_ERROR;
}
*len = 3;
return append_rc(block, len);
}
/* Builds I-Block */
int build_data_block(int more, const uint8_t * data, int datalen,
uint8_t * block, int *blocklen)
{
block[0] = usbtoken.nad;
block[1] = 0x00;
if (usbtoken.ns)
block[1] |= 0x40;
if (more)
block[1] |= 0x20;
if (datalen > usbtoken.ifsc)
return USBTOKEN_ERROR;
block[2] = (uint8_t) datalen;
memcpy(block + 3, data, datalen);
*blocklen = datalen + 3;
return append_rc(block, blocklen);
}
/* Returns N(R) or N(S) from R/I-Block. */
int get_sequence(const uint8_t * block)
{
if (is_t1_rblock(PCB(block))) {
return (block[1] & 0x10) ? 0x01 : 0x00;
}
if (is_t1_iblock(PCB(block))) {
return (block[1] & 0x40) ? 0x01 : 0x00;
}
return 0;
}
int t1_process(uint8_t * apdu_cmd, int apdu_cmdlen,
uint8_t * apdu_rsp, int *apdu_rsplen)
{
int sendptr; /* Points to begining of unsent data. */
int sendlen;
uint8_t block[T1_MAX_BLKLEN];
uint8_t rblock[T1_MAX_BLKLEN];
int blocklen;
int rblocklen;
uint8_t rsp[256 + 3];
uint8_t rsplen;
int more; /* More data to send. */
int direction; /* It's ICCs turn to send I-Blocks. */
int rc;
int errcntr = 0;
int rerrcntr = 0;
start:
*apdu_rsplen = 0;
direction = T1_TO_CARD;
rsplen = 0;
sendptr = 0;
sendlen = apdu_cmdlen;
if (sendlen > usbtoken.ifsc) {
sendlen = usbtoken.ifsc;
more = 1;
} else {
more = 0;
}
rc = build_data_block(more, apdu_cmd, sendlen, block, &blocklen);
if (rc) {
goto cleanup;
}
sendptr += sendlen;
while (1) {
rblocklen = sizeof(block);
rc = usbtoken.drv.transmit(block, blocklen, rblock,
&rblocklen);
/* communication error ? abort. */
if (rc != USBTOKEN_OK) {
goto cleanup;
}
if (is_t1_other_error(PCB(rblock))) {
/* other error, request resync */
rc = build_neg_block(T1_S_RESYNCH, T1_S_REQUEST,
rblock[3], block,
&blocklen);
if (rc) {
goto cleanup;
}
continue;
}
/* length or rc error ? try three times. */
if (!check_rc(rblock, rblocklen)) {
errcntr++;
if (errcntr > 3) {
rc = USBTOKEN_ERROR;
goto cleanup;
}
rc = build_retry_block(T1_R_EDC_ERROR,
block, &blocklen);
if (rc) {
goto cleanup;
}
continue;
}
/* ah, no length or rc error. reset counter. */
errcntr = 0;
/* shall we resend the last block ? try thee times. */
if (is_t1_rblock(PCB(rblock))) {
rerrcntr++;
if (rerrcntr > 3) {
rc = USBTOKEN_ERROR;
goto cleanup;
}
if (direction == T1_FROM_CARD) {
/* Card is sending I-Blocks, so send R-Block. */
rc = build_retry_block(T1_R_OK,
block, &blocklen);
if (rc) {
goto cleanup;
}
continue;
}
if (get_sequence(rblock) == usbtoken.ns) {
/* N(R) is old N(S),
* so resend I-Block. */
sendptr -= sendlen;
} else {
/* N(R) is next N(S),
* so make next I-Block and send it. */
/* Check if data available. */
if (more == 0) {
/* last block was with pcb: bit6=0
* (no more following blocks)
* so there is no more data to send.
* if the card is waiting for
* additional data, then it is wrong.
* comm error! */
rc = USBTOKEN_ERROR;
goto cleanup;
}
/* Change N(S) to new value. */
usbtoken.ns ^= 1;
/* Make next I-Block. */
/* Clear error counter */
rerrcntr = 0;
}
sendlen = apdu_cmdlen - sendptr;
if (sendlen > usbtoken.ifsc) {
sendlen = usbtoken.ifsc;
} else {
more = 0;
}
rc = build_data_block(more, apdu_cmd +
sendptr, sendlen, block,
&blocklen);
if (rc) {
goto cleanup;
}
sendptr += sendlen;
continue;
}
/* we shall not resend the last block ? reset error counter. */
rerrcntr = 0;
/* I-Block */
if (is_t1_iblock(PCB(rblock))) {
if (direction == T1_TO_CARD) {
/* Change N(S) to new value. */
usbtoken.ns ^= 1;
}
direction = T1_FROM_CARD;
if (get_sequence(rblock) != usbtoken.nr) {
/* Card is sending wrong I-Block, so send R-Block. */
rc = build_retry_block(T1_R_OTHER_ERROR,
block, &blocklen);
if (rc) {
goto cleanup;
}
continue;
}
/* Copy data. */
if (rblock[2] > (256 + 2 - rsplen)) {
rc = USBTOKEN_ERROR;
goto cleanup;
}
memcpy(rsp + rsplen, rblock + 3, rblock[2]);
rsplen += rblock[2];
if ((rblock[1] >> 5) & 1) {
/* More data available. */
/* Change N(R) to new value. */
usbtoken.nr ^= 1;
/* more fragments to come */
rc = build_retry_block(T1_R_OK,
block, &blocklen);
if (rc) {
goto cleanup;
}
continue;
}
/* Last block. */
/* Change N(R) to new value. */
usbtoken.nr ^= 1;
if (rsplen < 2) {
rc = USBTOKEN_ERROR;
goto cleanup;
}
memcpy(apdu_rsp, rsp, rsplen);
*apdu_rsplen = rsplen;
rc = USBTOKEN_OK;
goto cleanup;
}
if (is_t1_resync_res(PCB(rblock))) {
/* resync: start from scratch */
goto start;
}
if (is_t1_wtx_req(PCB(rblock))) {
/* request waiting time extension */
rc = build_neg_block(T1_S_WTX,
T1_S_RESPONSE, rblock[3],
block, &blocklen);
if (rc) {
goto cleanup;
}
continue;
}
if (is_t1_ifs_req(PCB(rblock))) {
/* the card want's to set a different ifsc. */
/* acknowledge */
rc = build_neg_block(T1_S_IFS,
T1_S_RESPONSE, rblock[3],
block, &blocklen);
if (rc) {
goto cleanup;
}
usbtoken.ifsc = rblock[3];
continue;
}
if (is_t1_abort_req(PCB(rblock))) {
/* S-Block ABORT Request */
rc = USBTOKEN_ERROR;
goto cleanup;
}
syslog(LOG_ERR, "t1 fatal: unknown pcb %d",PCB(rblock));
rc = USBTOKEN_ERROR;
goto cleanup;
}
cleanup:
memset(block, 0, sizeof(block));
memset(rblock, 0, sizeof(rblock));
memset(rsp, 0, sizeof(rsp));
return rc;
}

View File

@ -1,91 +0,0 @@
#include <errno.h>
#include <linux/usbdevice_fs.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include "usbtoken.h"
#ifdef USB_DEBUG
void debug_hexdump(char *msg, uint8_t * buf, int size)
{
char line[1024];
const char hex[16] =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
int n, i, max;
i = max = 0;
while (i < size) {
snprintf(line, sizeof(line), "%s %04x:", msg, i);
n = strlen(line);
max = i + 16;
if (max > size) {
max = size;
}
while (i < max) {
line[n++] = ' ';
line[n++] = hex[buf[i] / 16];
line[n++] = hex[buf[i] % 16];
i++;
}
line[n++] = 0;
syslog(LOG_DEBUG, line);
}
}
#endif /* USB_DEBUG */
int usb_control_xmit(int type, int req, int value, int index, int size,
uint8_t * buf)
{
struct usbdevfs_ctrltransfer ctrl;
int rc;
ctrl.requesttype = type;
ctrl.request = req;
ctrl.value = value;
ctrl.index = index;
ctrl.length = size;
ctrl.data = buf;
ctrl.timeout = usbtoken.drv.timeout;
#ifdef USB_DEBUG
syslog(LOG_DEBUG,
"usb xmit %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n",
type, req, value & 0xff, value >> 8, index & 0xff,
index >> 8, size & 0xff, size >> 8);
if (!(type & 0x80))
debug_hexdump("Sending:", buf, size);
#endif /* USB_DEBUG */
rc = ioctl(usbtoken.usbfd, USBDEVFS_CONTROL, &ctrl);
if (rc == -1) {
syslog(LOG_ERR, "usb ioctl control transfer failed:%s\n",
strerror(errno));
}
#ifdef USB_DEBUG
if (type & 0x80)
debug_hexdump("Received:", buf, rc);
#endif /* USB_DEBUG */
return rc;
}
int usb_reset()
{
int rc;
rc = ioctl(usbtoken.usbfd, USBDEVFS_RESET, NULL);
if (rc == -1) {
syslog(LOG_ERR, "usb ioctl reset failed:%s\n",
strerror(errno));
return USBTOKEN_ERROR;
}
return USBTOKEN_OK;
}

View File

@ -1,73 +0,0 @@
#ifndef _USBTOKEN_H
#define _USBTOKEN_H
#include <stdint.h>
#define SYSLOG_NAME "usbtoken"
#define PIDFILE "/var/run/usbtoken%d.pid"
#define SOCKET "/var/run/usbtoken/socket%d"
#define UMASK 0000 /* used while creating the socket */
#define MAXTOKEN 10
#define USBTOKEN_OK 0
#define USBTOKEN_ERROR 1
#define USBTOKEN_INCOMPLETE 2
struct token_drv {
int (*init) ();
int (*transmit) (uint8_t * send, int send_len, uint8_t * recv,
int *recv_len);
int max_ifsc;
int timeout;
char *name;
};
struct token {
struct token_drv drv;
int unixfd;
int connfd;
int usbfd;
int usbvendor;
int usbproduct;
int slot;
int ifsc;
int rc; /* redundancy check */
int nad; /* nad byte */
int nr; /* next r block (0|1) */
int ns; /* next s block (0|1) */
uint8_t *atr;
int atrlen;
};
extern struct token usbtoken;
int etoken_test(char *product);
int eutron_test(char *product);
int ikey2k_test(char *product);
int ikey3k_test(char *product);
/* atr.c */
int parse_atr();
int increase_ifsc();
int is_atr_complete(uint8_t * buffer, int lr);
/* pid.c */
void pid_exit();
int pid_init();
/* socket.c */
int socket_init();
int socket_accept();
int socket_hangup();
int socket_xmit();
/* t1.c */
int t1_process(uint8_t * apdu_cmd, int apdu_cmdlen,
uint8_t * apdu_rsp, int *apdu_rsplen);
/* usb.c */
void debug_hexdump(char *msg, uint8_t * buf, int size);
int usb_control_xmit(int type, int req, int value, int index,
int size, uint8_t * buf);
int usb_reset();
#endif