]> err.no Git - yubikey-personalization.old/commitdiff
Fix make distcheck by pulling in ykcore stuff.
authorSimon Josefsson <simon@josefsson.org>
Tue, 5 May 2009 14:33:27 +0000 (14:33 +0000)
committerSimon Josefsson <simon@josefsson.org>
Tue, 5 May 2009 14:33:27 +0000 (14:33 +0000)
14 files changed:
Makefile.am
README
configure.ac
ykcore/Makefile.am [new file with mode: 0644]
ykcore/ykcore.c [new file with mode: 0644]
ykcore/ykcore.h [new file with mode: 0644]
ykcore/ykcore_backend.h [new file with mode: 0644]
ykcore/ykcore_libusb.c [new file with mode: 0644]
ykcore/ykcore_osx.c [new file with mode: 0644]
ykcore/ykcore_stub.c [new file with mode: 0644]
ykcore/ykcore_win32.c [new file with mode: 0644]
ykcore/ykdef.h [new file with mode: 0644]
ykcore/ykstatus.c [new file with mode: 0644]
ykcore/ykstatus.h [new file with mode: 0644]

index e99c6083d10c6130f09b132593e507a1113b7f04..dc4dc03c4dd6b5f563d381e1e05b5be92139b944 100644 (file)
@@ -1,9 +1,6 @@
 # Written by Richard Levitte <richard@levitte.org>.
 # Copyright (c) 2008, 2009 Yubico AB
 # All rights reserved.
-#
-# Copyright (c) 2008, 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
 
 # Subdirectories
 
-SUBDIRS=@subdirs@
+SUBDIRS=ykcore
 
 ACLOCAL_AMFLAGS = -I m4
 
-AM_CPPFLAGS = -I./yubikey-core -I./rfc4634
+AM_CPPFLAGS = -I$(srcdir)/ykcore -I$(srcdir)/rfc4634
 
 # The library.
 
 lib_LTLIBRARIES = libykpers.la
-libykpers_la_SOURCES = ykpers.h ykpers.c ykpbkdf2.h ykpbkdf2.c \
-       rfc4634/hmac.c rfc4634/usha.c rfc4634/sha.h \
-       rfc4634/sha1.c rfc4634/sha224-256.c rfc4634/sha384-512.c
-libykpers_la_LIBADD = $(LTLIBYUBIKEY) ./yubikey-core/libykcore.la -lusb
+libykpers_la_SOURCES = ykpers.h ykpers.c ykpbkdf2.h ykpbkdf2.c
+libykpers_la_SOURCES += rfc4634/hmac.c rfc4634/usha.c rfc4634/sha.h    \
+       rfc4634/sha1.c rfc4634/sha224-256.c rfc4634/sha384-512.c        \
+       rfc4634/sha-private.h
+libykpers_la_LIBADD = $(LTLIBYUBIKEY) ./ykcore/libykcore.la -lusb
 libykpers_la_LDFLAGS = -no-undefined \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
 
@@ -52,12 +50,12 @@ libykpers_la_LDFLAGS = -no-undefined \
 bin_PROGRAMS = ykpersonalize
 
 ykpersonalize_SOURCES = ykpersonalize.c
-ykpersonalize_LDADD = ./libykpers.la ./yubikey-core/libykcore.la
+ykpersonalize_LDADD = ./libykpers.la ./ykcore/libykcore.la
 
 # Self tests.
 
 AM_LDFLAGS = -no-install
-LDADD = ./libykpers.la ./yubikey-core/libykcore.la
+LDADD = ./libykpers.la
 
 ctests = selftest$(EXEEXT)
 check_PROGRAMS = $(ctests)
diff --git a/README b/README
index ccc15c8fe6d7fd84f2643231bfdc1850babc70f2..32f65a63db85b24fe4ab51b221040056e402f3cc 100644 (file)
--- a/README
+++ b/README
@@ -1,28 +1,17 @@
 =Dependencies=
 
-This package depends on another yubikey package called yubikey-core.
+Yubico-c-client is needed, see http://code.google.com/p/yubico-c/
 
-The current best way to get a working yubikey-core is to fetch it as
-follows:
-
-  svn checkout http://yubikey-core.googlecode.com/svn/trunk/ yubikey-core
-
-You can do that in a completely separate directory as well as directly
-in the directory where you found this file.  If you do the former,
-just make sure there's a soft link here with the name yubikey-core, as
-follows:
-
-  ln -s /PATH/TO/yubikey-core yubikey-core
-
-Also, yubikey-core depends on the development files for libusb, so you
-will have to get those as well.  Getting and installing them depends
-on your operating systems, here are example for a few flavors:
+Yubikey-personalization depends on libusb, so you will have to get it.
+Getting and installing them depends on your operating systems, here
+are example for a few flavors:
 
   (Debian) apt-get install libusb-dev
   (Fedora) yum install libusb-devel
 
+
 =Build instructions=
 
-autoreconf -fvi
+autoreconf --install
 ./configure
 make check
index e23cef999408de11b87a53e6153c92a47e48e777..985db4fbd268310b286ad55fb38ad54f767836dd 100644 (file)
@@ -39,46 +39,14 @@ AC_SUBST(LT_CURRENT, 1)
 AC_SUBST(LT_REVISION, 0)
 AC_SUBST(LT_AGE, 0)
 
-AC_ARG_WITH([usb], [ AS_HELP_STRING([--with-usb], [set libusb root path])])
-
 AM_INIT_AUTOMAKE([-Wall -Werror])
 AC_PROG_CC
 AC_LIBTOOL_WIN32_DLL
 AC_PROG_LIBTOOL
 
-# This really checks a directory
-AC_CHECK_FILES([yubikey-core/configure.ac yubikey-core/ykcore.h],,AC_MSG_FAILURE(yubikey-core directory not found.
-
-************************************
-Please provide by checking out http://yubikey-core.googlecode.com/svn/trunk
-with svn and creating a symbolic link `yubikey-core' to that checkout
-************************************
-))
-#AC_SEARCH_LIBS([yubikey_parse],[yubikey],,AC_MSG_FAILURE(libyubikey not found))
-
-# Check that the yubikey-core we try to use is modern enough
-AC_MSG_CHECKING(if yubikey-core/ykcore.h declares yk_usb_strerror)
-AC_EGREP_CPP([yk_usb_strerror],
-            [#include "yubikey-core/ykcore.h"],
-            AC_MSG_RESULT(yes),
-            AC_MSG_RESULT(no)
-            AC_MSG_FAILURE(yubikey-core/ykcore.h does not declare yk_usb_strerror.
-You probably need to update yubikey-core))
-
-if test "$with_usb" != "yes"; then
-  if test "$with_usb" != ""; then
-    CFLAGS="$CFLAGS -I$with_usb/include"
-    CXXFLAGS="$CXXFLAGS -I$with_usb/include"
-    CPPFLAGS="$CPPFLAGS -I$with_usb/include"
-    LIBS="$LIBS -L$with_usb/lib"
-  fi
-fi
-
-AC_CHECK_HEADER([usb.h])
-AC_CHECK_LIB([usb], [usb_init])
-
-if test "$ac_cv_header_usb_h" == no; then
-  AC_MSG_WARN([Missing libusb])
+AC_LIB_HAVE_LINKFLAGS(usb,, [#include <usb.h>], [usb_init()])
+if test "$ac_cv_libusb" != yes; then
+   AC_MSG_ERROR([libusb not found, please install usb.h and libusb.so])
 fi
 
 AC_LIB_HAVE_LINKFLAGS(yubikey,, [#include <yubikey.h>],
@@ -87,6 +55,8 @@ if test "$ac_cv_libyubikey" != yes; then
    AC_MSG_ERROR([libyubikey not found, see http://code.google.com/p/yubico-c/])
 fi
 
-AC_CONFIG_SUBDIRS(yubikey-core)
-AC_CONFIG_FILES(Makefile)
+AC_CONFIG_FILES([
+  Makefile
+  ykcore/Makefile
+])
 AC_OUTPUT
diff --git a/ykcore/Makefile.am b/ykcore/Makefile.am
new file mode 100644 (file)
index 0000000..cb488db
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (c) 2008, 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.
+
+noinst_LTLIBRARIES = libykcore.la
+libykcore_la_SOURCES = ykdef.h ykcore.h ykcore_backend.h ykcore.c \
+       ykstatus.h ykstatus.c
+libykcore_la_LIBADD = $(LTLIBYUBIKEY)
+EXTRA_DIST = ykcore_libusb.c ykcore_win32.c
diff --git a/ykcore/ykcore.c b/ykcore/ykcore.c
new file mode 100644 (file)
index 0000000..e35fa6b
--- /dev/null
@@ -0,0 +1,305 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Copyright (c) 2008, 2009, 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.
+ */
+
+#include "ykcore.h"
+#include "ykdef.h"
+#include "ykcore_backend.h"
+
+/* Include platform-specific backends for the USB routines */
+#ifdef _WIN32
+# include "ykcore_win32.c"
+#elif defined(__APPLE__)
+# include "ykcore_osx.c"
+#else
+# include "ykcore_libusb.c"
+#endif
+
+#include <yubikey.h>
+
+int yk_init(void)
+{
+       _ykusb_start();
+}
+
+int yk_release(void)
+{
+       _ykusb_start();
+}
+
+YUBIKEY *yk_open_first_key(void)
+{
+       struct usb_bus *bus;
+       struct usb_device *dev;
+       YUBIKEY *yk = _ykusb_open_device(YUBICO_VID, YUBIKEY_PID);
+       int rc = yk_errno;
+
+       if (yk) {
+               STATUS st;
+
+               if (!yk_get_status(yk, &st)) {
+                       rc = yk_errno;
+                       yk_close_key(yk);
+                       yk = NULL;
+               } else {
+                       if (!(st.versionMajor == 1 && st.versionMinor == 3)) {
+                               rc = YK_EFIRMWARE;
+                               yk_close_key(yk);
+                               yk = NULL;
+                       }
+               }
+       }
+       yk_errno = rc;
+       return yk;
+}
+
+int yk_close_key(YUBIKEY *yk)
+{
+       return _ykusb_close_device(yk);
+}
+
+int yk_get_status(YUBIKEY *k, STATUS *status)
+{
+       unsigned int status_count = 0;
+
+       if (!yk_read_from_key(k, 0, status, sizeof(STATUS), &status_count))
+               return 0;
+
+       if (status_count != sizeof(STATUS)) {
+               yk_errno = YK_EWRONGSIZ;
+               return 0;
+       }
+
+       status->touchLevel = endian_swap_16(status->touchLevel);
+
+       return 1;
+}
+
+int yk_write_config(YUBIKEY *yk, CONFIG *cfg, unsigned char *acc_code)
+{
+       unsigned char buf[sizeof(CONFIG) + ACC_CODE_SIZE];
+       STATUS stat;
+       int seq;
+
+       /* Get current seqence # from status block */
+
+       if (!yk_get_status(yk, &stat /*, 0*/))
+               return 0;
+
+       seq = stat.pgmSeq;
+
+       /* Update checksum and insert config block in buffer if present */
+
+       memset(buf, 0, sizeof(buf));
+
+       if (cfg) {
+               cfg->crc = ~yubikey_crc16 ((unsigned char *) cfg,
+                                          sizeof(CONFIG) - sizeof(cfg->crc));
+               cfg->crc = endian_swap_16(cfg->crc);
+               memcpy(buf, cfg, sizeof(CONFIG));
+       }
+
+       /* Append current access code if present */
+
+       if (acc_code)
+               memcpy(buf + sizeof(CONFIG), acc_code, ACC_CODE_SIZE);
+
+       /* Write to Yubikey */
+
+       if (!yk_write_to_key(yk, SLOT_CONFIG, buf, sizeof(buf)))
+               return 0;
+
+       /* Verify update */
+
+       if (!yk_get_status(yk, &stat /*, 0*/))
+               return 0;
+
+       yk_errno = YK_EWRITEERR;
+       if (cfg) {
+               return stat.pgmSeq != seq;
+       }
+
+       return stat.pgmSeq == 0;
+
+}
+
+/* As soon as we find a way to safely detect if we're in a threaded environment
+   or not, this should be changed to support per-thread locations.  Until then,
+   we only support non-threaded applications. */
+static int _yk_errno = 0;
+
+int * const _yk_errno_location(void)
+{
+       return &_yk_errno;
+}
+
+static const char *errtext[] = {
+       "",
+       "USB error",
+       "wrong size",
+       "write error",
+       "timeout",
+       "no yubikey present",
+       "unsupported firmware version",
+       "out of memory",
+       "no status structure given",
+       "not yet implemented"
+};
+const char *yk_strerror(int errnum)
+{
+       if (errnum < sizeof(errtext)/sizeof(errtext[0]))
+               return errtext[errnum];
+       return NULL;
+}
+const char *yk_usb_strerror()
+{
+       return _ykusb_strerror();
+}
+
+/* Note: we currently have no idea whatsoever how to read things larger
+   than FEATURE_RPT_SIZE - 1.  We also have no idea what to do with the
+   slot parameter, it currently is there for future purposes only. */
+int yk_read_from_key(YUBIKEY *yk, uint8_t slot,
+                    void *buf, unsigned int bufsize, unsigned int *bufcount)
+{
+       unsigned char data[FEATURE_RPT_SIZE];
+
+       if (bufsize > FEATURE_RPT_SIZE - 1) {
+               yk_errno = YK_EWRONGSIZ;
+               return 0;
+       }
+
+       memset(data, 0, sizeof(data));
+
+       if (!_ykusb_read(yk, REPORT_TYPE_FEATURE, 0, data, FEATURE_RPT_SIZE))
+               return 0;
+
+       /* This makes it apparent that there's some mysterious value in
+          the first byte...  I wonder what...  /Richard Levitte */
+       memcpy(buf, data + 1, bufsize); 
+       *bufcount = bufsize;
+
+       return 1;
+}
+
+int yk_write_to_key(YUBIKEY *yk, uint8_t slot, const void *buf, int bufcount)
+{
+       unsigned char repbuf[FEATURE_RPT_SIZE];
+       unsigned char data[SLOT_DATA_SIZE + FEATURE_RPT_SIZE];
+       int i, j, pos, part;
+
+       /* Insert data and set slot # */
+
+       memset(data, 0, sizeof(data));
+       memcpy(data, buf, bufcount);
+       data[SLOT_DATA_SIZE] = slot;
+
+       /* Append slot checksum */
+
+       i = yubikey_crc16 (data, SLOT_DATA_SIZE);
+       data[SLOT_DATA_SIZE + 1] = (unsigned char) (i & 0xff);
+       data[SLOT_DATA_SIZE + 2] = (unsigned char) (i >> 8);
+
+       /* Chop up the data into parts that fits into the payload of a
+          feature report. Set the part number | 0x80 in the end
+          of the feature report. When the Yubikey has processed it,
+          it will clear this byte, signaling that the next part can be
+          sent */
+
+       for (pos = 0, part = 0x80; pos < (SLOT_DATA_SIZE + 4); part++) {
+
+               /* Ignore parts that are all zeroes except first and last
+                  to speed up the transfer */
+
+               for (i = j = 0; i < (FEATURE_RPT_SIZE - 1); i++)
+                       if (repbuf[i] = data[pos++]) j = 1;
+               if (!j && (part > 0x80) && (pos < SLOT_DATA_SIZE))
+                       continue;
+
+               repbuf[i] = part;
+
+               if (!_ykusb_write(yk, REPORT_TYPE_FEATURE, 0,
+                                   repbuf, FEATURE_RPT_SIZE))
+                       return 0;
+
+               /* When the last byte in the feature report is cleared by
+                  the Yubikey, the next part can be sent */
+
+               for (i = 0; i < 50; i++) {
+                       memset(repbuf, 0, sizeof(repbuf));
+                       if (!_ykusb_read(yk, REPORT_TYPE_FEATURE, 0,
+                                           repbuf, FEATURE_RPT_SIZE))
+                               return 0;
+                       if (!repbuf[FEATURE_RPT_SIZE - 1])
+                               break;
+                       Sleep(10);
+               }
+
+               /* If timeout, something has gone wrong */
+
+               if (i >= 50) {
+                       yk_errno = YK_ETIMEOUT;
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+int yk_force_key_update(YUBIKEY *yk)
+{
+       unsigned char buf[FEATURE_RPT_SIZE];
+
+       memset(buf, 0, sizeof(buf));
+       buf[FEATURE_RPT_SIZE - 1] = 0x8a; /* Invalid partition = update only */
+       if (!_ykusb_write(yk, REPORT_TYPE_FEATURE, 0, buf, FEATURE_RPT_SIZE))
+               return 0;
+
+       return 1;
+}
+
+uint16_t endian_swap_16(uint16_t x)
+{
+       static int testflag = -1;
+
+       if (testflag == -1) {
+               uint16_t testword = 0x0102;
+               unsigned char *testchars = (unsigned char *)&testword;
+               if (*testchars == '\1')
+                       testflag = 1; /* Big endian arch, swap needed */
+               else
+                       testflag = 0; /* Little endian arch, no swap needed */
+       }
+
+       if (testflag)
+               x = (x >> 8) | ((x & 0xff) << 8);
+
+       return x;
+}
+
diff --git a/ykcore/ykcore.h b/ykcore/ykcore.h
new file mode 100644 (file)
index 0000000..702c8f7
--- /dev/null
@@ -0,0 +1,154 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Copyright (c) 2008, 2009, 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.
+ */
+
+#ifndef        __YKCORE_H_INCLUDED__
+#define        __YKCORE_H_INCLUDED__
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/*************************************************************************
+ **
+ ** N O T E :  For all functions that return a value, 0 och NULL indicates
+ ** an error, other values indicate success.
+ **
+ ************************************************************************/
+
+/*************************************************************************
+ *
+ * Structures used.  They are further defined in ykdef.h
+ *
+ ****/
+
+typedef struct yubikey_st YUBIKEY;     /* Really a USB device handle. */
+typedef struct status_st STATUS;       /* Status structure,
+                                          filled by yk_get_status(). */
+
+typedef struct ticket_st TICKET;       /* Ticket structure... */
+typedef struct config_st CONFIG;       /* Configuration structure.
+                                          Other libraries provide access. */
+typedef struct nav_st NAV;             /* Navigation structure.
+                                          Other libraries provide access. */
+
+/*************************************************************************
+ *
+ * Library initialisation functions.
+ *
+ ****/
+extern int yk_init(void);
+extern int yk_release(void);
+
+/*************************************************************************
+ *
+ * Functions to get and release the key itself.
+ *
+ ****/
+extern YUBIKEY *yk_open_first_key(void);       /* opens the first key available */
+extern int yk_close_key(YUBIKEY *k);           /* closes a previously opened key */
+
+/*************************************************************************
+ *
+ * Functions to get data from the key.
+ *
+ ****/
+/* fetches key status into the structure given by `status' */
+extern int yk_get_status(YUBIKEY *k, STATUS *status /*, int forceUpdate */);
+
+/*************************************************************************
+ *
+ * Functions to write data to the key.
+ *
+ ****/
+
+/* writes the given configuration to the key.  If the configuration is NULL,
+   zap the key configuration.
+   acc_code has to be provided of the key has a protecting access code. */
+extern int yk_write_config(YUBIKEY *k, CONFIG *cfg, unsigned char *acc_code);
+
+/*************************************************************************
+ *
+ * Error handling fuctions
+ *
+ ****/
+extern int * const _yk_errno_location(void);
+#define yk_errno (*_yk_errno_location())
+const char *yk_strerror(int errnum);
+/* The following function is only useful if yk_errno == YK_EUSBERR and
+   no other USB-related operations have been performed since the time of
+   error.  */
+const char *yk_usb_strerror();
+
+#define YK_EUSBERR     0x01    /* USB error reporting should be used */
+#define YK_EWRONGSIZ   0x02
+#define YK_EWRITEERR   0x03
+#define YK_ETIMEOUT    0x04
+#define YK_ENOKEY      0x05
+#define YK_EFIRMWARE   0x06
+#define YK_ENOMEM      0x07
+#define YK_ENOSTATUS   0x07
+#define YK_ENOTYETIMPL 0x08
+
+/*=======================================================================*
+
+/*************************************************************************
+ **
+ ** = = = = = = = = =   B I G   F A T   W A R N I N G   = = = = = = = = =
+ **
+ ** DO NOT USE THE FOLLOWING FUCTIONS DIRECTLY UNLESS YOU WRITE CORE ROUTINES!
+ **
+ ** These functions are declared here only to make sure they get defined
+ ** correctly internally.
+ **
+ ** YOU HAVE BEEN WARNED!
+ **
+ ****/
+
+/*************************************************************************
+ *
+ * Functions to send and receive data to/from the key.
+ *
+ ****/
+extern int yk_read_from_key(YUBIKEY *k, uint8_t slot,
+                           void *buf, unsigned int bufsize,
+                           unsigned int *bufcount);
+extern int yk_write_to_key(YUBIKEY *k, uint8_t slot,
+                          const void *buf, int bufcount);
+
+/*************************************************************************
+ *
+ * Internal helper functions
+ *
+ ****/
+
+/* Swaps the two bytes between little and big endian on big endian machines */
+extern uint16_t endian_swap_16(uint16_t x);
+
+#endif /* __YKCORE_H_INCLUDED__ */
diff --git a/ykcore/ykcore_backend.h b/ykcore/ykcore_backend.h
new file mode 100644 (file)
index 0000000..7a01525
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Written by Richard Levitte <richar@levitte.org>
+ * Copyright (c) 2008, 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.
+ */
+
+#ifndef        __YKCORE_BACKEND_H_INCLUDED__
+#define        __YKCORE_BACKEND_H_INCLUDED__
+
+#define        FEATURE_RPT_SIZE                8
+
+#define        REPORT_TYPE_FEATURE             0x03
+
+int _ykusb_start(void);
+int _ykusb_stop(void);
+
+void * _ykusb_open_device(int vendor_id, int product_id);
+int _ykusb_close_device(void *);
+
+int _ykusb_read(void *dev, int report_type, int report_number,
+               char *buffer, int buffer_size);
+int _ykusb_write(void *dev, int report_type, int report_number,
+                char *buffer, int buffer_size);
+
+const char *_ykusb_strerror();
+
+#endif /* __YKCORE_BACKEND_H_INCLUDED__ */
diff --git a/ykcore/ykcore_libusb.c b/ykcore/ykcore_libusb.c
new file mode 100644 (file)
index 0000000..144422d
--- /dev/null
@@ -0,0 +1,186 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Copyright (c) 2008, 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.
+ */
+
+#include <usb.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ykcore_backend.h"
+
+#ifndef _WIN32
+#define Sleep(x) usleep((x)*1000)
+#endif
+
+#define HID_GET_REPORT                 0x01
+#define HID_SET_REPORT                 0x09
+
+/*************************************************************************
+ **  function _ykusb_write                                             **
+ **  Set HID report                                                    **
+ **                                                                    **
+ **  int _ykusb_write(YUBIKEY *yk, int report_type, int report_number, **
+ **                    char *buffer, int size)                         **
+ **                                                                    **
+ **  Where:                                                            **
+ **  "yk" is handle to open Yubikey                                    **
+ **  "report_type" is HID report type (in, out or feature)             **
+ **  "report_number" is report identifier                              **
+ **  "buffer" is pointer to in buffer                                  **
+ **  "size" is size of the buffer                                      **
+ **                                                                    **
+ **  Returns: Nonzero if successful, zero otherwise                    **
+ **                                                                    **
+ *************************************************************************/
+
+int _ykusb_write(void *dev, int report_type, int report_number,
+                char *buffer, int size)
+{
+       int rc = usb_claim_interface((usb_dev_handle *)dev, 0);
+
+       if (rc >= 0) {
+               int rc2;
+               rc = usb_control_msg((usb_dev_handle *)dev,
+                                    USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_OUT,
+                                    HID_SET_REPORT,
+                                    report_type << 8 | report_number, 0,
+                                    buffer, size,
+                                    1000);
+               /* preserve a control message error over an interface
+                  release one */
+               rc2 = usb_release_interface((usb_dev_handle *)dev, 0);
+               if (rc >= 0 && rc2 < 0)
+                       rc = rc2;
+       }
+       if (rc >= 0)
+               return 1;
+       yk_errno = YK_EUSBERR;
+       return 0;
+}
+
+/*************************************************************************
+**  function _ykusb_read                                               **
+**  Get HID report                                                     **
+**                                                                      **
+**  int _ykusb_read(YUBIKEY *dev, int report_type, int report_number,  **
+**                    char *buffer, int size)                          **
+**                                                                      **
+**  Where:                                                              **
+**  "dev" is handle to open Yubikey                                    **
+**  "report_type" is HID report type (in, out or feature)              **
+**  "report_number" is report identifier                                       **
+**  "buffer" is pointer to in buffer                                   **
+**  "size" is size of the buffer                                       **
+**                                                                     **
+**  Returns: Number of bytes read. Zero if failure                     **
+**                                                                      **
+*************************************************************************/
+
+int _ykusb_read(void *dev, int report_type, int report_number,
+               char *buffer, int size)
+{
+       int rc = usb_claim_interface((usb_dev_handle *)dev, 0);
+
+       if (rc >= 0) {
+               int rc2;
+               rc = usb_control_msg((usb_dev_handle *)dev,
+                                    USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_IN,
+                                    HID_GET_REPORT,
+                                    report_type << 8 | report_number, 0,
+                                    buffer, size,
+                                    1000);
+               /* preserve a control message error over an interface
+                  release one */
+               rc2 = usb_release_interface((usb_dev_handle *)dev, 0);
+               if (rc >= 0 && rc2 < 0)
+                       rc = rc2;
+       }
+       if (rc >= 0)
+               return 1;
+       yk_errno = YK_EUSBERR;
+       return 0;
+}
+
+int _ykusb_start(void)
+{
+       int rc;
+       usb_init();
+
+       rc = usb_find_busses();
+       if (rc >= 0)
+               rc = usb_find_devices();
+
+       if (rc >= 0)
+               return 1;
+       yk_errno = YK_EUSBERR;
+       return 0;
+}
+
+extern int _ykusb_stop(void)
+{
+       return 1;
+}
+
+void *_ykusb_open_device(int vendor_id, int product_id)
+{
+       struct usb_bus *bus;
+       struct usb_device *dev;
+       struct usb_dev_handle *h = NULL;
+       int rc = YK_EUSBERR;
+
+       for (bus = usb_get_busses(); bus; bus = bus->next) {
+               rc = YK_ENOKEY;
+               for (dev = bus->devices; dev; dev = dev->next)
+                       if (dev->descriptor.idVendor == YUBICO_VID
+                           && dev->descriptor.idProduct == YUBIKEY_PID) {
+                               rc = YK_EUSBERR;
+                               h = usb_open(dev);
+                               goto done;
+                       }
+       }
+ done:
+       if (h == NULL)
+               yk_errno = rc;
+       return h;
+}
+
+int _ykusb_close_device(void *yk)
+{
+       int rc = usb_close((usb_dev_handle *) yk);
+
+       if (rc >= 0)
+               return 1;
+       yk_errno = YK_EUSBERR;
+       return 0;
+}
+
+const char *_ykusb_strerror()
+{
+       return usb_strerror();
+}
diff --git a/ykcore/ykcore_osx.c b/ykcore/ykcore_osx.c
new file mode 100644 (file)
index 0000000..2a92c1c
--- /dev/null
@@ -0,0 +1,4 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/* Please implement this.  Have a look at ykcore_libusb.c or some other
+   already implemented backend for inspiration. */
+#include "ykcore_stub.c"
diff --git a/ykcore/ykcore_stub.c b/ykcore/ykcore_stub.c
new file mode 100644 (file)
index 0000000..7cf99fd
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Copyright (c) 2008, 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.
+ */
+
+#error "To be implemented!"
+
+int _ykusb_start(void)
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return 0;
+}
+
+int _ykusb_stop(void)
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return 0;
+}
+
+void * _ykusb_open_device(int vendor_id, int product_id)
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return NULL;
+}
+
+int _ykusb_close_device(void *)
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return 0;
+}
+
+int _ykusb_read(void *dev, int report_type, int report_number,
+               char *buffer, int buffer_size)
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return 0;
+}
+
+int _ykusb_write(void *dev, int report_type, int report_number,
+                char *buffer, int buffer_size)
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return 0;
+}
+
+const char *_ykusb_strerror()
+{
+       yk_errno = YK_ENOTYETIMPL;
+       return 0;
+}
diff --git a/ykcore/ykcore_win32.c b/ykcore/ykcore_win32.c
new file mode 100644 (file)
index 0000000..2a92c1c
--- /dev/null
@@ -0,0 +1,4 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/* Please implement this.  Have a look at ykcore_libusb.c or some other
+   already implemented backend for inspiration. */
+#include "ykcore_stub.c"
diff --git a/ykcore/ykdef.h b/ykcore/ykdef.h
new file mode 100644 (file)
index 0000000..626b5bc
--- /dev/null
@@ -0,0 +1,129 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*****************************************************************************************
+**                                                                                     **
+**             Y K D E F  -  Common Yubikey project header                             **
+**                                                                                     **
+**             Date            / Rev           / Sign  / Remark                        **
+**             06-06-03        / 0.9.0         / J E   / Main                          **
+**             06-08-25        / 1.0.0         / J E   / Rewritten for final spec      **
+**             08-06-03        / 1.3.0         / J E   / Added static OTP feature      **
+**                                                                                     **
+*****************************************************************************************/
+
+#ifndef        __YKDEF_H_INCLUDED__
+#define        __YKDEF_H_INCLUDED__
+
+/* We need the structures defined here to be packed byte-wise */
+#if defined(_WIN32) || defined(__GNUC__)
+#pragma pack(push, 1)
+#endif
+
+/* USB Identity */
+
+#define        YUBICO_VID                              0x1050
+#define        YUBIKEY_PID                             0x0010
+
+/* Slot entries */
+
+#define        SLOT_CONFIG             1
+#define        SLOT_NAV                2
+
+#define        SLOT_DATA_SIZE          64
+
+/* Ticket structure */
+
+#define        UID_SIZE                6       /* Size of secret ID field */
+
+struct ticket_st {
+       unsigned char uid[UID_SIZE];    /* Unique (secret) ID */
+       unsigned short useCtr;          /* Use counter (incremented by 1 at first use after power up) + usage flag in msb */
+       unsigned short tstpl;           /* Timestamp incremented by approx 8Hz (low part) */
+       unsigned char tstph;            /* Timestamp (high part) */
+       unsigned char sessionCtr;       /* Number of times used within session. 0 for first use. After it wraps from 0xff to 1 */
+       unsigned short rnd;             /* Pseudo-random value */
+       unsigned short crc;             /* CRC16 value of all fields */
+};
+
+/* Activation modifier of sessionUse field (bitfields not uses as they are not portable) */
+
+#define        TICKET_ACT_HIDRPT       0x8000  /* Ticket generated at activation by keyboard (scroll/num/caps) */
+#define        TICKET_CTR_MASK         0x7fff  /* Mask for useCtr value (except HID flag) */
+
+/* Configuration structure */
+
+#define        FIXED_SIZE              16      /* Max size of fixed field */
+#define        KEY_SIZE                16      /* Size of AES key */
+#define        ACC_CODE_SIZE           6       /* Size of access code to re-program device */
+
+struct config_st {
+       unsigned char fixed[FIXED_SIZE];/* Fixed data in binary format */
+       unsigned char uid[UID_SIZE];    /* Fixed UID part of ticket */
+       unsigned char key[KEY_SIZE];    /* AES key */
+       unsigned char accCode[ACC_CODE_SIZE]; /* Access code to re-program device */
+       unsigned char fixedSize;        /* Number of bytes in fixed field (0 if not used) */
+       unsigned char pgmSeq;           /* Program sequence number (ignored at programming - updated by firmware) */
+       unsigned char tktFlags;         /* Ticket configuration flags */
+       unsigned char cfgFlags;         /* General configuration flags */
+       unsigned short ctrOffs;         /* Counter offset value (ignored at programming - updated by firmware) */
+       unsigned short crc;             /* CRC16 value of all fields */
+};
+
+/* Ticket flags */
+
+#define        TKTFLAG_TAB_FIRST       0x01    /* Send TAB before first part */
+#define        TKTFLAG_APPEND_TAB1     0x02    /* Send TAB after first part */
+#define        TKTFLAG_APPEND_TAB2     0x04    /* Send TAB after second part */
+#define        TKTFLAG_APPEND_DELAY1   0x08    /* Add 0.5s delay after first part */
+#define        TKTFLAG_APPEND_DELAY2   0x10    /* Add 0.5s delay after second part */
+#define        TKTFLAG_APPEND_CR       0x20    /* Append CR as final character */
+
+/* Configuration flags */
+
+#define CFGFLAG_SEND_REF       0x01    /* Send reference string (0..F) before data */
+#define        CFGFLAG_TICKET_FIRST    0x02    /* Send ticket first (default is fixed part) */
+#define CFGFLAG_PACING_10MS    0x04    /* Add 10ms intra-key pacing */
+#define CFGFLAG_PACING_20MS    0x08    /* Add 20ms intra-key pacing */
+#define CFGFLAG_ALLOW_HIDTRIG  0x10    /* Allow trigger through HID/keyboard */
+#define CFGFLAG_STATIC_TICKET  0x20    /* Static ticket generation */
+
+/* Navigation */
+
+#define        MAX_URL                 48
+
+struct nav_st {
+       unsigned char scancode[MAX_URL];/* Scancode (lower 7 bits) */
+       unsigned char scanmod[MAX_URL >> 2];    /* Modifier fields (packed 2 bits each) */
+       unsigned char flags;            /* NAVFLAG_xxx flags */
+       unsigned char filler;           /* Filler byte */
+       unsigned short crc;             /* CRC16 value of all fields */
+};
+
+#define        SCANMOD_SHIFT           0x80    /* Highest bit in scancode */
+#define        SCANMOD_ALT_GR          0x01    /* Lowest bit in mod */
+#define        SCANMOD_WIN             0x02    /* WIN key */
+
+/* Navigation flags */
+
+#define        NAVFLAG_INSERT_TRIG     0x01    /* Automatic trigger when device is inserted */
+#define NAVFLAG_APPEND_TKT     0x02    /* Append ticket to URL */
+#define        NAVFLAG_DUAL_KEY_USAGE  0x04    /* Dual usage of key: Short = ticket  Long = Navigate */
+
+/* Status block */
+
+struct status_st {
+       unsigned char versionMajor;     /* Firmware version information */
+       unsigned char versionMinor;
+       unsigned char versionBuild;
+       unsigned char pgmSeq;           /* Programming sequence number. 0 if no valid configuration */
+       unsigned short touchLevel;      /* Level from touch detector */
+};
+
+/* Modified hex string mapping */
+
+#define        MODHEX_MAP              "cbdefghijklnrtuv"
+
+#if defined(_WIN32) || defined(__GNUC__)
+#pragma pack(pop)
+#endif
+
+#endif /* __YKDEF_H_INCLUDED__ */
diff --git a/ykcore/ykstatus.c b/ykcore/ykstatus.c
new file mode 100644 (file)
index 0000000..7f11bda
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Written by Richard Levitte <richard@levitte.org>
+ * Copyright (c) 2008, 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.
+ */
+
+#include "ykdef.h"
+#include "ykstatus.h"
+
+STATUS *ykds_alloc(void)
+{
+       STATUS *st = malloc(sizeof(STATUS));
+       if (!st) {
+               yk_errno = YK_ENOMEM;
+       }
+       return st;
+}
+
+void ykds_free(STATUS *st)
+{
+       free(st);
+}
+
+STATUS *ykds_static(void)
+{
+       static STATUS st;
+       return &st;
+}
+
+extern int ykds_version_major(const STATUS *st)
+{
+       if (st)
+               return st->versionMajor;
+       yk_errno = YK_ENOSTATUS;
+       return 0;
+}
+extern int ykds_version_minor(const STATUS *st)
+{
+       if (st)
+               return st->versionMinor;
+       yk_errno = YK_ENOSTATUS;
+       return 0;
+}
+extern int ykds_version_build(const STATUS *st)
+{
+       if (st)
+               return st->versionBuild;
+       yk_errno = YK_ENOSTATUS;
+       return 0;
+}
+extern int ykds_pgm_seq(const STATUS *st)
+{
+       if (st)
+               return st->pgmSeq;
+       yk_errno = YK_ENOSTATUS;
+       return 0;
+}
+extern int ykds_touch_level(const STATUS *st)
+{
+       if (st)
+               return st->touchLevel;
+       yk_errno = YK_ENOSTATUS;
+       return 0;
+}
diff --git a/ykcore/ykstatus.h b/ykcore/ykstatus.h
new file mode 100644 (file)
index 0000000..5e80cc8
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Written by Richard Levitte <richard@levitte.org>
+ * Copyright (c) 2008, 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.
+ */
+
+#ifndef        __YKDATA_H_INCLUDED__
+#define        __YKDATA_H_INCLUDED__
+
+#include "ykcore.h"
+
+/* Allocate and free status structures */
+extern STATUS *ykds_alloc(void);
+extern void ykds_free(STATUS *st);
+
+/* Return static status structure, to be used for quick checks.
+   USE WITH CAUTION, as this is a SHARED OBJECT. */
+extern STATUS *ykds_static(void);
+
+/* Accessor functions */
+extern int ykds_version_major(const STATUS *st);
+extern int ykds_version_minor(const STATUS *st);
+extern int ykds_version_build(const STATUS *st);
+extern int ykds_pgm_seq(const STATUS *st);
+extern int ykds_touch_level(const STATUS *st);
+
+#endif /* __YKDATA_H_INCLUDED__ */