yubikey-ksm-1.14/ 0000755 0001750 0001750 00000000000 12216316720 012024 5 ustar jas jas yubikey-ksm-1.14/ykksm-db.sql 0000644 0001750 0001750 00000000737 12216316720 014275 0 ustar jas jas create table yubikeys (
-- identities:
serialnr int not null,
publicname varchar(16) unique not null,
-- timestamps:
created varchar(24) not null,
-- the data:
internalname varchar(12) not null,
aeskey varchar(32) not null,
lockcode varchar(12) not null,
-- key creator, typically pgp key id of key generator
creator varchar(8) not null,
-- various flags:
active boolean default true,
hardware boolean default true,
primary key (publicname)
);
yubikey-ksm-1.14/NEWS 0000644 0001750 0001750 00000004413 12216316720 012525 0 ustar jas jas * Version 1.14 (released 2013-09-18)
* Add Oracle support via OCI.
* The README is included in the tarball now.
* Version 1.13 (released 2013-04-17)
* Updated release procedure, project moved from Google Code to GitHub.
* Version 1.12 (released 2013-02-05)
* Added COPYING file.
* Version 1.11 (released 2013-01-31)
* Added missing manprefix to Makefile.
* Version 1.10 (released 2013-01-31)
* Changed location of files to /usr/share/yubikey-ksm, etc.
* Changed location of configuration files to /etc/yubico/ksm/.
* Fixed bug causing scripts reading the database to fail if
the config file exists but is not readable by the current user.
* Version 1.9 (released 2013-01-23)
* Renamed hex2bin to yubi_hex2bin.
Issue #1 reported by Dain Nilsson, see:
https://github.com/Yubico/yubikey-ksm/issues/1
* Version 1.8 (released 2013-01-21)
* Added ChangeLog to releases.
* Updated documentation for building/installing.
* Version 1.7 (released 2012-12-21)
* Replaced usage of 'mcrypt_ecb' as it is deprecated.
Issue #5 reported by Gyula Szabó, see:
http://code.google.com/p/yubikey-ksm/issues/detail?id=5>.
* Read database config from /etc/yubico/ksm/config-db files,
as generated by dbconfig.
* Version 1.6 (released 2012-12-18)
* ykksm-gen-keys supports the PSKC YubiKey profile.
* ykksm-checksum sorts by serial number first.
* Removed .pl extension from scripts.
* Added man pages.
* Removed ykksm-upgrade.
* Version 1.5 (released 2010-09-14)
* Brown paper bag release to update NEWS and Makefile before release.
* Version 1.4 (released 2010-09-14)
* Don't use PDO rowCount, it is not portable.
Issue #2 reported by arte42.ripe, see:
http://code.google.com/p/yubikey-ksm/issues/detail?id=2>.
* Fixed perl warning in ykksm-gen-keys.
Issue #3 reported by toddejohnson, see:
http://code.google.com/p/yubikey-ksm/issues/detail?id=3>.
* Improve documentation.
* Version 1.3 (released 2010-03-16)
* Added ykksm-checksum tool.
* Version 1.2 (released 2009-12-15)
* Documentation and installation experience substantially improved.
* Version 1.1 (released 2009-12-02)
* Use PHP PDO instead of hard coding use of MySQL database interface.
* Version 1.0 (released 2009-11-19)
* Initial release.
yubikey-ksm-1.14/ykksm-gen-keys.1 0000644 0001750 0001750 00000001617 12216316720 014771 0 ustar jas jas .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH YKKSM-GEN-KEYS "1" "September 2013" "ykksm-gen-keys 1" "User Commands"
.SH NAME
ykksm-gen-keys \- Tool to generate keys on the YKKSM-KEYPROV format.
.SH SYNOPSIS
.B ykksm-gen-keys
[\fI--verbose\fR] [\fI--help\fR] [\fI--urandom\fR] [\fI--progflags PROGFLAGS\fR] [\fI--pskc\fR] \fISTART \fR[\fIEND\fR]
.SH DESCRIPTION
Tool to generate keys on the YKKSM\-KEYPROV format.
.PP
START: Decimal start point.
.PP
END: Decimal end point, if absent START is used as END.
.TP
\fB\-\-urandom\fR:
Use /dev/urandom instead of /dev/random as entropy source.
.HP
\fB\-\-progflags\fR PROGFLAGS: Add a final personalization configuration string.
.HP
\fB\-\-pskc\fR: Output keys on the YubiKey PSKC format.
.PP
Usage example:
.IP
\&./ykksm\-gen\-keys \fB\-\-urandom\fR 1 10 |
.IP
gpg \fB\-a\fR \fB\-\-sign\fR \fB\-\-encrypt\fR \fB\-r\fR 1D2F473E > keys.txt
yubikey-ksm-1.14/doc/ 0000755 0001750 0001750 00000000000 12216316720 012571 5 ustar jas jas yubikey-ksm-1.14/doc/ServerHardening.wiki 0000644 0001750 0001750 00000021740 12216316720 016550 0 ustar jas jas == Server Hardening ==
While the defaults should be secure, there are some simple
administrative actions that will increase your overall security. None
of these steps are required, but we encourage you to read this
document to see if the enhancements are relevant for your environment.
=== Tighten PHP configuration ===
Tighten the security of the PHP installation by creating a file
/etc/php5/conf.d/harden.ini with the following content:
user@host:~$ sudo sh -c 'cat > /etc/php5/conf.d/harden.ini'
display_errors = Off
log_errors = On
user@host:~$
=== Tighten Apache configuration ===
Tighten the security of the Apache installation by making sure
directory listings are disabled globally. Edit
/etc/apache2/conf.d/security and make sure the following is
uncommented:
AllowOverride None
Order Deny,Allow
Deny from all
=== Time synchronization ===
For logging and (on the validation server) time-stamping it is
important to have synchronized clocks. Install ntp.
user@host:~$ sudo apt-get install ntp
...
=== Firewall ===
There is no reason why the KSM needs to listen to incoming requests
from the entire Internet, and restricting access to the intended
YK-VAL servers are recommended.
user@ksm:~$ sudo sh -c 'cat > /etc/network/if-pre-up.d/iptables'
#!/bin/sh
# IPv4 firewall:
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -i eth0 -s 1.2.3.4 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -i eth0 -s 2.3.4.5 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -i eth0 -s 2.3.4.5 --dport 443 -j ACCEPT
# IPv6 firewall:
ip6tables -F
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
ip6tables -A INPUT -i lo -p all -j ACCEPT
ip6tables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 -s 2000:1:2::3 --dport 22 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 -s 2000:2:3::4 --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 -s 2000:2:3::4 --dport 443 -j ACCEPT
user@ksm:~$ chmod +x /etc/network/if-pre-up.d/iptables
user@ksm:~$
Replace 1.2.3.4 (for IPv4) and 2000:1:2::3 (for IPv6) with the address
of the host you want to be able to login from via SSH, and replace
2.3.4.5 (for IPv4) and 2000:2:3::4 (for IPv6) with the address of the
YK-VAL that will be accessing this YK-KSM. Add more lines for each
validation server and SSH host.
For a validation server, you may want to allow HTTP(S) requests from
anyone, but not anything else.
user@val:~$ sudo sh -c 'cat > /etc/network/if-pre-up.d/iptables'
#!/bin/sh
# IPv4 firewall
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -i eth0 -s 1.2.3.4 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 443 -j ACCEPT
# IPv6 firewall:
ip6tables -F
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
ip6tables -A INPUT -i lo -p all -j ACCEPT
ip6tables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 -s 2000:1:2::3 --dport 22 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 --dport 443 -j ACCEPT
user@ksm:~$ chmod +x /etc/network/if-pre-up.d/iptables
user@ksm:~$
Again, replace 1.2.3.4 (for IPv4) and 2000:1:2::3 (for IPv6) with the
address of the host you want to be able to login from via SSH.
If you want to allow SSH and HTTP(S) from everywhere, but nothing
else, try this:
user@val:~$ sudo sh -c 'cat > /etc/network/if-pre-up.d/iptables'
#!/bin/sh
# IPv4 firewall
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 443 -j ACCEPT
# IPv6 firewall:
ip6tables -F
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
ip6tables -A INPUT -i lo -p all -j ACCEPT
ip6tables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 --dport 22 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp -i eth0 --dport 443 -j ACCEPT
user@ksm:~$ chmod +x /etc/network/if-pre-up.d/iptables
user@val:~$
=== Database encryption ===
The database contains sensitive information. If someone is able to
access your machine physically, they may shut it off and steal it with
the goal of reading out the sensitive information. By encrypting the
disk, you can prevent this. Note that this does not protect against
an attacker who has physical access to your server and sufficient time
to read out the data from the already running system.
Full disk encryption will give you the highest protection, but
requires that you can enter the disk encryption password on each
power-up. This can be unpractical when your hosting environment is
remote.
Partial disk encryption allows the operating system to start up, and
enable you to login to the machine remotely to enter the disk
encryption password. This is less secure than full disk encryption,
because an attacker could physically disconnect your machine, modify
the operating system to send a copy of the password to the attacker,
but may be sufficient if you keep good track of when your machine is
not working properly.
To use partial disk encryption for the database content, we suggest
you install the operating system as normal but create another file
system on an encrypted volume.
If you need swap space, be sure to only put the swap on the encrypted
volume too. Make sure that the database does not start up
automatically on boot, and also make sure that the system does not
attempt to mount your encrypted partition automatically.
Setup:
user@ksm:~$ sudo apt-get install loop-aes-utils loop-aes-modules-2.6-amd64
...
user@ksm:~$ sudo rmmod loop && sudo modprobe loop
user@ksm:~$ sudo dd if=/dev/zero of=/root/ksm.img bs=1k count=1M
...
user@ksm:~$ sudo losetup -e AES128 /dev/loop0 /root/ksm.img
Password:
user@ksm:~$ sudo mkfs.ext2 -q /dev/loop0
user@ksm:~$ sudo mkdir /ksm
user@ksm:~$ sudo mount /dev/loop0 /ksm
user@ksm:~$ sudo /etc/init.d/postgresql-8.3 stop
...
user@ksm:~$ sudo update-rc.d -f postgresql-8.3 remove
user@ksm:~$ sudo mv /var/lib/postgresql /ksm
user@ksm:~$ sudo ln -s /ksm/postgresql /var/lib/postgresql
user@ksm:~$ sudo sh -c 'cat > /usr/local/sbin/ykksm-start'
#!/bin/sh
set -e
set -x
losetup -e AES128 /dev/loop0 /root/ksm.img
fsck /dev/loop0
mount /dev/loop0 /ksm/
/etc/init.d/postgresql-8.3 start
user@ksm:~$ sudo sh -c 'cat > /usr/local/sbin/ykksm-stop'
#!/bin/sh
set -e
set -x
/etc/init.d/postgresql-8.3 stop
umount /ksm
losetup -d /dev/loop0
user@ksm:~$ sudo chmod +x /usr/local/sbin/ykksm-{start,stop}
Slightly adapted for MySQL:
user@ksm:~$ sudo apt-get install loop-aes-utils loop-aes-modules-2.6-686
...
user@ksm:~$ sudo rmmod loop && sudo modprobe loop
user@ksm:~$ sudo dd if=/dev/zero of=/root/ksm.img bs=1k count=1M
...
user@ksm:~$ sudo losetup -e AES128 /dev/loop0 /root/ksm.img
Password:
user@ksm:~$ sudo mkfs.ext2 -q /dev/loop0
user@ksm:~$ sudo mkdir /ksm
user@ksm:~$ sudo mount /dev/loop0 /ksm
user@ksm:~$ sudo /etc/init.d/mysql stop
user@ksm:~$ sudo update-rc.d -f mysql remove
user@ksm:~$ sudo mv /var/lib/mysql /ksm
user@ksm:~$ sudo ln -s /ksm/mysql /var/lib/mysql
user@ksm:~$ sudo sh -c 'cat > /usr/local/sbin/ykksm-start'
#!/bin/sh
set -e
set -x
losetup -e AES128 /dev/loop0 /root/ksm.img
fsck /dev/loop0
mount /dev/loop0 /ksm/
/etc/init.d/mysql start
user@ksm:~$ sudo sh -c 'cat > /usr/local/sbin/ykksm-stop'
#!/bin/sh
set -e
set -x
/etc/init.d/mysql stop
umount /ksm
losetup -d /dev/loop0
user@ksm:~$ sudo chmod +x /usr/local/sbin/ykksm-{start,stop}
Then in the future, to start the YK-KSM, you will need to login to the
machine and issue the command 'sudo ykksm-start' and enter the disk
encryption password.
Again, make sure that you don't use any unencrypted swap.
=== Intrusion detection ===
To make some attacks discussed in the previous section harder, make
sure that your system has a hardware intrusion detection system and
that your software is notified when it is triggered. When the
intrusion detection is triggered, you should stop the database and
unmount the encrypted volume and send out a signal to your
administrators.
yubikey-ksm-1.14/doc/GenerateKSMKey.wiki 0000644 0001750 0001750 00000005672 12216316720 016246 0 ustar jas jas == Generate KSM Key ==
Import of key material to an YK-KSM is typically always done via the
OpenPGP encrypted/signed KeyProvisioningFormat format. This setup
assumes that each YK-KSM system has a private key.
Below is a walk-through of a typical key generation session for a host
called 'crater'. As you can see at the end, it generated a key with a
key id of '8B88A11B'.
After this step you may want to generate AES keys for your YubiKeys,
see [[GenerateKeys]], and then import them to your KSM, see
[[ImportKeysToKSM]].
user@crater:~$ gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) DSA and Elgamal (default)
(2) DSA (sign only)
(5) RSA (sign only)
Your selection? 1
DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter) "
Real name: YK-KSM crater Import Key
Email address:
Comment:
You selected this USER-ID:
"YK-KSM crater Import Key"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
.+++++++++++++++++++++++++..+++++.+++++++++++++++++++++++++...+++++++++++++++.++++++++++.++++++++++++++++++++++++++++++++++++++++.++++++++++>++++++++++......++++++++++..++++++++++++++++++++..++++++++++++++++++++++++++++++++++++++++....+++++.+++++...+++++.++++++++++.+++++++++++++++.+++++..+++++.++++++++++.+++++++++++++++..+++++>++++++++++>+++++.................................>+++++..............+++++^^^
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
gpg: key 8B88A11B marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub 1024D/8B88A11B 2009-12-14
Key fingerprint = 9B18 20A2 F02E 3C3B 84E3 44F5 AE72 7967 8B88 A11B
uid YK-KSM crater Import Key
sub 2048g/140A17F1 2009-12-14
user@crater:~$
yubikey-ksm-1.14/doc/DesignGoals.wiki 0000644 0001750 0001750 00000000435 12216316720 015657 0 ustar jas jas == YK-KSM Design Goals ==
The YK-KSM component was designed for these objectives:
* Have AES key storage be separate from the validation server
* Allow distribution of AES keys to multiple servers for load-balancing and high-availability
* The code must be short and easy to audit
yubikey-ksm-1.14/doc/Installation.wiki 0000644 0001750 0001750 00000020765 12216316720 016131 0 ustar jas jas == Installation and configuration of Yubikey KSM ==
The Yubikey KSM module is responsible for storing AES keys and
providing two interfaces:
* Decrypting an OTP
* Adding new AES keys
It is intentionally not possible to extract the AES keys or to make
modifications to the database content, see [[DesignGoals]].
The installation procedure documented below applies to any Unix-like
environment, although it was written for Debian GNU/Linux version 5.0
(aka "lenny").
Since version 1.1 of the YK-KSM, any database supported by the PHP PDO
interface is supported by the YK-KSM. To give concrete examples, we
will here explain how to set it up using MySQL or PostgreSQL. Note
that you only need to install either MySQL or PostgreSQL (or any other
supported database), not both!
=== Step 1: YK-KSM Installation ===
First you should download and install the latest YK-KSM release:
user@ksm:~$ sudo apt-get install wget make help2man
...
user@ksm:~$ wget http://yubico.github.com/yubikey-ksm/releases/yubikey-ksm-1.8.tgz
...
user@ksm:~$ tar xfz yubikey-ksm-1.8.tgz
user@ksm:~$ cd yubikey-ksm-1.8
user@ksm:~/yubikey-ksm-1.8$ sudo make install
...
user@ksm:~/yubikey-ksm-1.8$
Alternatively, you may also check out YK-KSM from its source code repository. For example:
user@ksm:~$ sudo apt-get install git make help2man
...
user@ksm:~$ git clone git://github.com/Yubico/yubikey-ksm.git
...
user@ksm:~$ cd yubikey-ksm
user@ksm:~/yubikey-ksm$ sudo make install
...
user@ksm:~/yubikey-ksm$
The rest of this documentation will assume you have installed the
YK-KSM with 'make install'.
=== Step 2: Install web server and PHP ===
You will need to install a web server with PHP5 and the PHP mcrypt
interface:
user@ksm:~$ sudo apt-get install apache2 php5 php5-mcrypt
Any web server with PHP support should work.
=== Step 3A: MySQL Installation ===
Install the required packages:
user@ksm:~$ sudo apt-get install mysql-server php5-mysql libdbd-mysql-perl
...
user@ksm:~$
The installation asks you for a MySQL "root" password, and I recommend
to specify one.
To avoid having to specify a password when using the 'mysql' tool
interactively, you can store the password in ~/.my.cnf, see
/usr/share/doc/mysql-server-5.0/README.Debian.gz. For example:
user@ksm:~$ cat > .my.cnf
[client]
user = root
password = YOURPASSWORD
user@ksm:~$
First create the database and the tables as follows:
user@ksm:~$ echo 'create database ykksm' | mysql
user@ksm:~$ mysql ykksm < /usr/share/doc/ykksm/ykksm-db.sql
user@ksm:~$
You should also create database users for the decrypt and import
interfaces, normally called 'ykksmreader' and 'ykksmimporter':
user@ksm:~$ mysql --silent ykksm
mysql> CREATE USER 'ykksmreader';
mysql> GRANT SELECT ON ykksm.yubikeys TO 'ykksmreader'@'localhost';
mysql> SET PASSWORD FOR 'ykksmreader'@'localhost' = PASSWORD('yourpassword');
mysql> CREATE USER 'ykksmimporter';
mysql> GRANT INSERT ON ykksm.yubikeys TO 'ykksmimporter'@'localhost';
mysql> SET PASSWORD FOR 'ykksmimporter'@'localhost' = PASSWORD('otherpassword');
mysql> FLUSH PRIVILEGES;
mysql> \q
user@ksm:~$
== Step 3B: PostgreSQL Installation ==
Install some packages:
user@ksm:~$ sudo apt-get install postgresql php5-pgsql libdbd-pg-perl
...
user@ksm:~$
The database needs to be initialized as follows:
user@ksm:~$ sudo su postgres
postgres@ksm:~$ createdb ykksm
postgres@ksm:~$ psql ykksm < /usr/share/doc/ykksm/ykksm-db.sql
postgres@ksm:~$
You also need to create a user for the decrypt interface, normally
called 'ykksmreader':
postgres@ksm:~$ psql ykksm -q
ykksm=# CREATE USER ykksmreader PASSWORD 'yourpassword';
ykksm=# GRANT SELECT ON yubikeys TO ykksmreader;
ykksm=# CREATE USER ykksmimporter PASSWORD 'otherpassword';
ykksm=# GRANT INSERT ON yubikeys TO ykksmimporter;
ykksm=# \q
postgres@ksm:~$
During installation and debugging it may be useful to watch the
database log entries:
user@ksm:~$ sudo tail -F /var/log/postgresql/postgresql-*-main.log &
== Step 4: Include path configuration ==
Set the include path by creating a file /etc/php5/conf.d/ykksm.ini
with the following content:
user@ksm:~$ sudo sh -c 'cat > /etc/php5/conf.d/ykksm.ini'
include_path = "/etc/yubico/ksm:/usr/share/ykksm"
user@ksm:~$ sudo /etc/init.d/apache2 restart
user@ksm:~$
The paths are the default, if you installed the YK-KSM in some other
place you need to modify the paths.
== Step 5: Logging ==
The PHP interface uses syslog for logging of incoming requests. The
facility is set in ykksm-config.php but defaults the LOG_LOCAL0. To
place these messages in a separate file, you can add the following to
/etc/syslog.conf, or if you use rsyslog, create a file
/etc/rsyslog.d/ykksm.conf with this content:
user@ksm:~$ sudo sh -c 'cat > /etc/rsyslog.d/ykksm.conf'
local0.* -/var/log/ykksm.log
user@ksm:~$ sudo /etc/init.d/rsyslog restart
...
user@ksm:~$
The '-' before the filename avoids syncing the file after each write,
which is recommended for performance.
The log file can grow large quickly, so it is a good idea to setup
rotation of log files. Here is an example that rotates the log file
weekly. Create a file /etc/logrotate.d/ykksm like this:
user@ksm:~$ sudo sh -c 'cat > /etc/logrotate.d/ykksm'
/var/log/ykksm.log {
weekly
missingok
rotate 9999
notifempty
postrotate
invoke-rc.d rsyslog reload > /dev/null
endscript
}
user@ksm:~$
=== Step 5.1: Fix default log (optional) ===
Unfortunately, most default syslog configuration, including the
syslog.conf configuration file on Debian, will also log all entries to
/var/log/syslog and/or /var/log/messages.
I am not aware of any way to avoid this without modifying these other
rules. To avoid YK-KSM log entries in these other files, you must
modify the default rules. For example, edit the following lines of
/etc/rsyslog.conf (or /etc/syslog.conf if you don't use rsyslog):
*.*;auth,authpriv.none -/var/log/syslog
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none -/var/log/messages
Change them into:
*.*;auth,authpriv.none,local0.none -/var/log/syslog
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
local0.none;\
mail,news.none -/var/log/messages
== Step 6: Decrypt OTP Interface ==
The interface to decrypt OTPs is implemented using a PHP script. You
can place the script under any URL, but we recommend serving it as
http://ykksm.example.org/wsapi/decrypt. The simplest way is to use
the 'symlink' rule in our makefile:
user@ksm:~$ sudo make -f /usr/share/doc/ykksm/ykksm.mk symlink
install -d /var/www/wsapi
ln -sf /usr/share/ykksm/.htaccess /var/www/wsapi/.htaccess
ln -sf /usr/share/ykksm/ykksm-decrypt.php /var/www/wsapi/decrypt.php
user@ksm:~$
You may also run the commands manually.
== Step 7: YK-KSM Configuration ==
You need to edit the ykksm-config.php script. An example file is
included in YK-KSM as 'ykksm-config.php'. It is normally installed as
/etc/yubico/ksm/ykksm-config.php:
user@ksm:~$ sudo cat /etc/yubico/ksm/ykksm-config.php
user@ksm:~$
Be careful about the user permissions and ownership so that unrelated
users on the system cannot read the database password.
Typically you only need to modify the database password, and possibly
the database definition in $db_dsn. Example DSN for a MySQL setup:
$db_dsn = "mysql:dbname=ykksm;host=127.0.0.1";
An example DSN for a PostgreSQL setup:
$db_dsn = "pgsql:dbname=ykksm;host=127.0.0.1";
=== The End ===
You now have a YK-KSM up and running. You can test the service by
requesting a URL. Using wget, for example:
user@ksm:~$ sudo apt-get install wget
user@ksm:~$ wget -q -O - 'http://localhost/wsapi/decrypt?otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh'
ERR Unknown yubikey
user@ksm:~$
You will need to import keys into the database for the decrypt
function to do anything useful. See [[ServerHardening]] on how to
improve security of your system. Likely next steps are
[[GenerateKSMKey]], [[GenerateKeys]] and/or [[ImportKeysToKSM]].
yubikey-ksm-1.14/doc/GenerateKeys.wiki 0000644 0001750 0001750 00000005563 12216316720 016055 0 ustar jas jas == Generate Keys ==
To generate some AES keys for your !YubiKeys served via your YK-KSM,
you use the 'ykksm-gen-keys' tool. The tool is useful for generating
large sets of test keys, for performance testing of the database and
web interface. It can also be used to produce keying material that
are intended to used for programming real keys.
As you should never store encryption keys in plaintext, you typically
use the tool by piping it directly to GnuPG. So the first step will
always be to create a OpenPGP key for your KSM host, see
[[GenerateKSMKey]]. Below we will both sign the data from and encrypt
it to the same key id '8B88A11B'. Here is how you would generate 5
keys for test purposes:
user@ksm:~$ ykksm-gen-keys --urandom 1 5 | gpg -a --encrypt -r 8B88A11B -s > keys.txt
user@ksm:~$
Note the flag --urandom will cause the tool to use /dev/urandom rather
than /dev/random, which speed things up but is considered by some to
have weaker security.
After this step you may want to import the keys into your KSM, see
[[ImportKeysToKSM]].
In production, you may want to separate the key generation facility
into a separate machine with a separate OpenPGP key.
To display the test keys above, you can decrypt them using GnuPG:
user@ksm:~$ gpg < keys.txt
You need a passphrase to unlock the secret key for
user: "YK-KSM crater Import Key"
2048-bit ELG-E key, ID 140A17F1, created 2009-12-14 (main key ID 8B88A11B)
gpg: encrypted with 2048-bit ELG-E key, ID 140A17F1, created 2009-12-14
"YK-KSM crater Import Key"
# ykksm 1
# serialnr,identity,internaluid,aeskey,lockpw,created,accessed[,progflags]
1,cccccccccccb,d74fbdf6a890,82211e0854e7369e83d941f24761a84e,881ae7bee927,2009-12-14T16:40:57,
2,cccccccccccd,7a5ad1886b70,3091a8048524ab8407ae816457d764e5,8e5ab609e346,2009-12-14T16:40:57,
3,ccccccccccce,981abbbeafb8,91be4bfd2f40e24ebd39386868aa9619,037b6f6ae73c,2009-12-14T16:40:57,
4,cccccccccccf,c1f33c17f77b,a2389839d7b80bfe4c80258184aff4ce,abf92cbbdab3,2009-12-14T16:40:57,
5,cccccccccccg,c55773192393,7387b5f6bede83f64a9cd75b2023826a,d70c937bbbff,2009-12-14T16:40:57,
gpg: Signature made Mon 14 Dec 2009 04:40:57 PM CET using DSA key ID 8B88A11B
gpg: Good signature from "YK-KSM crater Import Key"
user@ksm:~$
The format is documented in the KeyProvisioningFormat wiki page.
To generate many small files each containing just one key, you can use
a small wrapper like this:
#!/bin/sh
set -e
start=$1
stop=$2
key=$3
urandom=$4
if test -z "$start" || test -z "$stop" || test -z "$key"; then
echo "Usage: run-gen-keys START STOP KEY [--urandom]"
echo ""
echo "Example usage:"
echo " run-gen-keys 4711 11147 A1296239 --urandom"
echo ""
exit 0
fi
cur=$start
while test $cur -le $stop; do
ykksm-gen-keys $urandom $cur | gpg -a --sign --encrypt -r $key > $cur.asc
cur=`expr $cur + 1`
done
yubikey-ksm-1.14/doc/DecryptionProtocol.wiki 0000644 0001750 0001750 00000001611 12216316720 017317 0 ustar jas jas == Yubikey KSM Decryption Protocol ==
The protocol for asking the Yubikey Key Storage Module to decrypt an
OTP is to request a HTTP resource as follows:
http://ykksm.example.com/wsapi/decrypt/?otp=dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh
On success, the response will follow this format:
^OK .*
For example:
OK counter=000f low=c541 high=a7 use=04
The content of the various fields are as follows:
* '''counter''': 16-bit hex integer, counting upwards on each powerup&touch
* '''low''': 16-bit hex integer, low part of time-stamp of OTP
* '''high''': 8-bit hex integer, high part of time-stamp of OTP
* '''use''': 8-bit hex integer, counting upwards on each touch
On soft errors, the response will follow this format:
^ERR .*
For example:
ERR Invalid OTP format
The data matching .* will be a english error message in one line.
Any other kind of response means a hard error occured.
yubikey-ksm-1.14/doc/ImportKeysToKSM.wiki 0000644 0001750 0001750 00000007656 12216316720 016460 0 ustar jas jas == Import Keys To Yubikey KSM ==
To import keys into the YK-KSM database from text files in the
encrypted/signed KeyProvisioningFormat format, you can use the tool
'ykksm-import'. The tool reads the data on standard input, and will
import the data to the database. On any error, execution is aborted,
so be careful about partial imports leaving the database in an
intermediate state.
The tool requires that your system has a GnuPG private key, read
[[GenerateKSMKey]] on how to generate it.
For example, to import the file generated by the [[GenerateKeys]]
document:
user@ksm:~$ ykksm-import --verbose --database 'DBI:Pg:dbname=ykksm;host=127.0.0.1' --db-user ykksmimporter --db-passwd otherpassword < ~/keys.txt
You need a passphrase to unlock the secret key for
user: "YK-KSM crater Import Key"
2048-bit ELG-E key, ID 140A17F1, created 2009-12-14 (main key ID 8B88A11B)
Verification output:
[GNUPG:] ENC_TO 8C73EAF1140A17F1 16 0
[GNUPG:] USERID_HINT 8C73EAF1140A17F1 YK-KSM crater Import Key
[GNUPG:] NEED_PASSPHRASE 8C73EAF1140A17F1 AE7279678B88A11B 16 0
[GNUPG:] GOOD_PASSPHRASE
gpg: encrypted with 2048-bit ELG-E key, ID 140A17F1, created 2009-12-14
"YK-KSM crater Import Key"
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] PLAINTEXT 62 1260805257
gpg: Signature made Mon 14 Dec 2009 04:40:57 PM CET using DSA key ID 8B88A11B
[GNUPG:] SIG_ID YGplk8qkUkb75lY0aurb/iS1Oog 2009-12-14 1260805257
[GNUPG:] GOODSIG AE7279678B88A11B YK-KSM crater Import Key
gpg: Good signature from "YK-KSM crater Import Key"
[GNUPG:] VALIDSIG 9B1820A2F02E3C3B84E344F5AE7279678B88A11B 2009-12-14 1260805257 0 4 0 17 2 00 9B1820A2F02E3C3B84E344F5AE7279678B88A11B
[GNUPG:] TRUST_ULTIMATE
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION
encrypted to: 8C73EAF1140A17F1
signed by: 8B88A11B
You need a passphrase to unlock the secret key for
user: "YK-KSM crater Import Key"
2048-bit ELG-E key, ID 140A17F1, created 2009-12-14 (main key ID 8B88A11B)
line: 1,cccccccccccb,d74fbdf6a890,82211e0854e7369e83d941f24761a84e,881ae7bee927,2009-12-14T16:40:57,
serialnr 1 publicName cccccccccccb internalName d74fbdf6a890 aesKey 82211e0854e7369e83d941f24761a84e lockCode 881ae7bee927 created 2009-12-14T16:40:57 accessed eol
line: 2,cccccccccccd,7a5ad1886b70,3091a8048524ab8407ae816457d764e5,8e5ab609e346,2009-12-14T16:40:57,
serialnr 2 publicName cccccccccccd internalName 7a5ad1886b70 aesKey 3091a8048524ab8407ae816457d764e5 lockCode 8e5ab609e346 created 2009-12-14T16:40:57 accessed eol
line: 3,ccccccccccce,981abbbeafb8,91be4bfd2f40e24ebd39386868aa9619,037b6f6ae73c,2009-12-14T16:40:57,
serialnr 3 publicName ccccccccccce internalName 981abbbeafb8 aesKey 91be4bfd2f40e24ebd39386868aa9619 lockCode 037b6f6ae73c created 2009-12-14T16:40:57 accessed eol
line: 4,cccccccccccf,c1f33c17f77b,a2389839d7b80bfe4c80258184aff4ce,abf92cbbdab3,2009-12-14T16:40:57,
serialnr 4 publicName cccccccccccf internalName c1f33c17f77b aesKey a2389839d7b80bfe4c80258184aff4ce lockCode abf92cbbdab3 created 2009-12-14T16:40:57 accessed eol
line: 5,cccccccccccg,c55773192393,7387b5f6bede83f64a9cd75b2023826a,d70c937bbbff,2009-12-14T16:40:57,
serialnr 5 publicName cccccccccccg internalName c55773192393 aesKey 7387b5f6bede83f64a9cd75b2023826a lockCode d70c937bbbff created 2009-12-14T16:40:57 accessed eol
user@ksm:~$
When importing large data sets it is recommended to avoid the
--verbose flag to reduce noise.
To test the import, you can attempt to decrypt an (invalid) OTP for
one of the AES keys. Like this:
user@ksm:~$ curl 'http://localhost/wsapi/decrypt?otp=cccccccccccdvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv'
ERR Corrupt OTP
user@ksm:~$
In the system log file /var/log/ykksm.log you should get this error:
Dec 14 17:20:08 crater ykksm[12693]: UID error: cccccccccccdvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv a515841f249c5f4bb8e9007ab0f7ac2b: a515841f249c vs 7a5ad1886b70
Note that the actual values may differ slightly because the AES key
you generated was random.
yubikey-ksm-1.14/doc/SyncMonitor.wiki 0000644 0001750 0001750 00000003513 12216316720 015744 0 ustar jas jas == YK-KSM Synchronization Monitor ==
If you deploy multiple redundant YK-KSM instances, it is important to
monitor them to make sure the data they have is synchronized. While
there are many mechanisms to achieve this, we provide a simple yet
flexible approach. The 'ykksm-checksum' script reads out the
important fields from the database and computes a SHA-1 hash of it,
and truncates the hash to 10 hex characters and prints them to stdout.
The "important fields" are serial number, public name, internal name
and AES key.
Sample output looks like this, first there is a Unix time (for
freshness) and then is the truncated hash value.
1284488221
50f5649b80
The script requires the Perl SHA-1 package. Install it like this:
user@ksm:~$ sudo apt-get install libdigest-sha1-perl
...
user@ksm:~$
The typical way to use this is either manually or to run it in a cron
job and output the hash to a file that can be downloaded by a remote
monitor system such as Nagios. The intention is that you run a check
that downloads this file from all of your KSMs, and the Nagios check
verify that all values are 1) fresh (Unix time is not too old) and 2)
that the truncated hash value is identical on all KSMs.
user@ksm:~$ sudo sh -c 'cat > /etc/cron.hourly/run-ykksm-checksum'
#!/bin/sh
FILE=/var/www/checksum.txt
(date --utc +%s; ykksm-checksum --db-user ykksmreader --db-passwd `grep password /etc/yubico/ksm/ykksm-config.php|cut -d\ -f3|cut -d\" -f2`) > $FILE.tmp
mv $FILE.tmp $FILE
user@ksm:~$ sudo chmod +x /etc/cron.hourly/run-ykksm-checksum
If you notice mismatches, you may want to run ykksm-checksum with the
'-v' parameter on the different hosts and then use 'diff -ur' or
similar tool to compare the outputs. This should make it possible to
identify the missmatching entries easily.
yubikey-ksm-1.14/doc/KeyProvisioningFormat.wiki 0000644 0001750 0001750 00000006110 12216316720 017764 0 ustar jas jas == Format of Key Provisioning Data = =
This file holds data used in the Yubikey personalization phase.
The file is an OpenPGP signed and encrypted text file. Readers should
support both CRLF and LF line endings. The values are text and
separated by comma ("," ASCII 0x2C). The first line of the file MUST
be as follows:
# ykksm 1
Each of the rest lines in the file follows the following format:
serialNr,publicName,internalName,aesKey,lockCode,created,accessed[,progflags] # comment
Any data after a # is treated as a comment and is ignored. Lines of
the following format:
# comment
are also treated as comments.
The meaning are as follows:
;serialNr:
: the serial number of the device used for the barcode, decimal integer
;publicName:
: encoding of the "external" yubikey prefix, 0-16 modhex characters, typically 12
: modhex encoded data
;internalName:
: encoding of the "internal" yubikey identity, always 6 binary bytes = 12 hex,
: hex encoded data
;aesKey:
: an aes key used for the device, length decides whether it is a 128, 192, or 256 bit keys.
: hex encoded data
;lockCode:
: the locking code, always 6 binary bytes = 12 hex,
: hex encoded data
;created:
: timestamp of when the key was created
: for example 2009-02-24T17:41:57 or empty
;accessed:
: timestamp of when the key was last accessed
: for example 2009-02-24T17:41:57 or empty
;progflags:
: optional field, integer with flags used during personalization
: to enable, e.g., static key mode or cr output
Examples of valid data lines:
4711,dlcfffckrcde,ca62baca62ba,ecde18dbe76fbd0c33330f1c354871db,be70aeca62ba,2009-01-22 00:25:11,
4712,,ca62baca62ba,ecde18dbe76fbd0c33330f1c354871db,be70aeca62ba,2009-01-22 00:25:11,2009-02-13 00:05:40
4713,dlcfffckrcdedlcf,ca62baca62ba,ecde18dbe76fbd0c33330f1c354871db,be70aeca62ba,2009-01-22 00:25:11,2009-02-13 00:05:40,0
4714,dlcfffckrcdedlcf,ca62baca62ba,ecde18dbe76fbd0c33330f1c354871db,be70aeca62ba,2009-01-22 00:25:11,2009-02-13 00:05:40,4711
Example of actual data using the password 'foobar' (normally it would
be encrypted to a particular OpenPGP key id):
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.9 (GNU/Linux)
jA0EAwMClfljrWYVfm5gycDMIpZXLnzKtUfeEsqXRp63IdAghBzAfdIt4aeJ2kdV
x8uvvHKeHfytjEo/U9Wg4NYqYoDnMeb4zXBmrRqWu558ldW75e5R2kPImuQnZIBQ
3WKRbElrLpQTlbdyDDAzlOnVLvTrmekZ8ByUrED3tyZKJw7OW5YsHi3z5N+QNFbZ
hpMWfDBiJRksQEXv3BbiWVojSS+ZlCBiDjqnbIGuk0nZlJSe3F3Jwdz22Y05aU2h
+2e6vWkqsbvZMVHnU6pauyaM1dh2owXsoHCPLM1fs7ztIh5dAnV9d0TuW4ufKEFQ
FdH5c4dNgl36CNM8dDlM3c8YpfjxlQ11e6ub7QZC1Eu3gqvfPIvYpczlwjkYOkcH
nu1Iq42VgUSJzBr36aL9lLySyT8WRizzmJLaGYX/YqKgBXt6RTSO984WsxE6cl80
paFvFOjybJ2V5GYc7pfdZAM2ySEhnS6PaxYAQXfrEhhtTTCCg1eCqKh4Yamv3u0v
DAkppMqXeprjpC4cNvrQsVOKGx7HissA5x4rECLC
=d54w
-----END PGP MESSAGE-----
=== Naming Scheme ===
The files should use the standard GnuPG output extension '.asc'.
If you want to store many keys in a one-key per file approach, we
suggest to create files named after the serial number. For example:
0.asc
1.asc
2.asc
3.asc
4.asc
5.asc
6.asc
7.asc
8.asc
9.asc
10.asc
11.asc
...
yubikey-ksm-1.14/ykksm-checksum.1 0000644 0001750 0001750 00000002063 12216316720 015045 0 ustar jas jas .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH YKKSM-CHECKSUM "1" "September 2013" "ykksm-checksum 1" "User Commands"
.SH NAME
ykksm-checksum \- Print checksum of important database fields. Useful for quickly determining whether several KSMs are in sync.
.SH SYNOPSIS
.B ykksm-checksum
[\fI--verbose\fR] [\fI--help\fR] [\fI--database DBI\fR] [\fI--db-user USER\fR] [\fI--db-passwd PASSWD\fR]
.SH DESCRIPTION
Print checksum of important database fields. Useful for quickly
determining whether several KSMs are in sync.
.HP
\fB\-\-database\fR DBI: Database identifier, see http://dbi.perl.org/
.IP
defaults to a MySQL database ykksm on localhost,
i.e., dbi:mysql:ykksm. For PostgreSQL on the local
host you can use 'DBI:Pg:dbname=ykksm;host=127.0.0.1'.
.HP
\fB\-\-db\-user\fR USER: Database username to use, defaults to empty string.
.HP
\fB\-\-db\-passwd\fR PASSWD: Database password to use, defaults to empty string.
.PP
Usage example:
.IP
\&./ykksm\-checksum \fB\-\-database\fR dbi:mysql:ykksm \fB\-\-db\-user\fR user \fB\-\-db\-passwd\fR pencil
yubikey-ksm-1.14/ykksm-gen-keys 0000755 0001750 0001750 00000013322 12216316720 014631 0 ustar jas jas #!/usr/bin/perl
# Written by Simon Josefsson .
# Copyright (c) 2009-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use strict;
use POSIX qw(strftime);
use MIME::Base64;
my $device = "/dev/random";
sub usage {
print "Usage: ykksm-gen-keys [--verbose] [--help] [--urandom] [--progflags PROGFLAGS] [--pskc] START [END]\n";
print "\n";
print "Tool to generate keys on the YKKSM-KEYPROV format.\n";
print "\n";
print "START: Decimal start point.\n";
print "\n";
print "END: Decimal end point, if absent START is used as END.\n";
print "\n";
print " --urandom: Use /dev/urandom instead of /dev/random as entropy source.\n";
print "\n";
print " --progflags PROGFLAGS: Add a final personalization configuration string.\n";
print "\n";
print " --pskc: Output keys on the YubiKey PSKC format.\n";
print "\n";
print "Usage example:\n";
print "\n";
print " ./ykksm-gen-keys --urandom 1 10 |\n";
print " gpg -a --sign --encrypt -r 1D2F473E > keys.txt\n";
print "\n";
exit 1;
}
sub hex2modhex {
$_ = shift;
tr/0123456789abcdef/cbdefghijklnrtuv/;
return $_;
}
sub getrand {
my $cnt = shift;
my $buf;
open (FH, $device) or die "Cannot open $device for reading";
read (FH, $buf, $cnt) or die "Cannot read from $device";
close FH;
return $buf;
}
sub gethexrand {
my $cnt = shift;
my $buf = getrand ($cnt);
return lc(unpack("H*", $buf));
}
sub getb64rand {
my $cnt = shift;
my $buf = getrand ($cnt);
return encode_base64($buf, '');
}
# main
if ($#ARGV==-1) {
usage();
}
my $verbose = 0;
my $pskc = 0;
my $progflags;
my $start = "";
my $end = "";
while (defined($ARGV[0])) {
my $cmd = shift @ARGV;
if (($cmd eq "-v") || ($cmd eq "--verbose")) {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
} elsif ($cmd eq "--urandom") {
$device = "/dev/urandom";
} elsif ($cmd eq "--progflags") {
$progflags = "," . shift;
} elsif ($cmd eq "--pskc") {
$pskc = 1;
} elsif ($cmd =~ m/^[0-9]+/) {
if ($start eq "") {
$start = $cmd;
} elsif ($end eq "") {
$end = $cmd;
} else {
die "Invalid extra argument: $cmd";
}
}
}
die "Missing START parameter, try --help" if ($start eq "");
$end = $start if (!$end);
my $now = strftime "%Y-%m-%dT%H:%M:%S", localtime;
if ($pskc) {
$now .= 'Z';
}
my $ctr;
if ($pskc) {
print "\n";
print "\n";
} else {
print "# ykksm 1\n";
print "# start $start end $end device $device\n" if ($verbose);
print "# serialnr,identity,internaluid,aeskey,lockpw,created,accessed[,progflags]\n";
}
$ctr = $start;
while ($ctr <= $end) {
my $hexctr = sprintf "%012x", $ctr;
my $modhexctr = hex2modhex($hexctr);
my $internaluid = gethexrand(6);
my $aeskey = $pskc ? getb64rand(16) : gethexrand(16);
my $lockpw = gethexrand(6);
if ($pskc) {
print " \n";
print " \n";
print " oath.UB\n";
print " $ctr\n";
print " $now\n";
print " \n";
print " \n";
print " 1\n";
print " \n";
print " \n";
print " Yubico\n";
print " \n";
print " \n";
print " \n";
print " \n";
print " \n";
print " \n";
print " $aeskey\n";
print " \n";
print " \n";
print " \n";
print " CN=$modhexctr, UID=$internaluid\n";
print " \n";
print " \n";
} else {
print "# hexctr $hexctr modhexctr $modhexctr\n" if ($verbose);
printf "$ctr,$modhexctr,$internaluid,$aeskey,$lockpw,$now,$progflags\n";
}
$ctr++;
}
if ($pskc) {
print "\n";
} else {
print "# the end\n";
}
exit 0;
yubikey-ksm-1.14/README 0000644 0001750 0001750 00000001660 12216316720 012707 0 ustar jas jas yubikey-ksm
===========
The YubiKey Key Storage Module (YK-KSM) provides a AES key storage
facility for use with a YubiKey validation server.
The YK-KSM is intended to be run on a locked-down server.
This separation allows third parties to keep tight control of the AES
keys for their YubiKeys, but at the same time allow external
validation servers (e.g., Yubico's) to validate OTPs from these
YubiKeys.
Releases are available from:
http://yubico.github.io/yubikey-ksm/releases.html
The YK-KSM was designed to work with the YubiKey validation server:
http://yubico.github.io/yubikey-val/
Documentation is in doc/.
The documentation is also available online at:
http://github.com/Yubico/yubikey-ksm/wiki
Development
-----------
To create a tarball you must have a recent versions of "help2man" and
"git2cl".
If you've checked out the source tree and the doc/ dir is empty, do
$ git submodule init
$ git submodule update
yubikey-ksm-1.14/ykksm-decrypt.php 0000644 0001750 0001750 00000010626 12216316720 015350 0 ustar jas jas .
# Copyright (c) 2009-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require_once 'ykksm-config.php';
require_once 'ykksm-utils.php';
openlog("ykksm", LOG_PID, $logfacility)
or die("ERR Syslog open error\n");
$otp = $_REQUEST["otp"];
if (!$otp) {
syslog(LOG_INFO, "No OTP provided");
die("ERR No OTP provided\n");
}
if (!preg_match("/^([cbdefghijklnrtuv]{0,16})([cbdefghijklnrtuv]{32})$/",
$otp, $matches)) {
syslog(LOG_INFO, "Invalid OTP format: $otp");
die("ERR Invalid OTP format\n");
}
$id = $matches[1];
$modhex_ciphertext = $matches[2];
# Oracle support in PDO is highly experimental, OCI is used instead
# Unfortunately PDO and OCI APIs are different...
$use_oci = substr($db_dsn,0,3) === 'oci';
if (!$use_oci) {
try {
$dbh = new PDO($db_dsn, $db_username, $db_password, $db_options);
} catch (PDOException $e) {
syslog(LOG_ERR, "Database error: " . $e->getMessage());
die("ERR Database error\n");
}
}
else {
# "oci:" prefix needs to be removed before passing db_dsn to OCI
$db_dsn = substr($db_dsn, 4);
$dbh = oci_connect($db_username, $db_password, $db_dsn);
if (!$dbh) {
$error = oci_error();
syslog(LOG_err, "Database error: " . $error["message"]);
die("ERR Database error\n");
}
}
$sql = "SELECT aeskey, internalname FROM yubikeys " .
"WHERE publicname = '$id' AND active = 1";
if (!$use_oci) {
$result = $dbh->query($sql);
if (!$result) {
syslog(LOG_ERR, "Database query error. Query: " . $sql . " Error: " .
print_r ($dbh->errorInfo (), true));
die("ERR Database error\n");
}
$row = $result->fetch(PDO::FETCH_ASSOC);
$aeskey = $row['aeskey'];
$internalname = $row['internalname'];
}
else {
$result = oci_parse($dbh, $sql);
$execute = oci_execute($result);
if (!$execute) {
$error = oci_error($result);
syslog(LOG_ERR, 'Database query error. Query: ' . $sql . 'Error: CODE : ' . $error["code"] .
' MESSAGE : ' . $error["message"] . ' POSITION : ' . $error["offset"] .
' STATEMENT : ' . $error["sqltext"]);
die("ERR Database error\n");
}
$row = oci_fetch_array($result, OCI_ASSOC);
$aeskey = $row['AESKEY'];
$internalname = $row['INTERNALNAME'];
}
if (!$aeskey) {
syslog(LOG_INFO, "Unknown yubikey: " . $otp);
die("ERR Unknown yubikey\n");
}
$ciphertext = modhex2hex($modhex_ciphertext);
$plaintext = aes128ecb_decrypt($aeskey, $ciphertext);
$uid = substr($plaintext, 0, 12);
if (strcmp($uid, $internalname) != 0) {
syslog(LOG_ERR, "UID error: $otp $plaintext: $uid vs $internalname");
die("ERR Corrupt OTP\n");;
}
if (!crc_is_good($plaintext)) {
syslog(LOG_ERR, "CRC error: $otp: $plaintext");
die("ERR Corrupt OTP\n");
}
# Mask out interesting fields
$counter = substr($plaintext, 14, 2) . substr($plaintext, 12, 2);
$low = substr($plaintext, 18, 2) . substr($plaintext, 16, 2);
$high = substr($plaintext, 20, 2);
$use = substr($plaintext, 22, 2);
$out = "OK counter=$counter low=$low high=$high use=$use";
syslog(LOG_INFO, "SUCCESS OTP $otp PT $plaintext $out")
or die("ERR Log error\n");
print "$out\n";
# Close database connection.
$dbh = null;
?>
yubikey-ksm-1.14/Makefile 0000644 0001750 0001750 00000012263 12216316720 013470 0 ustar jas jas # Written by Simon Josefsson .
# Copyright (c) 2009-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
VERSION = 1.14
PACKAGE = yubikey-ksm
CODE = .htaccess Makefile NEWS README ykksm-config.php ykksm-db.sql \
ykksm-decrypt.php ykksm-export ykksm-gen-keys \
ykksm-import ykksm-utils.php ykksm-checksum
DOCS = doc/DecryptionProtocol.wiki doc/DesignGoals.wiki \
doc/GenerateKeys.wiki doc/GenerateKSMKey.wiki \
doc/ImportKeysToKSM.wiki doc/Installation.wiki \
doc/KeyProvisioningFormat.wiki doc/ServerHardening.wiki \
doc/SyncMonitor.wiki
MANS = ykksm-checksum.1 ykksm-export.1 ykksm-gen-keys.1 \
ykksm-import.1
all:
@echo "Try 'make install' or 'make symlink'."
@echo "Docs: https://github.com/Yubico/$(PROJECT)/wiki/Installation"
@exit 1
# Installation rules.
etcprefix = /etc/yubico/ksm
binprefix = /usr/bin
phpprefix = /usr/share/yubikey-ksm
docprefix = /usr/share/doc/yubikey-ksm
manprefix = /usr/share/man/man1
wwwgroup = www-data
install: $(MANS)
install -D --mode 640 .htaccess $(DESTDIR)$(phpprefix)/.htaccess
install -D --mode 640 ykksm-decrypt.php $(DESTDIR)$(phpprefix)/ykksm-decrypt.php
install -D --mode 640 ykksm-utils.php $(DESTDIR)$(phpprefix)/ykksm-utils.php
install -D ykksm-gen-keys $(DESTDIR)$(binprefix)/ykksm-gen-keys
install -D ykksm-import $(DESTDIR)$(binprefix)/ykksm-import
install -D ykksm-export $(DESTDIR)$(binprefix)/ykksm-export
install -D ykksm-checksum $(DESTDIR)$(binprefix)/ykksm-checksum
install -D --backup --mode 640 --group $(wwwgroup) ykksm-config.php $(DESTDIR)$(etcprefix)/ykksm-config.php
install -D ykksm-gen-keys.1 $(DESTDIR)$(manprefix)/ykksm-gen-keys.1
install -D ykksm-import.1 $(DESTDIR)$(manprefix)/ykksm-import.1
install -D ykksm-export.1 $(DESTDIR)$(manprefix)/ykksm-export.1
install -D ykksm-checksum.1 $(DESTDIR)$(manprefix)/ykksm-checksum.1
install -D ykksm-db.sql $(DESTDIR)$(docprefix)/ykksm-db.sql
install -D Makefile $(DESTDIR)$(docprefix)/ykksm.mk
install -D $(DOCS) $(DESTDIR)$(docprefix)/
wwwprefix = /var/www/wsapi
symlink:
install -d $(wwwprefix)
ln -sf $(phpprefix)/.htaccess $(wwwprefix)/.htaccess
ln -sf $(phpprefix)/ykksm-decrypt.php $(wwwprefix)/decrypt.php
# Maintainer rules.
PROJECT = $(PACKAGE)
$(PACKAGE)-$(VERSION).tgz: $(FILES) $(MANS)
git submodule init
git submodule update
mkdir $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION)/doc
cp $(CODE) $(PACKAGE)-$(VERSION)/
cp $(MANS) $(PACKAGE)-$(VERSION)/
cp $(DOCS) $(PACKAGE)-$(VERSION)/doc/
git2cl > $(PACKAGE)-$(VERSION)/ChangeLog
tar cfz $(PACKAGE)-$(VERSION).tgz $(PACKAGE)-$(VERSION)
rm -rf $(PACKAGE)-$(VERSION)
dist: $(PACKAGE)-$(VERSION).tgz
distclean: clean
rm -f *.1
clean:
rm -f *~
rm -rf $(PACKAGE)-$(VERSION)
NAME_ykksm-checksum = 'Print checksum of important database fields. Useful for quickly determining whether several KSMs are in sync.'
NAME_ykksm-export = 'Tool to export keys to the YKKSM-KEYPROV format.'
NAME_ykksm-gen-keys = 'Tool to generate keys on the YKKSM-KEYPROV format.'
NAME_ykksm-import = 'Tool to import key data on the YKKSM-KEYPROV format.'
%.1: %
help2man -N --name=$(NAME_$*) --version-string=1 ./$* > $@
man: $(MANS)
release: dist
@if test -z "$(KEYID)"; then \
echo "Try this instead:"; \
echo " make release KEYID=[PGPKEYID]"; \
echo "For example:"; \
echo " make release KEYID=2117364A"; \
exit 1; \
fi
@head -1 NEWS | grep -q "Version $(VERSION) (released `date -I`)" || \
(echo 'error: You need to update date/version in NEWS'; exit 1)
@if test ! -d "$(YUBICO_GITHUB_REPO)"; then \
echo "yubico.github.com repo not found!"; \
echo "Make sure that YUBICO_GITHUB_REPO is set"; \
exit 1; \
fi
gpg --detach-sign --default-key $(KEYID) $(PACKAGE)-$(VERSION).tgz
gpg --verify $(PACKAGE)-$(VERSION).tgz.sig
git tag -u $(KEYID) -m "$(PACKAGE)-$(VERSION)" $(PACKAGE)-$(VERSION)
$(YUBICO_GITHUB_REPO)/publish $(PROJECT) $(VERSION) $(PACKAGE)-$(VERSION).tgz*
@echo "Release created and tagged, remember to git push && git push --tags"
yubikey-ksm-1.14/ykksm-checksum 0000755 0001750 0001750 00000007761 12216316720 014723 0 ustar jas jas #!/usr/bin/perl
# Written by Simon Josefsson .
# Copyright (c) 2010-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use strict;
use DBI;
use POSIX qw(strftime);
use Digest::SHA;
sub usage {
print "Usage: $0 [--verbose] [--help] [--database DBI] [--db-user USER] [--db-passwd PASSWD]\n";
print "\n";
print "Print checksum of important database fields. Useful for quickly\n";
print "determining whether several KSMs are in sync.\n";
print "\n";
print " --database DBI: Database identifier, see http://dbi.perl.org/\n";
print " defaults to a MySQL database ykksm on localhost,\n";
print " i.e., dbi:mysql:ykksm. For PostgreSQL on the local\n";
print " host you can use 'DBI:Pg:dbname=ykksm;host=127.0.0.1'.\n";
print "\n";
print " --db-user USER: Database username to use, defaults to empty string.\n";
print "\n";
print " --db-passwd PASSWD: Database password to use, defaults to empty string.\n";
print "\n";
print "Usage example:\n";
print "\n";
print " ./ykksm-checksum --database dbi:mysql:ykksm --db-user user --db-passwd pencil\n";
print "\n";
exit 1;
}
#Support dbconfig-common generated database settings, if available
our ($dbuser, $dbpass, $basepath, $dbname, $dbserver, $dbport, $dbtype);
if( -r '/etc/yubico/ksm/config-db.cfg' ) {
require '/etc/yubico/ksm/config-db.cfg';
} else {
$dbtype = 'mysql';
$dbname = 'ykksm';
}
my $verbose = 0;
my $db = "dbi:$dbtype:$dbname";
while ($ARGV[0] =~ m/^-(.*)/) {
my $cmd = shift @ARGV;
if (($cmd eq "-v") || ($cmd eq "--verbose")) {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
} elsif ($cmd eq "--database") {
$db = shift;
} elsif ($cmd eq "--db-user") {
$dbuser = shift;
} elsif ($cmd eq "--db-passwd") {
$dbpass = shift;
}
}
if ($#ARGV>=0) {
usage();
}
my $dbh = DBI->connect($db, $dbuser, $dbpass, {'RaiseError' => 1});
my $sth = $dbh->prepare ('SELECT serialnr, publicname, internalname, aeskey '.
'FROM yubikeys '.
'ORDER BY serialnr, publicname')
or die "Couldn't prepare statement: " . $dbh->errstr;
$sth->execute()
or die "Couldn't execute statement: " . $sth->errstr;
my $sha1 = Digest::SHA->new(1);
my $row;
while ($row = $sth->fetchrow_hashref()) {
if ($verbose) {
print "# serialnr=" . $row->{'serialnr'} .
" publicname=" . $row->{'publicname'} . "\n";
}
$sha1->add($row->{'serialnr'});
$sha1->add($row->{'publicname'});
$sha1->add($row->{'internalname'});
$sha1->add($row->{'aeskey'});
}
if ($sth->rows == 0) {
print "No data?!\n\n";
exit 1;
}
print substr ($sha1->hexdigest, 0, 10) . "\n";
$sth->finish;
$dbh->disconnect();
exit 0;
yubikey-ksm-1.14/.htaccess 0000644 0001750 0001750 00000000077 12216316720 013626 0 ustar jas jas RewriteEngine on
RewriteRule ^([^/\.\?]+)(\?.*)?$ $1.php$2 [L]
yubikey-ksm-1.14/ykksm-export 0000755 0001750 0001750 00000007440 12216316720 014434 0 ustar jas jas #!/usr/bin/perl
# Written by Simon Josefsson .
# Copyright (c) 2009-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use strict;
use DBI;
use MIME::Base64;
sub usage {
print "Usage: $0 [--verbose] [--help] [--database DBI] [--db-user USER] [--db-passwd PASSWD]\n";
print "\n";
print "Tool to export keys to the YKKSM-KEYPROV format.\n";
print "\n";
print " --database DBI: Database identifier, see http://dbi.perl.org/\n";
print " defaults to a MySQL database ykksm on localhost,\n";
print " i.e., DBI::mysql:ykksm.\n";
print "\n";
print " --db-user USER: Database username to use, defaults to empty string.\n";
print "\n";
print " --db-passwd PASSWD: Database password to use, defaults to empty string.\n";
print "\n";
print "Usage example:\n";
print "\n";
print " ./ykksm-export --db-user foo --db-passwd pass123 |\n";
print " gpg -a --sign --encrypt -r 1D2F473E > keys.txt\n";
print "\n";
exit 1;
}
#Support dbconfig-common generated database settings, if available
our ($dbuser, $dbpass, $basepath, $dbname, $dbserver, $dbport, $dbtype);
if( -r '/etc/yubico/ksm/config-db.cfg' ) {
require '/etc/yubico/ksm/config-db.cfg';
} else {
$dbtype = 'mysql';
$dbname = 'ykksm';
}
my $verbose = 0;
my $db = "dbi:$dbtype:$dbname";
while ($ARGV[0] =~ m/^-(.*)/) {
my $cmd = shift @ARGV;
if (($cmd eq "-v") || ($cmd eq "--verbose")) {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
} elsif ($cmd eq "--database") {
$db = shift;
} elsif ($cmd eq "--db-user") {
$dbuser = shift;
} elsif ($cmd eq "--db-passwd") {
$dbpass = shift;
}
}
if ($#ARGV>=0) {
usage();
}
my $dbh = DBI->connect($db, $dbuser, $dbpass, {'RaiseError' => 1});
my $sth = $dbh->prepare
('SELECT serialnr, publicname, internalname, aeskey, lockcode, created FROM yubikeys')
or die "Couldn't prepare statement: " . $dbh->errstr;
$sth->execute()
or die "Couldn't execute statement: " . $sth->errstr;
my $row;
while ($row = $sth->fetchrow_hashref()) {
if ($verbose) {
print "# ";
foreach my $key (keys %$row) {
print $key . "=" . $row->{$key} . " ";
}
print "\n";
}
print $row->{'serialnr'} . ",";
print $row->{'publicname'} . ",";
print $row->{'internalname'} . ",";
print $row->{'aeskey'} . ",";
print $row->{'lockcode'} . ",";
print $row->{'created'} . ",\n";
}
if ($sth->rows == 0) {
print "No data?!\n\n";
}
$sth->finish;
$dbh->disconnect();
exit 0;
yubikey-ksm-1.14/ykksm-import 0000755 0001750 0001750 00000012425 12216316720 014424 0 ustar jas jas #!/usr/bin/perl
# Written by Simon Josefsson .
# Copyright (c) 2009-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use strict;
use DBI;
use POSIX qw(strftime);
sub usage {
print "Usage: $0 [--verbose] [--help] [--database DBI] [--db-user USER] [--db-passwd PASSWD] [--creator CREATOR]\n";
print "\n";
print "Tool to import key data on the YKKSM-KEYPROV format.\n";
print "\n";
print " --database DBI: Database identifier, see http://dbi.perl.org/\n";
print " defaults to a MySQL database ykksm on localhost,\n";
print " i.e., dbi:mysql:ykksm. For PostgreSQL on the local\n";
print " host you can use 'DBI:Pg:dbname=ykksm;host=127.0.0.1'.\n";
print "\n";
print " --db-user USER: Database username to use, defaults to empty string.\n";
print "\n";
print " --db-passwd PASSWD: Database password to use, defaults to empty string.\n";
print "\n";
print " --creator CREATOR: Short string with creator info.\n";
print " Defaults to using the PGP signer key id, normally.\n";
print " you don't change this.\n";
print "\n";
print "Usage example:\n";
print "\n";
print " ./ykksm-import < keys.txt\n";
print "\n";
exit 1;
}
#Support dbconfig-common generated database settings, if available
our ($dbuser, $dbpass, $basepath, $dbname, $dbserver, $dbport, $dbtype);
if( -r '/etc/yubico/ksm/config-db.cfg' ) {
require '/etc/yubico/ksm/config-db.cfg';
} else {
$dbtype = 'mysql';
$dbname = 'ykksm';
}
my $verbose = 0;
my $creator;
my $db = "dbi:$dbtype:$dbname";
while ($ARGV[0] =~ m/^-(.*)/) {
my $cmd = shift @ARGV;
if (($cmd eq "-v") || ($cmd eq "--verbose")) {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
} elsif ($cmd eq "--creator") {
$creator = shift;
} elsif ($cmd eq "--database") {
$db = shift;
} elsif ($cmd eq "--db-user") {
$dbuser = shift;
} elsif ($cmd eq "--db-passwd") {
$dbpass = shift;
}
}
if ($#ARGV>=0) {
usage();
}
my $infilename = "tmp.$$";
my $verify_status;
my $encrypted_to;
my $signed_by;
# Read input into temporary file.
open TMPFILE, ">$infilename"
or die "Cannot open $infilename for writing";
while (<>) {
print TMPFILE $_;
}
close TMPFILE;
END { unlink $infilename; }
# Get status
open(GPGV, "gpg --status-fd 1 --output /dev/null < $infilename 2>&1 |")
or die "Cannot launch gpg";
while () {
$verify_status .= $_;
$encrypted_to = $1 if m,^\[GNUPG:\] ENC_TO ([0-9A-F]+) ,;
$signed_by = $1 if m,^\[GNUPG:\] VALIDSIG [0-9A-F]+([0-9A-F]{8}) ,;
}
close GPGV;
print "Verification output:\n" . $verify_status;
print "encrypted to: " . $encrypted_to . "\n";
print "signed by: " . $signed_by . "\n";
die "Input not signed?" if !$signed_by;
my $dbh = DBI->connect($db, $dbuser, $dbpass, {'RaiseError' => 1});
my $inserth = $dbh->prepare_cached(qq{
INSERT INTO yubikeys (creator, created, serialnr,
publicname, internalname, aeskey, lockcode)
VALUES (?, ?, ?, ?, ?, ?, ?)
});
my $now = strftime "%Y-%m-%dT%H:%M:%S", localtime;
$creator = $signed_by if !$creator;
open(GPGV, "gpg < $infilename 2>/dev/null |")
or die "Cannot launch gpg";
while () {
next if m:^#:;
my ($serialnr, $publicname, $internalname, $aeskey,
$lockcode, $created, $accessed) =
m%^([0-9]+),([cbdefghijklnrtuv]+),([0-9a-f]+),([0-9a-f]+),([0-9a-f]+),([T:0-9 -]*),([T:0-9 -]*)%;
if ($verbose) {
print "line: $_";
}
print "\tserialnr $serialnr publicname $publicname " .
"internalname $internalname aeskey $aeskey lockcode $lockcode " .
"created $created accessed $accessed eol";
if ($verbose) {
print "\n";
} else {
print "\r";
}
$created = $now if !$created;
$accessed = "NULL" if !$accessed;
$inserth->execute($creator, $created, $serialnr,
$publicname, $internalname,
$aeskey, $lockcode)
or die "Database insert error: " . $dbh->errstr;
}
print "\n";
close GPGV;
$dbh->disconnect();
exit 0;
yubikey-ksm-1.14/ykksm-import.1 0000644 0001750 0001750 00000002015 12216316720 014552 0 ustar jas jas .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH YKKSM-IMPORT "1" "September 2013" "ykksm-import 1" "User Commands"
.SH NAME
ykksm-import \- Tool to import key data on the YKKSM-KEYPROV format.
.SH SYNOPSIS
.B ykksm-import
[\fI--verbose\fR] [\fI--help\fR] [\fI--database DBI\fR] [\fI--db-user USER\fR] [\fI--db-passwd PASSWD\fR] [\fI--creator CREATOR\fR]
.SH DESCRIPTION
Tool to import key data on the YKKSM\-KEYPROV format.
.HP
\fB\-\-database\fR DBI: Database identifier, see http://dbi.perl.org/
.IP
defaults to a MySQL database ykksm on localhost,
i.e., dbi:mysql:ykksm. For PostgreSQL on the local
host you can use 'DBI:Pg:dbname=ykksm;host=127.0.0.1'.
.HP
\fB\-\-db\-user\fR USER: Database username to use, defaults to empty string.
.HP
\fB\-\-db\-passwd\fR PASSWD: Database password to use, defaults to empty string.
.TP
\fB\-\-creator\fR CREATOR: Short string with creator info.
Defaults to using the PGP signer key id, normally.
you don't change this.
.PP
Usage example:
.IP
\&./ykksm\-import < keys.txt
yubikey-ksm-1.14/ykksm-export.1 0000644 0001750 0001750 00000001613 12216316720 014564 0 ustar jas jas .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH YKKSM-EXPORT "1" "September 2013" "ykksm-export 1" "User Commands"
.SH NAME
ykksm-export \- Tool to export keys to the YKKSM-KEYPROV format.
.SH SYNOPSIS
.B ykksm-export
[\fI--verbose\fR] [\fI--help\fR] [\fI--database DBI\fR] [\fI--db-user USER\fR] [\fI--db-passwd PASSWD\fR]
.SH DESCRIPTION
Tool to export keys to the YKKSM\-KEYPROV format.
.HP
\fB\-\-database\fR DBI: Database identifier, see http://dbi.perl.org/
.IP
defaults to a MySQL database ykksm on localhost,
i.e., DBI::mysql:ykksm.
.HP
\fB\-\-db\-user\fR USER: Database username to use, defaults to empty string.
.HP
\fB\-\-db\-passwd\fR PASSWD: Database password to use, defaults to empty string.
.PP
Usage example:
.IP
\&./ykksm\-export \fB\-\-db\-user\fR foo \fB\-\-db\-passwd\fR pass123 |
.IP
gpg \fB\-a\fR \fB\-\-sign\fR \fB\-\-encrypt\fR \fB\-r\fR 1D2F473E > keys.txt
yubikey-ksm-1.14/ChangeLog 0000644 0001750 0001750 00000031015 12216316720 013576 0 ustar jas jas 2013-09-18 Simon Josefsson
* doc: Bump doc/.
2013-09-18 Simon Josefsson
* NEWS: Version 1.14.
2013-09-18 Simon Josefsson
* Makefile: Fix release rule.
2013-09-18 Simon Josefsson
* NEWS: Add.
2013-09-05 Simon Josefsson
* NEWS: Add.
2013-07-01 Remi Mollon
* ykksm-decrypt.php: oracle support
2013-04-22 Simon Josefsson
* Makefile, README: Improve README. Dist it.
2013-04-17 Simon Josefsson
* Makefile, NEWS: Bump version.
2013-04-17 Simon Josefsson
* Makefile: Improve release target.
2013-04-17 Simon Josefsson
* Makefile, NEWS: Version 1.13.
2013-04-17 Simon Josefsson
* NEWS: Updated release procedure.
2013-04-17 Simon Josefsson
* Makefile: Fix dist target.
2013-04-10 Dain Nilsson
* Makefile: Updated release target.
2013-03-05 Dain Nilsson
* : Merge pull request #2 from colinnewell/master The makefile has spaces where there should be tabs
2013-02-05 Dain Nilsson
* Makefile: Fixed homepage building in make release.
2013-02-05 Dain Nilsson
* NEWS: Updated NEWS for 1.12 release.
2013-02-04 Dain Nilsson
* ykksm-checksum, ykksm-export, ykksm-import: Updated copyright
headers.
2013-02-01 Dain Nilsson
* .gitignore: Added .gitignore with build artifacts.
2013-02-04 Simon Josefsson
* COPYING, Makefile, NEWS, ykksm-decrypt.php, ykksm-gen-keys,
ykksm-utils.php: Update copyright information.
2013-02-04 Simon Josefsson
* README: Fix ykval link.
2013-01-31 Dain Nilsson
* Makefile, NEWS: Updated Makefile and NEWS post 1.11.
2013-01-31 Dain Nilsson
* NEWS: Updated NEWS for 1.11.
2013-01-31 Dain Nilsson
* Makefile: Added missing manprefix to Makefile.
2013-01-31 Dain Nilsson
* Makefile, NEWS: Updated Makefile and NEWS post 1.10 release.
2013-01-31 Dain Nilsson
* NEWS: Updated NEWS for 1.10
2013-01-31 Dain Nilsson
* Makefile: Added quoting of versions for Jekyll
2013-01-30 Dain Nilsson
* Makefile: Makefile fixes.
2013-01-30 Dain Nilsson
* Makefile: Makefile now installs man pages.
2013-01-28 Dain Nilsson
* ykksm-config.php: Added missing default db type.
2013-01-28 Dain Nilsson
* ykksm-checksum, ykksm-export, ykksm-import: Fixed scripts failing
when db config exists but isn't readable.
2013-01-28 Dain Nilsson
* Makefile, NEWS, doc, ykksm-checksum, ykksm-config.php,
ykksm-export, ykksm-import: Use yubikey-ksm instead of ykksm in
paths, configuration in /etc/yubico/ksm
2013-01-23 Dain Nilsson
* Makefile, NEWS: Updated versions post 1.9.
2013-01-23 Dain Nilsson
* NEWS, doc: Version 1.9
2013-01-23 Dain Nilsson
* NEWS, ykksm-utils.php: Renamed hex2bin to yubi_hex2bin.
2013-01-23 Dain Nilsson
* Makefile, NEWS: Updated versions post 1.8 release.
2013-01-21 Dain Nilsson
* NEWS, doc: Updated NEWS for 1.8 release.
2013-01-21 Dain Nilsson
* Makefile, NEWS: Added ChangeLog generation to make dist.
2012-12-21 Dain Nilsson
* Makefile: Fixed formatting of releases.html
2012-12-21 Dain Nilsson
* Makefile, NEWS: Updated versions post 1.7 release.
2012-12-21 Dain Nilsson
* NEWS: Version 1.7.
2012-12-21 Dain Nilsson
* NEWS: Updated NEWS
2012-12-21 Dain Nilsson
* ykksm-checksum, ykksm-config.php, ykksm-export, ykksm-import:
Added support for reading db config from /etc/ykksm/
2012-12-20 Dain Nilsson
* ykksm-utils.php: Replaced the deprecated use of 'mcrypt_ecb' with
'mdecrypt_generic'
2012-12-20 Dain Nilsson
* Makefile: Added man pages requirement to install.
2012-12-20 Dain Nilsson
* Makefile: Added distclean to Makefile
2012-12-19 Dain Nilsson
* Makefile: Makefile fixes (DESTDIR and file permissions).
2012-12-19 Dain Nilsson
* Makefile: Added automated publishing of release to Makefile.
2012-12-18 Dain Nilsson
* README: Corrected releases link in README.
2012-12-18 Dain Nilsson
* README: Added link to GitHub Pages page to README.
2012-12-18 Dain Nilsson
* Makefile, NEWS: Bumped version post release.
2012-12-18 Dain Nilsson
* Makefile: Added manual entry of KEYID to make release.
2012-12-18 Dain Nilsson
* NEWS: Updated NEWS for release of 1.6
2012-12-18 Dain Nilsson
* doc: Updated docs.
2012-12-18 Dain Nilsson
* Makefile: Updated make release to use git.
2012-12-18 Dain Nilsson
* Makefile, NEWS, README, README.md: Updated NEWS. Renamed README.
2012-12-18 Dain Nilsson
* Makefile: Added clean-man to clean in Makefile
2012-12-18 Dain Nilsson
* README.md: Updated README with info about doc.
2012-12-18 Dain Nilsson
* .gitmodules, doc: Added doc submodule.
2012-12-18 Dain Nilsson
* README.md: Updated URL to yubikey-val-server-php in readme.
2012-12-18 Dain Nilsson
* : commit 9f3f2373db74127c4e1fe6258aa28e9855401e94 Author: Dain
Nilsson Date: Tue Dec 18 04:40:42 2012 -0800
2012-12-18 Dain Nilsson
* Makefile, ykksm-checksum, ykksm-checksum.pl, ykksm-export,
ykksm-export.pl, ykksm-gen-keys, ykksm-gen-keys.pl, ykksm-import,
ykksm-import.pl, ykksm-upgrade.pl: Removed .pl suffix from scripts.
Added man page generation to Makefile.
2012-12-18 Dain Nilsson
* ykksm-checksum.pl: Replaced DIGEST::SHA1 with DIGEST::SHA.
2012-01-23 Simon Josefsson
* Makefile, ykksm-checksum.pl, ykksm-decrypt.php, ykksm-export.pl,
ykksm-gen-keys.pl, ykksm-import.pl, ykksm-upgrade.pl,
ykksm-utils.php: Bump copyright information.
2011-01-14 Simon Josefsson
* NEWS: Add.
2011-01-14 Simon Josefsson
* ykksm-checksum.pl: Order by serial number first, makes more sense.
2010-11-11 Simon Josefsson
* ykksm-gen-keys.pl: Fix command line handling.
2010-11-11 Simon Josefsson
* ykksm-gen-keys.pl: Make the old format the default, use --pkcs to
get PKSC.
2010-11-11 Simon Josefsson
* NEWS, ykksm-gen-keys.pl: ykkgsm-gen-keys supports the PSKC YubiKey
profile.
2010-09-21 Simon Josefsson
* Makefile, NEWS: Bump versions.
2010-09-14 Simon Josefsson
* NEWS: Version 1.5.
2010-09-14 Simon Josefsson
* NEWS: Version 1.4.
2010-09-14 Simon Josefsson
* Makefile: Fix release target. Bump revision.
2010-09-14 Simon Josefsson
* NEWS, ykksm-decrypt.php: Don't use PDO rowCount. Issue #2.
2010-09-14 Simon Josefsson
* NEWS: Add.
2010-09-14 Simon Josefsson
* NEWS: Add.
2010-09-14 Simon Josefsson
* ykksm-gen-keys.pl: Fix warning. Issue #3 reported by
toddejohnson.
2010-03-16 Simon Josefsson
* Makefile: Version 1.3.
2010-03-16 Simon Josefsson
* NEWS: Add dates to versions.
2010-03-16 Simon Josefsson
* Makefile: Dist doc/SyncMonitor.wiki.
2010-03-03 Simon Josefsson
* ykksm-checksum.pl: Better ordering.
2010-03-03 Simon Josefsson
* ykksm-checksum.pl: Order query.
2010-03-03 Simon Josefsson
* Makefile, ykksm-checksum.pl: Add checksum tool.
2010-01-19 Simon Josefsson
* Makefile: Fix.
2009-12-16 Simon Josefsson
* Makefile: Prepare for release.
2009-12-15 Simon Josefsson
* NEWS: Version 1.2.
2009-12-15 Simon Josefsson
* Makefile: Fix release target.
2009-12-15 Simon Josefsson
* Makefile: Fix.
2009-12-15 Simon Josefsson
* Makefile: Fix rules.
2009-12-15 Simon Josefsson
* ykksm-decrypt.php: Use require_once.
2009-12-15 Simon Josefsson
* Makefile: Fix symlink rule.
2009-12-15 Simon Josefsson
* Makefile: Fix install rule.
2009-12-15 Simon Josefsson
* Makefile: Add symlink rule.
2009-12-15 Simon Josefsson
* Makefile: Fix install rule.
2009-12-15 Simon Josefsson
* Makefile: fix
2009-12-15 Simon Josefsson
* Makefile: Fix install target.
2009-12-14 Simon Josefsson
* Makefile: Fix perms.
2009-12-14 Simon Josefsson
* Makefile: Fix.
2009-12-14 Simon Josefsson
* Makefile: Add install rule.
2009-12-14 Simon Josefsson
* ykksm-db.sql, ykksm-decrypt.php, ykksm-export.pl,
ykksm-import.pl, ykksm-upgrade.pl: Case insensitive.
2009-12-14 Simon Josefsson
* ykksm-import.pl: Improve help and fix created_by field.
2009-12-14 Simon Josefsson
* ykksm-db.sql: Make portable.
2009-12-02 Simon Josefsson
* ykksm-config.php: Update for PHP PDO configuration.
2009-12-02 Simon Josefsson
* ykksm-decrypt.php: Use PHP PDO database interface instead of hard
coding the MySQL interface.
2009-12-02 Simon Josefsson
* NEWS: Add.
2009-12-02 Simon Josefsson
* Makefile: Bump version.
2009-11-20 Simon Josefsson
* Makefile: Less hard coding.
2009-11-20 Simon Josefsson
* Makefile: Fix file description.
2009-11-20 Simon Josefsson
* Makefile: Add.
2009-11-20 Simon Josefsson
* : Pull in wiki to doc/.
2009-06-24 Simon Josefsson
* ykksm-decrypt.php: Reorder UID/CRC check so we get only the
interesting CRC errors.
2009-05-04 Simon Josefsson
* .htaccess: Add.
2009-04-19 Simon Josefsson
* ykksm-export.pl: Hint.
2009-04-19 Simon Josefsson
* ykksm-export.pl: Chmod.x
2009-04-19 Simon Josefsson
* ykksm-export.pl: Fix typo.
2009-04-19 Simon Josefsson
* ykksm-export.pl: Add.
2009-04-19 Simon Josefsson
* ykksm-db.sql: Be first-time install friendly.
2009-03-18 Simon Josefsson
* ykksm-decrypt.php: Log return string.
2009-03-18 Simon Josefsson
* ykksm-decrypt.php: Improve debugging.
2009-03-18 Simon Josefsson
* ykksm-decrypt.php: Reorder high/low to match internal order.
2009-03-18 Simon Josefsson
* TODO, ykksm-db.sql, ykksm-decrypt.php, ykksm-import.pl: Drop
accessed field.
2009-03-11 Simon Josefsson
* ykksm-decrypt.php: Accidentally reversed high/low. Rename fields
slightly.
2009-02-27 Simon Josefsson
* ykksm-import.pl: Fix --help.
2009-02-27 Simon Josefsson
* ykksm-import.pl: Don't require progflags.
2009-02-27 Simon Josefsson
* ykksm-gen-keys.pl: Support --progflags.
2009-02-25 Simon Josefsson
* ykksm-gen-keys.pl: Fix --help.
2009-02-25 Simon Josefsson
* ykksm-config.php, ykksm-decrypt.php: Make syslog facility
configurable.
2009-02-25 Simon Josefsson
* ykksm-import.pl: Cleanup temp file properly.
2009-02-24 Simon Josefsson
* ykksm-import.pl: Fix --help.
2009-02-24 Simon Josefsson
* TODO, ykksm-config.php, ykksm-db.sql, ykksm-decrypt.php,
ykksm-gen-keys.pl, ykksm-import.pl, ykksm-utils.php: Commit initial
version.
2009-02-24 Simon Josefsson
* Initial directory structure.
yubikey-ksm-1.14/ykksm-config.php 0000644 0001750 0001750 00000000753 12216316720 015143 0 ustar jas jas
yubikey-ksm-1.14/ykksm-utils.php 0000644 0001750 0001750 00000004574 12216316720 015043 0 ustar jas jas .
# Copyright (c) 2009-2013 Yubico AB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function yubi_hex2bin($h)
{
if (!is_string($h)) return null;
$r='';
for ($a=0; $a> 1;
if ($n != 0) {
$crc = $crc ^ 0x8408;
}
}
}
return $crc;
}
function crc_is_good($token) {
$crc = calculate_crc($token);
return $crc == 0xf0b8;
}
?>