├── README.adoc ├── CMakeLists.txt ├── u2f-host ├── config.h.cmake.in ├── u2f-host.pc.in ├── u2f-host.map ├── b64 │ ├── cdecode.h │ └── cencode.h ├── global.c ├── version.c ├── u2f-host-types.h ├── Makefile.am ├── internal.h ├── u2f-host-version.h.in ├── u2f-host.h ├── error.c ├── CMakeLists.txt ├── cencode.c ├── cdecode.c ├── inc │ ├── u2f.h │ └── u2f_hid.h ├── register.c └── authenticate.c ├── THANKS ├── AUTHORS ├── autogen.sh ├── gl ├── .gitignore ├── m4 │ ├── .gitignore │ ├── sha256.m4 │ ├── off_t.m4 │ ├── strverscmp.m4 │ ├── sys_types_h.m4 │ ├── ssize_t.m4 │ ├── wchar_t.m4 │ ├── gnulib-tool.m4 │ ├── ld-version-script.m4 │ ├── stddef_h.m4 │ ├── gl-openssl.m4 │ ├── multiarch.m4 │ ├── gnulib-cache.m4 │ ├── 00gnulib.m4 │ ├── warn-on-use.m4 │ ├── stdalign.m4 │ ├── warnings.m4 │ ├── extern-inline.m4 │ ├── absolute-header.m4 │ ├── onceonly.m4 │ ├── longlong.m4 │ ├── extensions.m4 │ ├── string_h.m4 │ └── manywarnings.m4 ├── check-version.h ├── check-version.c ├── sys_types.in.h ├── stddef.in.h ├── sha256.h ├── gl_openssl.h ├── strverscmp.c └── stdalign.in.h ├── BLURB ├── .travis.yml ├── tests ├── Makefile.am └── basic.c ├── .github └── workflows │ └── scan.yml ├── gtk-doc ├── u2f-host-docs.xml └── Makefile.am ├── src ├── cmdline.ggo ├── Makefile.am └── u2f-host.c ├── doc └── Mode_switch_YubiKey.adoc ├── cfg.mk ├── .gitignore ├── Makefile.am ├── windows.mk ├── macosx.mk ├── NEWS ├── u2f.conf.sample ├── m4 └── gtk-doc.m4 ├── 70-u2f.rules ├── GNUmakefile └── configure.ac /README.adoc: -------------------------------------------------------------------------------- 1 | README -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(libu2f-host) 2 | cmake_minimum_required(VERSION 3.0) 3 | 4 | add_subdirectory(u2f-host) 5 | -------------------------------------------------------------------------------- /u2f-host/config.h.cmake.in: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H_ 2 | #define _CONFIG_H_ 3 | 4 | #cmakedefine HAVE_STDINT_H 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2014 Yubico AB. Licensed under GPLv3+. 2 | 3 | Some public-domain Base64 code is taken from the libb64 project. 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2014 Yubico AB. Licensed under GPLv3+. 2 | 3 | Klas Lindfors 4 | Rewrite for HIDAPI/U2Fv2. 5 | 6 | Simon Josefsson 7 | Initial framework and WinUSB/U2Fv0. 8 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | 6 | main() { 7 | autoreconf --install 8 | } 9 | 10 | pushd "$DIR" &>/dev/null 11 | main "$@" 12 | popd &>/dev/null 13 | -------------------------------------------------------------------------------- /gl/.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.am 2 | /check-version.c 3 | /check-version.h 4 | /gl_openssl.h 5 | /sha256.c 6 | /sha256.h 7 | /stdalign.in.h 8 | /stddef.in.h 9 | /stdint.in.h 10 | /string.in.h 11 | /strverscmp.c 12 | /sys_types.in.h 13 | -------------------------------------------------------------------------------- /BLURB: -------------------------------------------------------------------------------- 1 | Author: Yubico 2 | Basename: libu2f-host 3 | Homepage: https://developers.yubico.com/libu2f-host/ 4 | License: GPL-3.0+ 5 | Name: libu2f-host 6 | Project: libu2f-host 7 | Summary: Yubico Universal 2nd Factor (U2F) Host C Library 8 | Travis: https://travis-ci.org/Yubico/libu2f-host 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang 5 | before_install: 6 | - sudo apt-get update -qq 7 | - sudo apt-get install -qq -y gengetopt help2man $EXTRA 8 | env: 9 | - EXTRA="libjson0-dev libudev-dev libusb-1.0-0-dev" 10 | script: 11 | - ./build-aux/travis 12 | -------------------------------------------------------------------------------- /u2f-host/u2f-host.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: Libu2f-host 7 | Description: Yubico Universal 2nd Factor (U2F) Host C Library 8 | URL: http://www.yubico.com/ 9 | Version: @VERSION@ 10 | Libs: -L${libdir} -lu2f-host 11 | Cflags: -I${includedir}/u2f-host 12 | -------------------------------------------------------------------------------- /gl/m4/.gitignore: -------------------------------------------------------------------------------- 1 | /00gnulib.m4 2 | /absolute-header.m4 3 | /extensions.m4 4 | /extern-inline.m4 5 | /gl-openssl.m4 6 | /gnulib-common.m4 7 | /gnulib-comp.m4 8 | /gnulib-tool.m4 9 | /include_next.m4 10 | /longlong.m4 11 | /manywarnings.m4 12 | /multiarch.m4 13 | /off_t.m4 14 | /onceonly.m4 15 | /sha256.m4 16 | /ssize_t.m4 17 | /stdalign.m4 18 | /stddef_h.m4 19 | /stdint.m4 20 | /string_h.m4 21 | /strverscmp.m4 22 | /sys_types_h.m4 23 | /warn-on-use.m4 24 | /warnings.m4 25 | /wchar_t.m4 26 | /ld-version-script.m4 27 | -------------------------------------------------------------------------------- /gl/m4/sha256.m4: -------------------------------------------------------------------------------- 1 | # sha256.m4 serial 8 2 | dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | AC_DEFUN([gl_SHA256], 8 | [ 9 | dnl Prerequisites of lib/sha256.c. 10 | AC_REQUIRE([gl_BIGENDIAN]) 11 | 12 | dnl Determine HAVE_OPENSSL_SHA256 and LIB_CRYPTO 13 | gl_CRYPTO_CHECK([SHA256]) 14 | ]) 15 | -------------------------------------------------------------------------------- /gl/m4/off_t.m4: -------------------------------------------------------------------------------- 1 | # off_t.m4 serial 1 2 | dnl Copyright (C) 2012-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl Check whether to override the 'off_t' type. 8 | dnl Set WINDOWS_64_BIT_OFF_T. 9 | 10 | AC_DEFUN([gl_TYPE_OFF_T], 11 | [ 12 | m4_ifdef([gl_LARGEFILE], [ 13 | AC_REQUIRE([gl_LARGEFILE]) 14 | ], [ 15 | WINDOWS_64_BIT_OFF_T=0 16 | ]) 17 | AC_SUBST([WINDOWS_64_BIT_OFF_T]) 18 | ]) 19 | -------------------------------------------------------------------------------- /gl/m4/strverscmp.m4: -------------------------------------------------------------------------------- 1 | # strverscmp.m4 serial 8 2 | dnl Copyright (C) 2002, 2005-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | AC_DEFUN([gl_FUNC_STRVERSCMP], 8 | [ 9 | dnl Persuade glibc to declare strverscmp(). 10 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 11 | 12 | AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) 13 | AC_CHECK_FUNCS([strverscmp]) 14 | if test $ac_cv_func_strverscmp = no; then 15 | HAVE_STRVERSCMP=0 16 | fi 17 | ]) 18 | 19 | # Prerequisites of lib/strverscmp.c. 20 | AC_DEFUN([gl_PREREQ_STRVERSCMP], [ 21 | : 22 | ]) 23 | -------------------------------------------------------------------------------- /gl/m4/sys_types_h.m4: -------------------------------------------------------------------------------- 1 | # sys_types_h.m4 serial 5 2 | dnl Copyright (C) 2011-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | AC_DEFUN_ONCE([gl_SYS_TYPES_H], 8 | [ 9 | AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS]) 10 | gl_NEXT_HEADERS([sys/types.h]) 11 | 12 | dnl Ensure the type pid_t gets defined. 13 | AC_REQUIRE([AC_TYPE_PID_T]) 14 | 15 | dnl Ensure the type mode_t gets defined. 16 | AC_REQUIRE([AC_TYPE_MODE_T]) 17 | 18 | dnl Whether to override the 'off_t' type. 19 | AC_REQUIRE([gl_TYPE_OFF_T]) 20 | ]) 21 | 22 | AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS], 23 | [ 24 | ]) 25 | -------------------------------------------------------------------------------- /gl/m4/ssize_t.m4: -------------------------------------------------------------------------------- 1 | # ssize_t.m4 serial 5 (gettext-0.18.2) 2 | dnl Copyright (C) 2001-2003, 2006, 2010-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Bruno Haible. 8 | dnl Test whether ssize_t is defined. 9 | 10 | AC_DEFUN([gt_TYPE_SSIZE_T], 11 | [ 12 | AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t], 13 | [AC_COMPILE_IFELSE( 14 | [AC_LANG_PROGRAM( 15 | [[#include ]], 16 | [[int x = sizeof (ssize_t *) + sizeof (ssize_t); 17 | return !x;]])], 18 | [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])]) 19 | if test $gt_cv_ssize_t = no; then 20 | AC_DEFINE([ssize_t], [int], 21 | [Define as a signed type of the same size as size_t.]) 22 | fi 23 | ]) 24 | -------------------------------------------------------------------------------- /gl/m4/wchar_t.m4: -------------------------------------------------------------------------------- 1 | # wchar_t.m4 serial 4 (gettext-0.18.2) 2 | dnl Copyright (C) 2002-2003, 2008-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Bruno Haible. 8 | dnl Test whether has the 'wchar_t' type. 9 | dnl Prerequisite: AC_PROG_CC 10 | 11 | AC_DEFUN([gt_TYPE_WCHAR_T], 12 | [ 13 | AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t], 14 | [AC_COMPILE_IFELSE( 15 | [AC_LANG_PROGRAM( 16 | [[#include 17 | wchar_t foo = (wchar_t)'\0';]], 18 | [[]])], 19 | [gt_cv_c_wchar_t=yes], 20 | [gt_cv_c_wchar_t=no])]) 21 | if test $gt_cv_c_wchar_t = yes; then 22 | AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.]) 23 | fi 24 | ]) 25 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, eithe version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | AM_CFLAGS = $(WARN_CFLAGS) 17 | AM_CPPFLAGS=-I$(top_srcdir)/u2f-host -I$(top_builddir) -I$(top_builddir)/u2f-host 18 | 19 | AM_LDFLAGS = -no-install 20 | LDADD = ../u2f-host/libu2f-host.la 21 | 22 | check_PROGRAMS = basic 23 | TESTS = $(check_PROGRAMS) 24 | -------------------------------------------------------------------------------- /gl/check-version.h: -------------------------------------------------------------------------------- 1 | /* check-version.h --- Check version string compatibility. 2 | Copyright (C) 2005, 2009-2015 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . */ 16 | 17 | /* Written by Simon Josefsson. */ 18 | 19 | #ifndef CHECK_VERSION_H 20 | # define CHECK_VERSION_H 21 | 22 | extern const char * 23 | check_version (const char *req_version); 24 | 25 | #endif /* CHECK_VERSION_H */ 26 | -------------------------------------------------------------------------------- /.github/workflows/scan.yml: -------------------------------------------------------------------------------- 1 | name: static code analysis 2 | # Documentation: https://github.com/Yubico/yes-static-code-analysis 3 | 4 | on: 5 | push: 6 | schedule: 7 | - cron: '0 0 * * 1' 8 | 9 | env: 10 | SCAN_IMG: 11 | yubico-yes-docker-local.jfrog.io/static-code-analysis/c:v1 12 | SECRET: ${{ secrets.ARTIFACTORY_READER_TOKEN }} 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@master 20 | 21 | - name: Scan and fail on warnings 22 | run: | 23 | if [ "${SECRET}" != "" ]; then 24 | docker login yubico-yes-docker-local.jfrog.io/ \ 25 | -u svc-static-code-analysis-reader -p ${SECRET} 26 | docker pull ${SCAN_IMG} 27 | docker run -v${PWD}:/k -e COMPILE_DEPS="${COMPILE_DEPS}" \ 28 | -e PROJECT_NAME=${GITHUB_REPOSITORY#Yubico/} \ 29 | -e PVS_IGNORE_WARNINGS=${PVS_IGNORE_WARNINGS} -t ${SCAN_IMG} 30 | else 31 | echo "No docker registry credentials, not scanning" 32 | fi 33 | 34 | - uses: actions/upload-artifact@master 35 | if: failure() 36 | with: 37 | name: suppression_files 38 | path: suppression_files 39 | -------------------------------------------------------------------------------- /gtk-doc/u2f-host-docs.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | ]> 7 | 8 | 9 | Yubico Universal 2nd Factor C Library 10 | 11 | The latest version of this documentation can be found on-line at 12 | 13 | https://github.com/Yubico/libu2f-host. 14 | 15 | 16 | 17 | 18 | Yubico Universal 2nd Factor C Library 19 | 20 | 21 | This is a C library that implements the host-side of the U2F 22 | protocol. More precisely, it provides an API for applications 23 | that wishes to talk to a U2F device and perform the U2F Register 24 | and U2F Authenticate operations. 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/cmdline.ggo: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | package "u2f-host" 17 | purpose "Perform U2F host-side operations on the command line. Reads challenge from standard input and writes a response to standard output." 18 | 19 | option "origin" o "Origin URL to use." string optional 20 | option "action" a "Action to take." values="register","authenticate","sendrecv" enum 21 | option "touch" t "Invert user-presence flag (on by default)" flag off 22 | option "debug" d "Print debug information to standard error" flag off 23 | option "command" c "Command for sendrecv action" string optional 24 | -------------------------------------------------------------------------------- /u2f-host/u2f-host.map: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | U2F_HOST_0.0 17 | { 18 | global: 19 | u2fh_check_version; 20 | u2fh_devs_discover; 21 | u2fh_devs_done; 22 | u2fh_devs_init; 23 | u2fh_get_device_description; 24 | u2fh_global_done; 25 | u2fh_global_init; 26 | u2fh_is_alive; 27 | u2fh_register; 28 | u2fh_sendrecv; 29 | u2fh_authenticate; 30 | u2fh_strerror; 31 | u2fh_strerror_name; 32 | 33 | local: 34 | *; 35 | }; 36 | 37 | U2F_HOST_1.1 38 | { 39 | global: 40 | u2fh_authenticate2; 41 | u2fh_register2; 42 | } U2F_HOST_0.0; 43 | -------------------------------------------------------------------------------- /doc/Mode_switch_YubiKey.adoc: -------------------------------------------------------------------------------- 1 | YubiKey Mode Switch 2 | ------------------- 3 | 4 | The YubiKey can be mode-switched from the U2F-only mode using 5 | libu2f-host by sending some non-standardized commands. 6 | 7 | echo -e '\x06\x00\x00\x00' | u2f-host -d -a sendrecv -c c0 8 | 9 | The '\x06' corresponds to mode 6 and the following modes are known: 10 | 11 | - 0 OTP device only. 12 | - 1 CCID device only. 13 | - 2 OTP/CCID composite device. 14 | - 3 U2F device only. 15 | - 4 OTP/U2F composite device. 16 | - 5 U2F/CCID composite device. 17 | - 6 OTP/U2F/CCID composite device. 18 | 19 | Add 80 to set MODE_FLAG_EJECT, for example: 81 is mode 1 (CCID-only) 20 | with MODE_FLAG_EJECT. To select another mode, replace \x06 with what 21 | you wish. For example, if you want to put the YubiKey into pure OTP-mode 22 | use the following: 23 | 24 | echo -e '\x01\x00\x00\x00' | u2f-host -d -a sendrecv -c c0 25 | 26 | For mode-switching in other modes (OTP, CCID or combo modes), we 27 | recommend the following libraries and command-line tools instead: 28 | 29 | For OTP-modes:: https://developers.yubico.com/yubikey-personalization[YubiKey Personalization] 30 | 31 | For CCID-modes:: https://developers.yubico.com/libykneomgr[YubiKey NEO CCID Manager C Library] 32 | 33 | If you prefer a GUI (for all modes):: https://developers.yubico.com/yubikey-neo-manager[YubiKey NEO Manager] 34 | -------------------------------------------------------------------------------- /u2f-host/b64/cdecode.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | /* 19 | cdecode.h - c header for a base64 decoding algorithm 20 | 21 | This is part of the libb64 project, and has been placed in the public domain. 22 | For details, see http://sourceforge.net/projects/libb64 23 | */ 24 | 25 | #ifndef BASE64_CDECODE_H 26 | #define BASE64_CDECODE_H 27 | 28 | typedef enum 29 | { 30 | step_a, step_b, step_c, step_d 31 | } base64_decodestep; 32 | 33 | typedef struct 34 | { 35 | base64_decodestep step; 36 | char plainchar; 37 | } base64_decodestate; 38 | 39 | void base64_init_decodestate (base64_decodestate * state_in); 40 | 41 | int base64_decode_value (char value_in); 42 | 43 | int base64_decode_block (const char *code_in, const int length_in, 44 | char *plaintext_out, base64_decodestate * state_in); 45 | 46 | #endif /* BASE64_CDECODE_H */ 47 | -------------------------------------------------------------------------------- /u2f-host/global.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | #include "internal.h" 20 | 21 | int debug; 22 | 23 | /** 24 | * u2fh_global_init: 25 | * @flags: initialization flags, ORed #u2fh_initflags. 26 | * 27 | * Initialize the library. This function is not guaranteed to be 28 | * thread safe and must be invoked on application startup. 29 | * 30 | * Returns: On success %U2FH_OK (integer 0) is returned, and on errors 31 | * an #u2fh_rc error code. 32 | */ 33 | u2fh_rc 34 | u2fh_global_init (u2fh_initflags flags) 35 | { 36 | if (flags & U2FH_DEBUG) 37 | debug = 1; 38 | 39 | return U2FH_OK; 40 | } 41 | 42 | /** 43 | * u2fh_global_done: 44 | * 45 | * Release all resources from the library. Call this function when no 46 | * further use of the library is needed. 47 | */ 48 | void 49 | u2fh_global_done (void) 50 | { 51 | debug = 0; 52 | } 53 | -------------------------------------------------------------------------------- /u2f-host/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "check-version.h" 22 | 23 | /** 24 | * u2fh_check_version: 25 | * @req_version: Required version number, or NULL. 26 | * 27 | * Check that the version of the library is at minimum the requested 28 | * one and return the version string; return NULL if the condition is 29 | * not satisfied. If a NULL is passed to this function, no check is 30 | * done, but the version string is simply returned. 31 | * 32 | * See %U2FH_VERSION_STRING for a suitable @req_version string. 33 | * 34 | * Return value: Version string of run-time library, or NULL if the 35 | * run-time library does not meet the required version number. 36 | */ 37 | const char * 38 | u2fh_check_version (const char *req_version) 39 | { 40 | return check_version (req_version); 41 | } 42 | -------------------------------------------------------------------------------- /u2f-host/b64/cencode.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | /* 19 | cencode.h - c header for a base64 encoding algorithm 20 | 21 | This is part of the libb64 project, and has been placed in the public domain. 22 | For details, see http://sourceforge.net/projects/libb64 23 | */ 24 | 25 | #ifndef BASE64_CENCODE_H 26 | #define BASE64_CENCODE_H 27 | 28 | typedef enum 29 | { 30 | step_A, step_B, step_C 31 | } base64_encodestep; 32 | 33 | typedef struct 34 | { 35 | base64_encodestep step; 36 | char result; 37 | int stepcount; 38 | } base64_encodestate; 39 | 40 | void base64_init_encodestate (base64_encodestate * state_in); 41 | 42 | char base64_encode_value (char value_in); 43 | 44 | int base64_encode_block (const char *plaintext_in, int length_in, 45 | char *code_out, base64_encodestate * state_in); 46 | 47 | int base64_encode_blockend (char *code_out, base64_encodestate * state_in); 48 | 49 | #endif /* BASE64_CENCODE_H */ 50 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | AM_CFLAGS = $(WARN_CFLAGS) 17 | AM_CPPFLAGS=-I$(top_srcdir)/u2f-host -I$(top_builddir) -I$(top_builddir)/u2f-host 18 | 19 | bin_PROGRAMS = u2f-host 20 | 21 | u2f_host_SOURCES = u2f-host.c 22 | u2f_host_LDADD = ../u2f-host/libu2f-host.la 23 | u2f_host_LDADD += libu2f_cmd.la 24 | 25 | noinst_LTLIBRARIES = libu2f_cmd.la 26 | libu2f_cmd_la_SOURCES = cmdline.ggo cmdline.c cmdline.h 27 | libu2f_cmd_la_CFLAGS = 28 | 29 | cmdline.c cmdline.h: cmdline.ggo Makefile.am 30 | gengetopt --no-handle-help --input $^ 31 | 32 | BUILT_SOURCES = cmdline.c cmdline.h 33 | MAINTAINERCLEANFILES = $(BUILT_SOURCES) 34 | 35 | dist_man_MANS = u2f-host.1 36 | DISTCLEANFILES = $(dist_man_MANS) 37 | 38 | u2f-host.1: $(srcdir)/u2f-host.c $(srcdir)/cmdline.ggo $(top_srcdir)/configure.ac | $(builddir)/u2f-host$(EXEEXT) 39 | $(AM_V_GEN)$(HELP2MAN) \ 40 | --output=$@ $(builddir)/u2f-host$(EXEEXT) \ 41 | --name="Yubico Universal 2nd Factor (U2F) Host Tool" \ 42 | --no-info 43 | -------------------------------------------------------------------------------- /gl/m4/gnulib-tool.m4: -------------------------------------------------------------------------------- 1 | # gnulib-tool.m4 serial 2 2 | dnl Copyright (C) 2004-2005, 2009-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl The following macros need not be invoked explicitly. 8 | dnl Invoking them does nothing except to declare default arguments 9 | dnl for "gnulib-tool --import". 10 | 11 | dnl Usage: gl_LOCAL_DIR([DIR]) 12 | AC_DEFUN([gl_LOCAL_DIR], []) 13 | 14 | dnl Usage: gl_MODULES([module1 module2 ...]) 15 | AC_DEFUN([gl_MODULES], []) 16 | 17 | dnl Usage: gl_AVOID([module1 module2 ...]) 18 | AC_DEFUN([gl_AVOID], []) 19 | 20 | dnl Usage: gl_SOURCE_BASE([DIR]) 21 | AC_DEFUN([gl_SOURCE_BASE], []) 22 | 23 | dnl Usage: gl_M4_BASE([DIR]) 24 | AC_DEFUN([gl_M4_BASE], []) 25 | 26 | dnl Usage: gl_PO_BASE([DIR]) 27 | AC_DEFUN([gl_PO_BASE], []) 28 | 29 | dnl Usage: gl_DOC_BASE([DIR]) 30 | AC_DEFUN([gl_DOC_BASE], []) 31 | 32 | dnl Usage: gl_TESTS_BASE([DIR]) 33 | AC_DEFUN([gl_TESTS_BASE], []) 34 | 35 | dnl Usage: gl_WITH_TESTS 36 | AC_DEFUN([gl_WITH_TESTS], []) 37 | 38 | dnl Usage: gl_LIB([LIBNAME]) 39 | AC_DEFUN([gl_LIB], []) 40 | 41 | dnl Usage: gl_LGPL or gl_LGPL([VERSION]) 42 | AC_DEFUN([gl_LGPL], []) 43 | 44 | dnl Usage: gl_MAKEFILE_NAME([FILENAME]) 45 | AC_DEFUN([gl_MAKEFILE_NAME], []) 46 | 47 | dnl Usage: gl_LIBTOOL 48 | AC_DEFUN([gl_LIBTOOL], []) 49 | 50 | dnl Usage: gl_MACRO_PREFIX([PREFIX]) 51 | AC_DEFUN([gl_MACRO_PREFIX], []) 52 | 53 | dnl Usage: gl_PO_DOMAIN([DOMAIN]) 54 | AC_DEFUN([gl_PO_DOMAIN], []) 55 | 56 | dnl Usage: gl_VC_FILES([BOOLEAN]) 57 | AC_DEFUN([gl_VC_FILES], []) 58 | -------------------------------------------------------------------------------- /gl/check-version.c: -------------------------------------------------------------------------------- 1 | /* check-version.h --- Check version string compatibility. 2 | Copyright (C) 1998-2006, 2008-2015 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . */ 16 | 17 | /* Written by Simon Josefsson. This interface is influenced by 18 | gcry_check_version from Werner Koch's Libgcrypt. Paul Eggert 19 | suggested the use of strverscmp to simplify implementation. */ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | /* Get specification. */ 27 | #include "check-version.h" 28 | 29 | /* Check that the version of the library (i.e., the CPP symbol VERSION) 30 | * is at minimum the requested one in REQ_VERSION (typically found in 31 | * a header file) and return the version string. Return NULL if the 32 | * condition is not satisfied. If a NULL is passed to this function, 33 | * no check is done, but the version string is simply returned. 34 | */ 35 | const char * 36 | check_version (const char *req_version) 37 | { 38 | if (!req_version || strverscmp (req_version, VERSION) <= 0) 39 | return VERSION; 40 | 41 | return NULL; 42 | } 43 | -------------------------------------------------------------------------------- /gl/m4/ld-version-script.m4: -------------------------------------------------------------------------------- 1 | # ld-version-script.m4 serial 4 2 | dnl Copyright (C) 2008-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Simon Josefsson 8 | 9 | # FIXME: The test below returns a false positive for mingw 10 | # cross-compiles, 'local:' statements does not reduce number of 11 | # exported symbols in a DLL. Use --disable-ld-version-script to work 12 | # around the problem. 13 | 14 | # gl_LD_VERSION_SCRIPT 15 | # -------------------- 16 | # Check if LD supports linker scripts, and define automake conditional 17 | # HAVE_LD_VERSION_SCRIPT if so. 18 | AC_DEFUN([gl_LD_VERSION_SCRIPT], 19 | [ 20 | AC_ARG_ENABLE([ld-version-script], 21 | [AS_HELP_STRING([--enable-ld-version-script], 22 | [enable linker version script (default is enabled when possible)])], 23 | [have_ld_version_script=$enableval], 24 | [AC_CACHE_CHECK([if LD -Wl,--version-script works], 25 | [gl_cv_sys_ld_version_script], 26 | [gl_cv_sys_ld_version_script=no 27 | save_LDFLAGS=$LDFLAGS 28 | LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" 29 | echo foo >conftest.map 30 | AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], 31 | [], 32 | [cat > conftest.map <, for platforms that have issues. 2 | # stddef_h.m4 serial 5 3 | dnl Copyright (C) 2009-2015 Free Software Foundation, Inc. 4 | dnl This file is free software; the Free Software Foundation 5 | dnl gives unlimited permission to copy and/or distribute it, 6 | dnl with or without modifications, as long as this notice is preserved. 7 | 8 | AC_DEFUN([gl_STDDEF_H], 9 | [ 10 | AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) 11 | AC_REQUIRE([gt_TYPE_WCHAR_T]) 12 | STDDEF_H= 13 | AC_CHECK_TYPE([max_align_t], [], [HAVE_MAX_ALIGN_T=0; STDDEF_H=stddef.h], 14 | [[#include 15 | ]]) 16 | if test $gt_cv_c_wchar_t = no; then 17 | HAVE_WCHAR_T=0 18 | STDDEF_H=stddef.h 19 | fi 20 | AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], 21 | [gl_cv_decl_null_works], 22 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include 23 | int test[2 * (sizeof NULL == sizeof (void *)) -1]; 24 | ]])], 25 | [gl_cv_decl_null_works=yes], 26 | [gl_cv_decl_null_works=no])]) 27 | if test $gl_cv_decl_null_works = no; then 28 | REPLACE_NULL=1 29 | STDDEF_H=stddef.h 30 | fi 31 | AC_SUBST([STDDEF_H]) 32 | AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"]) 33 | if test -n "$STDDEF_H"; then 34 | gl_NEXT_HEADERS([stddef.h]) 35 | fi 36 | ]) 37 | 38 | AC_DEFUN([gl_STDDEF_MODULE_INDICATOR], 39 | [ 40 | dnl Use AC_REQUIRE here, so that the default settings are expanded once only. 41 | AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) 42 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) 43 | ]) 44 | 45 | AC_DEFUN([gl_STDDEF_H_DEFAULTS], 46 | [ 47 | dnl Assume proper GNU behavior unless another module says otherwise. 48 | REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) 49 | HAVE_MAX_ALIGN_T=1; AC_SUBST([HAVE_MAX_ALIGN_T]) 50 | HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) 51 | ]) 52 | -------------------------------------------------------------------------------- /gl/m4/gl-openssl.m4: -------------------------------------------------------------------------------- 1 | # gl-openssl.m4 serial 3 2 | dnl Copyright (C) 2013-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | AC_DEFUN([gl_SET_CRYPTO_CHECK_DEFAULT], 8 | [ 9 | m4_define([gl_CRYPTO_CHECK_DEFAULT], [$1]) 10 | ]) 11 | gl_SET_CRYPTO_CHECK_DEFAULT([no]) 12 | 13 | AC_DEFUN([gl_CRYPTO_CHECK], 14 | [ 15 | dnl gnulib users set this before gl_INIT with gl_SET_CRYPTO_CHECK_DEFAULT() 16 | m4_divert_once([DEFAULTS], [with_openssl_default='gl_CRYPTO_CHECK_DEFAULT']) 17 | 18 | dnl Only clear once, so crypto routines can be checked for individually 19 | m4_divert_once([DEFAULTS], [LIB_CRYPTO=]) 20 | 21 | AC_ARG_WITH([openssl], 22 | [AS_HELP_STRING([--with-openssl], 23 | [use libcrypto hash routines. Valid ARGs are: 24 | 'yes', 'no', 'auto' => use if available, 25 | 'optional' => use if available and warn if not available; 26 | default is ']gl_CRYPTO_CHECK_DEFAULT['])], 27 | [], 28 | [with_openssl=$with_openssl_default]) 29 | 30 | if test "x$1" = xMD5; then 31 | ALG_header=md5.h 32 | else 33 | ALG_header=sha.h 34 | fi 35 | 36 | AC_SUBST([LIB_CRYPTO]) 37 | if test "x$with_openssl" != xno; then 38 | AC_CHECK_LIB([crypto], [$1], 39 | [AC_CHECK_HEADERS([openssl/$ALG_header], 40 | [LIB_CRYPTO=-lcrypto 41 | AC_DEFINE([HAVE_OPENSSL_$1], [1], 42 | [Define to 1 if libcrypto is used for $1.])])]) 43 | if test "x$LIB_CRYPTO" = x; then 44 | if test "x$with_openssl" = xyes; then 45 | AC_MSG_ERROR([openssl development library not found for $1]) 46 | elif test "x$with_openssl" = xoptional; then 47 | AC_MSG_WARN([openssl development library not found for $1]) 48 | fi 49 | fi 50 | fi 51 | ]) 52 | -------------------------------------------------------------------------------- /cfg.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | CFGFLAGS = --enable-gtk-doc --enable-gtk-doc-pdf --enable-gcc-warnings 17 | 18 | ifeq ($(.DEFAULT_GOAL),abort-due-to-no-makefile) 19 | .DEFAULT_GOAL := bootstrap 20 | endif 21 | 22 | autoreconf: 23 | autoreconf --install --verbose 24 | 25 | bootstrap: autoreconf 26 | ./configure $(CFGFLAGS) 27 | make 28 | 29 | INDENT_SOURCES = `find . -name '*.[ch]' -o -name '*.h.in' | \ 30 | grep -v -e /gl/ -e build-aux` 31 | 32 | update-copyright-env = UPDATE_COPYRIGHT_HOLDER="Yubico AB" \ 33 | UPDATE_COPYRIGHT_USE_INTERVALS=1 34 | 35 | local-checks-to-skip = sc_bindtextdomain sc_immutable_NEWS sc_program_name 36 | local-checks-to-skip += sc_prohibit_strcmp sc_unmarked_diagnostics 37 | local-checks-to-skip += sc_GPL_version 38 | 39 | exclude_file_name_regexp--sc_m4_quote_check = ^gl/m4/ 40 | exclude_file_name_regexp--sc_makefile_at_at_check = ^maint.mk|gl/Makefile.am 41 | exclude_file_name_regexp--sc_prohibit_undesirable_word_seq = ^maint.mk 42 | exclude_file_name_regexp--sc_prohibit_atoi_atof = ^src/u2f-host.c 43 | exclude_file_name_regexp--sc_space_tab = ^gtk-doc/gtk-doc.make 44 | exclude_file_name_regexp--sc_trailing_blank = ^u2f-host/cdecode.c|u2f-host/cencode.c|u2f-host/inc/u2f.h|u2f-host/inc/u2f_hid.h 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | *.lo 3 | *.log 4 | *.o 5 | *.trs 6 | *~ 7 | .deps 8 | .libs 9 | ChangeLog 10 | GNUmakefile 11 | INSTALL 12 | Makefile 13 | Makefile.in 14 | aclocal.m4 15 | autom4te.cache/ 16 | build-aux/ar-lib 17 | build-aux/compile 18 | build-aux/config.guess 19 | build-aux/config.sub 20 | build-aux/depcomp 21 | build-aux/install-sh 22 | build-aux/ltmain.sh 23 | build-aux/missing 24 | build-aux/test-driver 25 | config.h 26 | config.h.in 27 | config.log 28 | config.status 29 | configure 30 | gl/arg-nonnull.h 31 | gl/c++defs.h 32 | gl/libgnu.la 33 | gl/stddef.h 34 | gl/string.h 35 | gl/sys/ 36 | gl/warn-on-use.h 37 | gtk-doc/html-build.stamp 38 | gtk-doc/html.stamp 39 | gtk-doc/html/ 40 | gtk-doc/pdf-build.stamp 41 | gtk-doc/pdf.stamp 42 | gtk-doc/scan-build.stamp 43 | gtk-doc/setup-build.stamp 44 | gtk-doc/sgml-build.stamp 45 | gtk-doc/sgml.stamp 46 | gtk-doc/tmpl-build.stamp 47 | gtk-doc/tmpl.stamp 48 | gtk-doc/tmpl/ 49 | gtk-doc/u2f-host-decl-list.txt 50 | gtk-doc/u2f-host-decl.txt 51 | gtk-doc/u2f-host-overrides.txt 52 | gtk-doc/u2f-host-sections.txt 53 | gtk-doc/u2f-host-undeclared.txt 54 | gtk-doc/u2f-host-undocumented.txt 55 | gtk-doc/u2f-host-unused.txt 56 | gtk-doc/u2f-host.args 57 | gtk-doc/u2f-host.hierarchy 58 | gtk-doc/u2f-host.interfaces 59 | gtk-doc/u2f-host.pdf 60 | gtk-doc/u2f-host.prerequisites 61 | gtk-doc/u2f-host.signals 62 | gtk-doc/u2f-host.types 63 | gtk-doc/xml/ 64 | libtool 65 | libu2f-host-*-mac.zip* 66 | libu2f-host-*-win32.zip* 67 | libu2f-host-*-win64.zip* 68 | libu2f-host-*.tar.xz* 69 | m4/libtool.m4 70 | m4/ltoptions.m4 71 | m4/ltsugar.m4 72 | m4/ltversion.m4 73 | m4/lt~obsolete.m4 74 | maint.mk 75 | src/cmdline.c 76 | src/cmdline.h 77 | src/libu2f_cmd.la 78 | src/u2f-host 79 | src/u2f-host.1 80 | stamp-h1 81 | tests/.deps/ 82 | tests/Makefile 83 | tests/Makefile.in 84 | tests/basic 85 | tmp32 86 | tmp64 87 | u2f-host/libu2f-host.la 88 | u2f-host/libu2f_b64.la 89 | u2f-host/u2f-host-version.h 90 | u2f-host/u2f-host.pc 91 | u2f-host.1.txt 92 | -------------------------------------------------------------------------------- /gl/sys_types.in.h: -------------------------------------------------------------------------------- 1 | /* Provide a more complete sys/types.h. 2 | 3 | Copyright (C) 2011-2015 Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, see . */ 17 | 18 | #if __GNUC__ >= 3 19 | @PRAGMA_SYSTEM_HEADER@ 20 | #endif 21 | @PRAGMA_COLUMNS@ 22 | 23 | #ifndef _@GUARD_PREFIX@_SYS_TYPES_H 24 | 25 | /* The include_next requires a split double-inclusion guard. */ 26 | # define _GL_INCLUDING_SYS_TYPES_H 27 | #@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@ 28 | # undef _GL_INCLUDING_SYS_TYPES_H 29 | 30 | #ifndef _@GUARD_PREFIX@_SYS_TYPES_H 31 | #define _@GUARD_PREFIX@_SYS_TYPES_H 32 | 33 | /* Override off_t if Large File Support is requested on native Windows. */ 34 | #if @WINDOWS_64_BIT_OFF_T@ 35 | /* Same as int64_t in . */ 36 | # if defined _MSC_VER 37 | # define off_t __int64 38 | # else 39 | # define off_t long long int 40 | # endif 41 | /* Indicator, for gnulib internal purposes. */ 42 | # define _GL_WINDOWS_64_BIT_OFF_T 1 43 | #endif 44 | 45 | /* MSVC 9 defines size_t in , not in . */ 46 | /* But avoid namespace pollution on glibc systems. */ 47 | #if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ 48 | && ! defined __GLIBC__ 49 | # include 50 | #endif 51 | 52 | #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ 53 | #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ 54 | -------------------------------------------------------------------------------- /u2f-host/u2f-host-types.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #ifndef U2F_HOST_TYPES_H 19 | #define U2F_HOST_TYPES_H 20 | 21 | /** 22 | * u2fh_rc: 23 | * @U2FH_OK: Success. 24 | * @U2FH_MEMORY_ERROR: Memory error. 25 | * @U2FH_TRANSPORT_ERROR: Transport (e.g., USB) error. 26 | * @U2FH_JSON_ERROR: Json error. 27 | * @U2FH_BASE64_ERROR: Base64 error. 28 | * @U2FH_NO_U2F_DEVICE: Missing U2F device. 29 | * @U2FH_AUTHENTICATOR_ERROR: Authenticator error. 30 | * @U2FH_TIMEOUT_ERROR: Timeout error. 31 | * 32 | * Error codes. 33 | */ 34 | typedef enum 35 | { 36 | U2FH_OK = 0, 37 | U2FH_MEMORY_ERROR = -1, 38 | U2FH_TRANSPORT_ERROR = -2, 39 | U2FH_JSON_ERROR = -3, 40 | U2FH_BASE64_ERROR = -4, 41 | U2FH_NO_U2F_DEVICE = -5, 42 | U2FH_AUTHENTICATOR_ERROR = -6, 43 | U2FH_TIMEOUT_ERROR = -7, 44 | U2FH_SIZE_ERROR = -8, 45 | } u2fh_rc; 46 | 47 | /** 48 | * u2fh_initflags: 49 | * @U2FH_DEBUG: Print debug messages. 50 | * 51 | * Flags passed to u2fh_global_init(). 52 | */ 53 | typedef enum 54 | { 55 | U2FH_DEBUG = 1 56 | } u2fh_initflags; 57 | 58 | /** 59 | * u2fh_cmdflags: 60 | * @U2FH_REQUEST_USER_PRESENCE: Request user presence. 61 | * 62 | * Flags passed to u2fh_register() and u2fh_authenticate(). 63 | */ 64 | typedef enum 65 | { 66 | U2FH_REQUEST_USER_PRESENCE = 1 67 | } u2fh_cmdflags; 68 | 69 | typedef struct u2fh_devs u2fh_devs; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /u2f-host/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | AM_CFLAGS = $(WARN_CFLAGS) 17 | AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_builddir)/gl 18 | AM_CPPFLAGS += -I$(srcdir)/.. -I$(builddir)/.. 19 | AM_CPPFLAGS += $(HIDAPI_CFLAGS) $(LIBJSON_CFLAGS) 20 | 21 | lib_LTLIBRARIES = libu2f-host.la 22 | u2f_host_includedir=$(includedir)/u2f-host 23 | u2f_host_include_HEADERS = u2f-host.h u2f-host-types.h u2f-host-version.h 24 | 25 | libu2f_host_la_SOURCES = u2f-host.h u2f-host-types.h u2f-host-version.h 26 | libu2f_host_la_SOURCES += internal.h 27 | libu2f_host_la_SOURCES += u2f-host.pc.in u2f-host.map 28 | libu2f_host_la_SOURCES += global.c version.c error.c 29 | libu2f_host_la_SOURCES += devs.c register.c authenticate.c u2fmisc.c 30 | libu2f_host_la_SOURCES += inc/u2f.h inc/u2f_hid.h 31 | 32 | libu2f_host_la_LIBADD = $(HIDAPI_LIBS) $(LIBJSON_LIBS) 33 | libu2f_host_la_LIBADD += libu2f_b64.la 34 | libu2f_host_la_LIBADD += ../gl/libgnu.la 35 | 36 | libu2f_host_la_LDFLAGS = -no-undefined \ 37 | -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) 38 | 39 | if HAVE_LD_VERSION_SCRIPT 40 | libu2f_host_la_LDFLAGS += -Wl,--version-script=$(srcdir)/u2f-host.map 41 | else 42 | libu2f_host_la_LDFLAGS += -export-symbols-regex '^u2fh_.*' 43 | endif 44 | 45 | noinst_LTLIBRARIES = libu2f_b64.la 46 | libu2f_b64_la_SOURCES = cencode.c cdecode.c b64/cencode.h b64/cdecode.h 47 | libu2f_b64_la_CFLAGS = 48 | 49 | pkgconfigdir = $(libdir)/pkgconfig 50 | pkgconfig_DATA = u2f-host.pc 51 | -------------------------------------------------------------------------------- /gl/m4/multiarch.m4: -------------------------------------------------------------------------------- 1 | # multiarch.m4 serial 7 2 | dnl Copyright (C) 2008-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | # Determine whether the compiler is or may be producing universal binaries. 8 | # 9 | # On Mac OS X 10.5 and later systems, the user can create libraries and 10 | # executables that work on multiple system types--known as "fat" or 11 | # "universal" binaries--by specifying multiple '-arch' options to the 12 | # compiler but only a single '-arch' option to the preprocessor. Like 13 | # this: 14 | # 15 | # ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 16 | # CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 17 | # CPP="gcc -E" CXXCPP="g++ -E" 18 | # 19 | # Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly. 20 | 21 | AC_DEFUN_ONCE([gl_MULTIARCH], 22 | [ 23 | dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN. 24 | gl_cv_c_multiarch=no 25 | AC_COMPILE_IFELSE( 26 | [AC_LANG_SOURCE( 27 | [[#ifndef __APPLE_CC__ 28 | not a universal capable compiler 29 | #endif 30 | typedef int dummy; 31 | ]])], 32 | [ 33 | dnl Check for potential -arch flags. It is not universal unless 34 | dnl there are at least two -arch flags with different values. 35 | arch= 36 | prev= 37 | for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do 38 | if test -n "$prev"; then 39 | case $word in 40 | i?86 | x86_64 | ppc | ppc64) 41 | if test -z "$arch" || test "$arch" = "$word"; then 42 | arch="$word" 43 | else 44 | gl_cv_c_multiarch=yes 45 | fi 46 | ;; 47 | esac 48 | prev= 49 | else 50 | if test "x$word" = "x-arch"; then 51 | prev=arch 52 | fi 53 | fi 54 | done 55 | ]) 56 | if test $gl_cv_c_multiarch = yes; then 57 | APPLE_UNIVERSAL_BUILD=1 58 | else 59 | APPLE_UNIVERSAL_BUILD=0 60 | fi 61 | AC_SUBST([APPLE_UNIVERSAL_BUILD]) 62 | ]) 63 | -------------------------------------------------------------------------------- /gl/m4/gnulib-cache.m4: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2002-2015 Free Software Foundation, Inc. 2 | # 3 | # This file is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This file is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this file. If not, see . 15 | # 16 | # As a special exception to the GNU General Public License, 17 | # this file may be distributed as part of a program that 18 | # contains a configuration script generated by Autoconf, under 19 | # the same distribution terms as the rest of that program. 20 | # 21 | # Generated by gnulib-tool. 22 | # 23 | # This file represents the specification of how gnulib-tool is used. 24 | # It acts as a cache: It is written and read by gnulib-tool. 25 | # In projects that use version control, this file is meant to be put under 26 | # version control, like the configure.ac and various Makefile.am files. 27 | 28 | 29 | # Specification in the form of a command-line invocation: 30 | # gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --vc-files check-version crypto/sha256 lib-symbol-versions maintainer-makefile manywarnings 31 | 32 | # Specification in the form of a few gnulib-tool.m4 macro invocations: 33 | gl_LOCAL_DIR([]) 34 | gl_MODULES([ 35 | check-version 36 | crypto/sha256 37 | lib-symbol-versions 38 | maintainer-makefile 39 | manywarnings 40 | ]) 41 | gl_AVOID([]) 42 | gl_SOURCE_BASE([gl]) 43 | gl_M4_BASE([gl/m4]) 44 | gl_PO_BASE([]) 45 | gl_DOC_BASE([doc]) 46 | gl_TESTS_BASE([tests]) 47 | gl_LIB([libgnu]) 48 | gl_LGPL([2]) 49 | gl_MAKEFILE_NAME([]) 50 | gl_LIBTOOL 51 | gl_MACRO_PREFIX([gl]) 52 | gl_PO_DOMAIN([]) 53 | gl_WITNESS_C_MACRO([]) 54 | gl_VC_FILES([true]) 55 | -------------------------------------------------------------------------------- /gl/m4/00gnulib.m4: -------------------------------------------------------------------------------- 1 | # 00gnulib.m4 serial 3 2 | dnl Copyright (C) 2009-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl This file must be named something that sorts before all other 8 | dnl gnulib-provided .m4 files. It is needed until such time as we can 9 | dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE and 10 | dnl m4_divert semantics. 11 | 12 | # Until autoconf 2.63, handling of the diversion stack required m4_init 13 | # to be called first; but this does not happen with aclocal. Wrapping 14 | # the entire execution in another layer of the diversion stack fixes this. 15 | # Worse, prior to autoconf 2.62, m4_wrap depended on the underlying m4 16 | # for whether it was FIFO or LIFO; in order to properly balance with 17 | # m4_init, we need to undo our push just before anything wrapped within 18 | # the m4_init body. The way to ensure this is to wrap both sides of 19 | # m4_init with a one-shot macro that does the pop at the right time. 20 | m4_ifndef([_m4_divert_diversion], 21 | [m4_divert_push([KILL]) 22 | m4_define([gl_divert_fixup], [m4_divert_pop()m4_define([$0])]) 23 | m4_define([m4_init], 24 | [gl_divert_fixup()]m4_defn([m4_init])[gl_divert_fixup()])]) 25 | 26 | 27 | # AC_DEFUN_ONCE([NAME], VALUE) 28 | # ---------------------------- 29 | # Define NAME to expand to VALUE on the first use (whether by direct 30 | # expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. 31 | # Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This 32 | # definition is slower than the version in Autoconf 2.64, because it 33 | # can only use interfaces that existed since 2.59; but it achieves the 34 | # same effect. Quoting is necessary to avoid confusing Automake. 35 | m4_version_prereq([2.63.263], [], 36 | [m4_define([AC][_DEFUN_ONCE], 37 | [AC][_DEFUN([$1], 38 | [AC_REQUIRE([_gl_DEFUN_ONCE([$1])], 39 | [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl 40 | [AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) 41 | 42 | # gl_00GNULIB 43 | # ----------- 44 | # Witness macro that this file has been included. Needed to force 45 | # Automake to include this file prior to all other gnulib .m4 files. 46 | AC_DEFUN([gl_00GNULIB]) 47 | -------------------------------------------------------------------------------- /gl/m4/warn-on-use.m4: -------------------------------------------------------------------------------- 1 | # warn-on-use.m4 serial 5 2 | dnl Copyright (C) 2010-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | # gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) 8 | # --------------------------------------- 9 | # For each whitespace-separated element in the list of NAMES, define 10 | # HAVE_RAW_DECL_name if the function has a declaration among INCLUDES 11 | # even after being undefined as a macro. 12 | # 13 | # See warn-on-use.h for some hints on how to poison function names, as 14 | # well as ideas on poisoning global variables and macros. NAMES may 15 | # include global variables, but remember that only functions work with 16 | # _GL_WARN_ON_USE. Typically, INCLUDES only needs to list a single 17 | # header, but if the replacement header pulls in other headers because 18 | # some systems declare functions in the wrong header, then INCLUDES 19 | # should do likewise. 20 | # 21 | # It is generally safe to assume declarations for functions declared 22 | # in the intersection of C89 and C11 (such as printf) without 23 | # needing gl_WARN_ON_USE_PREPARE. 24 | AC_DEFUN([gl_WARN_ON_USE_PREPARE], 25 | [ 26 | m4_foreach_w([gl_decl], [$2], 27 | [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), 28 | [Define to 1 if ]m4_defn([gl_decl])[ is declared even after 29 | undefining macros.])])dnl 30 | dnl FIXME: gl_Symbol must be used unquoted until we can assume 31 | dnl autoconf 2.64 or newer. 32 | for gl_func in m4_flatten([$2]); do 33 | AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl 34 | AC_CACHE_CHECK([whether $gl_func is declared without a macro], 35 | gl_Symbol, 36 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1], 37 | [@%:@undef $gl_func 38 | (void) $gl_func;])], 39 | [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])]) 40 | AS_VAR_IF(gl_Symbol, [yes], 41 | [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) 42 | dnl shortcut - if the raw declaration exists, then set a cache 43 | dnl variable to allow skipping any later AC_CHECK_DECL efforts 44 | eval ac_cv_have_decl_$gl_func=yes]) 45 | AS_VAR_POPDEF([gl_Symbol])dnl 46 | done 47 | ]) 48 | -------------------------------------------------------------------------------- /gl/m4/stdalign.m4: -------------------------------------------------------------------------------- 1 | # Check for stdalign.h that conforms to C11. 2 | 3 | dnl Copyright 2011-2015 Free Software Foundation, Inc. 4 | dnl This file is free software; the Free Software Foundation 5 | dnl gives unlimited permission to copy and/or distribute it, 6 | dnl with or without modifications, as long as this notice is preserved. 7 | 8 | # Prepare for substituting if it is not supported. 9 | 10 | AC_DEFUN([gl_STDALIGN_H], 11 | [ 12 | AC_CACHE_CHECK([for working stdalign.h], 13 | [gl_cv_header_working_stdalign_h], 14 | [AC_COMPILE_IFELSE( 15 | [AC_LANG_PROGRAM( 16 | [[#include 17 | #include 18 | 19 | /* Test that alignof yields a result consistent with offsetof. 20 | This catches GCC bug 52023 21 | . */ 22 | #ifdef __cplusplus 23 | template struct alignof_helper { char a; t b; }; 24 | # define ao(type) offsetof (alignof_helper, b) 25 | #else 26 | # define ao(type) offsetof (struct { char a; type b; }, b) 27 | #endif 28 | char test_double[ao (double) % _Alignof (double) == 0 ? 1 : -1]; 29 | char test_long[ao (long int) % _Alignof (long int) == 0 ? 1 : -1]; 30 | char test_alignof[alignof (double) == _Alignof (double) ? 1 : -1]; 31 | 32 | /* Test _Alignas only on platforms where gnulib can help. */ 33 | #if \ 34 | ((defined __cplusplus && 201103 <= __cplusplus) \ 35 | || (defined __APPLE__ && defined __MACH__ \ 36 | ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \ 37 | : __GNUC__) \ 38 | || __HP_cc || __HP_aCC || __IBMC__ || __IBMCPP__ \ 39 | || __ICC || 0x5110 <= __SUNPRO_C \ 40 | || 1300 <= _MSC_VER) 41 | struct alignas_test { char c; char alignas (8) alignas_8; }; 42 | char test_alignas[offsetof (struct alignas_test, alignas_8) == 8 43 | ? 1 : -1]; 44 | #endif 45 | ]])], 46 | [gl_cv_header_working_stdalign_h=yes], 47 | [gl_cv_header_working_stdalign_h=no])]) 48 | 49 | if test $gl_cv_header_working_stdalign_h = yes; then 50 | STDALIGN_H='' 51 | else 52 | STDALIGN_H='stdalign.h' 53 | fi 54 | 55 | AC_SUBST([STDALIGN_H]) 56 | AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"]) 57 | ]) 58 | -------------------------------------------------------------------------------- /u2f-host/internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #ifndef INTERNAL_H 19 | #define INTERNAL_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "inc/u2f.h" 26 | #include "inc/u2f_hid.h" 27 | 28 | #ifdef _WIN32 29 | #include 30 | #else 31 | #include 32 | #define Sleep(x) (usleep((x) * 1000)) 33 | #endif 34 | 35 | struct u2fdevice 36 | { 37 | struct u2fdevice *next; 38 | hid_device *devh; 39 | unsigned id; 40 | uint32_t cid; 41 | char *device_string; 42 | char *device_path; 43 | int skipped; 44 | uint8_t versionInterface; // Interface version 45 | uint8_t versionMajor; // Major version number 46 | uint8_t versionMinor; // Minor version number 47 | uint8_t versionBuild; // Build version number 48 | uint8_t capFlags; // Capabilities flags 49 | }; 50 | 51 | struct u2fh_devs 52 | { 53 | unsigned max_id; 54 | struct u2fdevice *first; 55 | }; 56 | 57 | extern int debug; 58 | 59 | #define MAXDATASIZE 16384 60 | 61 | #define MAXFIXEDLEN 1024 62 | 63 | #define REGISTER_TYP "navigator.id.finishEnrollment" 64 | #define AUTHENTICATE_TYP "navigator.id.getAssertion" 65 | 66 | #define CTAPHID_KEEPALIVE (TYPE_INIT | 0x3b) // Keepalive response 67 | 68 | int prepare_browserdata (const char *challenge, const char *origin, 69 | const char *typstr, char *out, size_t * outlen); 70 | int prepare_origin (const char *origin, unsigned char *p); 71 | u2fh_rc send_apdu (u2fh_devs * devs, int index, int cmd, 72 | const unsigned char *d, size_t dlen, int p1, 73 | unsigned char *out, size_t * outlen); 74 | int get_fixed_json_data (const char *jsonstr, const char *key, char *p, 75 | size_t * len); 76 | int hash_data (const char *in, size_t len, unsigned char *out); 77 | 78 | struct u2fdevice *get_device (u2fh_devs * devs, unsigned index); 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | SUBDIRS = gl u2f-host src tests gtk-doc 17 | 18 | ACLOCAL_AMFLAGS = -I m4 -I gl/m4 19 | 20 | DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc 21 | 22 | EXTRA_DIST = BLURB cfg.mk macosx.mk windows.mk COPYING.LGPLv2 23 | 24 | EXTRA_DIST += doc/Mode_switch_YubiKey.adoc 25 | 26 | EXTRA_DIST += 70-u2f.rules 27 | udevrulesdir = @udevrulesdir@ 28 | dist_udevrules_DATA = $(udevrulesfile) 29 | 30 | # Release 31 | 32 | ChangeLog: 33 | cd $(srcdir) && git2cl > ChangeLog 34 | 35 | release: my-release 36 | my-release: 37 | @if test ! -d "$(YUBICO_WWW_REPO)"; then \ 38 | echo "www repo not found!"; \ 39 | echo "Make sure that YUBICO_WWW_REPO is set"; \ 40 | exit 1; \ 41 | fi 42 | @head -3 $(srcdir)/NEWS | \ 43 | grep -q "Version $(VERSION) .released `date -I`" || \ 44 | (echo 'error: Update date/version in $(srcdir)/NEWS'; exit 1) 45 | rm -f $(srcdir)/ChangeLog 46 | make ChangeLog syntax-check distcheck 47 | make -f windows.mk VERSION=$(VERSION) 48 | gpg --detach-sign $(PACKAGE)-$(VERSION).tar.xz 49 | gpg --detach-sign $(PACKAGE)-$(VERSION)-win32.zip 50 | gpg --detach-sign $(PACKAGE)-$(VERSION)-win64.zip 51 | gpg --verify $(PACKAGE)-$(VERSION).tar.xz.sig 52 | gpg --verify $(PACKAGE)-$(VERSION)-win32.zip.sig 53 | gpg --verify $(PACKAGE)-$(VERSION)-win64.zip.sig 54 | cd $(srcdir) && git push 55 | cd $(srcdir) && git tag -s -m "$(PACKAGE) $(VERSION)" $(PACKAGE)-$(VERSION) 56 | cd $(srcdir) && git push --tags 57 | $(YUBICO_WWW_REPO)/publish $(PACKAGE) $(VERSION) $(PACKAGE)-$(VERSION).tar.xz* 58 | $(YUBICO_WWW_REPO)/publish $(PACKAGE) $(VERSION) $(PACKAGE)-$(VERSION)-win32.zip* 59 | $(YUBICO_WWW_REPO)/publish $(PACKAGE) $(VERSION) $(PACKAGE)-$(VERSION)-win64.zip* 60 | $(HELP2ADOC) -e src/u2f-host -n "Yubico Universal 2nd Factor (U2F) Host Tool" > u2f-host.1.txt 61 | $(YUBICO_WWW_REPO)/save-mans $(PACKAGE) u2f-host.1.txt 62 | -------------------------------------------------------------------------------- /u2f-host/u2f-host-version.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #ifndef U2F_HOST_VERSION_H 19 | #define U2F_HOST_VERSION_H 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif 25 | 26 | /** 27 | * U2FH_VERSION_STRING 28 | * 29 | * Pre-processor symbol with a string that describe the header file 30 | * version number. Used together with u2fh_check_version() to verify 31 | * header file and run-time library consistency. 32 | */ 33 | #define U2FH_VERSION_STRING "@VERSION@" 34 | 35 | /** 36 | * U2FH_VERSION_NUMBER 37 | * 38 | * Pre-processor symbol with a hexadecimal value describing the header 39 | * file version number. For example, when the header version is 1.2.3 40 | * this symbol will have the value 0x01020300. The last two digits 41 | * are only used between public releases, and will otherwise be 00. 42 | */ 43 | #define U2FH_VERSION_NUMBER @U2FH_VERSION_NUMBER@ 44 | 45 | /** 46 | * U2FH_VERSION_MAJOR 47 | * 48 | * Pre-processor symbol with a decimal value that describe the major 49 | * level of the header file version number. For example, when the 50 | * header version is 1.2.3 this symbol will be 1. 51 | */ 52 | #define U2FH_VERSION_MAJOR @U2FH_VERSION_MAJOR@ 53 | 54 | /** 55 | * U2FH_VERSION_MINOR 56 | * 57 | * Pre-processor symbol with a decimal value that describe the minor 58 | * level of the header file version number. For example, when the 59 | * header version is 1.2.3 this symbol will be 2. 60 | */ 61 | #define U2FH_VERSION_MINOR @U2FH_VERSION_MINOR@ 62 | 63 | /** 64 | * U2FH_VERSION_PATCH 65 | * 66 | * Pre-processor symbol with a decimal value that describe the patch 67 | * level of the header file version number. For example, when the 68 | * header version is 1.2.3 this symbol will be 3. 69 | */ 70 | #define U2FH_VERSION_PATCH @U2FH_VERSION_PATCH@ 71 | 72 | const char *u2fh_check_version (const char *req_version); 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | #endif 78 | -------------------------------------------------------------------------------- /tests/basic.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | int 27 | main (void) 28 | { 29 | u2fh_devs *devs; 30 | int rc; 31 | 32 | if (strcmp (U2FH_VERSION_STRING, u2fh_check_version (NULL)) != 0) 33 | { 34 | printf ("version mismatch %s != %s\n", U2FH_VERSION_STRING, 35 | u2fh_check_version (NULL)); 36 | return EXIT_FAILURE; 37 | } 38 | 39 | if (u2fh_check_version (U2FH_VERSION_STRING) == NULL) 40 | { 41 | printf ("version NULL?\n"); 42 | return EXIT_FAILURE; 43 | } 44 | 45 | if (u2fh_check_version ("99.99.99") != NULL) 46 | { 47 | printf ("version not NULL?\n"); 48 | return EXIT_FAILURE; 49 | } 50 | 51 | printf ("u2fh version: header %s library %s\n", 52 | U2FH_VERSION_STRING, u2fh_check_version (NULL)); 53 | 54 | rc = u2fh_global_init (0); 55 | if (rc != U2FH_OK) 56 | { 57 | printf ("u2fh_global_init rc %d\n", rc); 58 | return EXIT_FAILURE; 59 | } 60 | 61 | if (u2fh_strerror (U2FH_OK) == NULL) 62 | { 63 | printf ("u2fh_strerror NULL\n"); 64 | return EXIT_FAILURE; 65 | } 66 | 67 | { 68 | const char *s; 69 | s = u2fh_strerror_name (U2FH_OK); 70 | if (s == NULL || strcmp (s, "U2FH_OK") != 0) 71 | { 72 | printf ("u2fh_strerror_name %s\n", s); 73 | return EXIT_FAILURE; 74 | } 75 | } 76 | 77 | rc = u2fh_devs_init (&devs); 78 | if (rc != U2FH_OK) 79 | { 80 | printf ("u2fh_devs_init %d\n", rc); 81 | return EXIT_FAILURE; 82 | } 83 | 84 | rc = u2fh_devs_discover (devs, NULL); 85 | if (rc == U2FH_OK) 86 | { 87 | printf ("Found U2F device\n"); 88 | /* XXX: register+authenticate */ 89 | } 90 | else if (rc != U2FH_NO_U2F_DEVICE) 91 | { 92 | printf ("u2fh_devs_discover %d\n", rc); 93 | return EXIT_FAILURE; 94 | } 95 | 96 | u2fh_devs_done (devs); 97 | 98 | u2fh_global_done (); 99 | 100 | return EXIT_SUCCESS; 101 | } 102 | -------------------------------------------------------------------------------- /windows.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | LIBJSONVERSION=0.13.1 17 | HIDAPIHASH=0cbc3a409bcb45cefb3edbf144d64ddd4e0821ce 18 | PACKAGE=libu2f-host 19 | 20 | all: usage 32bit 64bit 21 | 22 | .PHONY: usage 23 | usage: 24 | @if test -z "$(VERSION)"; then \ 25 | echo "Try this instead:"; \ 26 | echo " make VERSION=[VERSION]"; \ 27 | echo "For example:"; \ 28 | echo " make VERSION=1.6.0"; \ 29 | exit 1; \ 30 | fi 31 | 32 | doit: 33 | rm -rf tmp$(ARCH) && mkdir tmp$(ARCH) && cd tmp$(ARCH) && \ 34 | mkdir -p root/licenses && \ 35 | cp ../json-c-$(LIBJSONVERSION).tar.gz . || \ 36 | wget --no-check-certificate https://s3.amazonaws.com/json-c_releases/releases/json-c-$(LIBJSONVERSION).tar.gz && \ 37 | tar xfa json-c-$(LIBJSONVERSION).tar.gz && \ 38 | cd json-c-$(LIBJSONVERSION) && \ 39 | ac_cv_func_realloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes ./configure --host=$(HOST) --build=x86_64-unknown-linux-gnu --prefix=$(PWD)/tmp$(ARCH)/root && \ 40 | make install && \ 41 | cp COPYING $(PWD)/tmp$(ARCH)/root/licenses/json-c.txt && \ 42 | cd .. && \ 43 | git clone https://github.com/signal11/hidapi.git && \ 44 | cd hidapi && \ 45 | git checkout $(HIDAPIHASH) && \ 46 | ./bootstrap && \ 47 | ./configure --host=$(HOST) --build=x86_64-unknown-linux-gnu --prefix=$(PWD)/tmp$(ARCH)/root && \ 48 | make install $(CHECK) && \ 49 | cp LICENSE-gpl3.txt $(PWD)/tmp$(ARCH)/root/licenses/hidapi.txt && \ 50 | cd .. && \ 51 | cp ../$(PACKAGE)-$(VERSION).tar.xz . && \ 52 | tar xfa $(PACKAGE)-$(VERSION).tar.xz && \ 53 | cd $(PACKAGE)-$(VERSION)/ && \ 54 | CC="$(HOST)-gcc -static-libgcc -lbcrypt" PKG_CONFIG_PATH=$(PWD)/tmp$(ARCH)/root/lib/pkgconfig lt_cv_deplibs_check_method=pass_all ./configure --host=$(HOST) --build=x86_64-unknown-linux-gnu --prefix=$(PWD)/tmp$(ARCH)/root LDFLAGS=-L$(PWD)/tmp$(ARCH)/root/lib CPPFLAGS="-I$(PWD)/tmp$(ARCH)/root/include" && \ 55 | make install $(CHECK) && \ 56 | cp COPYING $(PWD)/tmp$(ARCH)/root/licenses/$(PACKAGE).txt && \ 57 | cd .. && \ 58 | cd root && \ 59 | zip -r ../../$(PACKAGE)-$(VERSION)-win$(ARCH).zip * 60 | 61 | 32bit: 62 | $(MAKE) -f windows.mk doit ARCH=32 HOST=i686-w64-mingw32 63 | 64 | 64bit: 65 | $(MAKE) -f windows.mk doit ARCH=64 HOST=x86_64-w64-mingw32 66 | -------------------------------------------------------------------------------- /u2f-host/u2f-host.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #ifndef U2F_HOST_H 19 | #define U2F_HOST_H 20 | 21 | // Visual studio 2008 and earlier are missing stdint.h 22 | #if defined _MSC_VER && _MSC_VER <= 1500 && !defined HAVE_STDINT_H 23 | typedef unsigned char uint8_t; 24 | typedef unsigned short uint16_t; 25 | typedef unsigned int uint32_t; 26 | typedef unsigned long int uint64_t; 27 | #else 28 | #include 29 | #endif 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | #if defined _MSC_VER 37 | #define U2FH_EXPORT __declspec(dllexport) 38 | #else 39 | #define U2FH_EXPORT extern 40 | #endif 41 | 42 | #ifdef __cplusplus 43 | extern "C" 44 | { 45 | #endif 46 | 47 | /* Must be called successfully before using any other functions. */ 48 | U2FH_EXPORT u2fh_rc u2fh_global_init (u2fh_initflags flags); 49 | U2FH_EXPORT void u2fh_global_done (void); 50 | 51 | U2FH_EXPORT const char *u2fh_strerror (int err); 52 | U2FH_EXPORT const char *u2fh_strerror_name (int err); 53 | 54 | U2FH_EXPORT u2fh_rc u2fh_devs_init (u2fh_devs ** devs); 55 | U2FH_EXPORT u2fh_rc u2fh_devs_discover (u2fh_devs * devs, unsigned *max_index); 56 | U2FH_EXPORT void u2fh_devs_done (u2fh_devs * devs); 57 | 58 | U2FH_EXPORT u2fh_rc u2fh_register (u2fh_devs * devs, 59 | const char *challenge, 60 | const char *origin, 61 | char **response, u2fh_cmdflags flags); 62 | 63 | U2FH_EXPORT u2fh_rc u2fh_register2 (u2fh_devs * devs, 64 | const char *challenge, 65 | const char *origin, 66 | char *response, size_t * response_len, 67 | u2fh_cmdflags flags); 68 | 69 | U2FH_EXPORT u2fh_rc u2fh_authenticate (u2fh_devs * devs, 70 | const char *challenge, 71 | const char *origin, 72 | char **response, u2fh_cmdflags flags); 73 | 74 | U2FH_EXPORT u2fh_rc u2fh_authenticate2 (u2fh_devs * devs, 75 | const char *challenge, 76 | const char *origin, 77 | char *response, size_t * response_len, 78 | u2fh_cmdflags flags); 79 | 80 | U2FH_EXPORT u2fh_rc u2fh_sendrecv (u2fh_devs * devs, 81 | unsigned index, 82 | uint8_t cmd, 83 | const unsigned char *send, 84 | uint16_t sendlen, 85 | unsigned char *recv, size_t * recvlen); 86 | 87 | U2FH_EXPORT u2fh_rc u2fh_get_device_description (u2fh_devs * devs, 88 | unsigned index, char *out, 89 | size_t * len); 90 | 91 | U2FH_EXPORT int u2fh_is_alive (u2fh_devs * devs, unsigned index); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | #endif 97 | -------------------------------------------------------------------------------- /gl/m4/warnings.m4: -------------------------------------------------------------------------------- 1 | # warnings.m4 serial 11 2 | dnl Copyright (C) 2008-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Simon Josefsson 8 | 9 | # gl_AS_VAR_APPEND(VAR, VALUE) 10 | # ---------------------------- 11 | # Provide the functionality of AS_VAR_APPEND if Autoconf does not have it. 12 | m4_ifdef([AS_VAR_APPEND], 13 | [m4_copy([AS_VAR_APPEND], [gl_AS_VAR_APPEND])], 14 | [m4_define([gl_AS_VAR_APPEND], 15 | [AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])]) 16 | 17 | 18 | # gl_COMPILER_OPTION_IF(OPTION, [IF-SUPPORTED], [IF-NOT-SUPPORTED], 19 | # [PROGRAM = AC_LANG_PROGRAM()]) 20 | # ----------------------------------------------------------------- 21 | # Check if the compiler supports OPTION when compiling PROGRAM. 22 | # 23 | # FIXME: gl_Warn must be used unquoted until we can assume Autoconf 24 | # 2.64 or newer. 25 | AC_DEFUN([gl_COMPILER_OPTION_IF], 26 | [AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl 27 | AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl 28 | AS_LITERAL_IF([$1], 29 | [m4_pushdef([gl_Positive], m4_bpatsubst([$1], [^-Wno-], [-W]))], 30 | [gl_positive="$1" 31 | case $gl_positive in 32 | -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;; 33 | esac 34 | m4_pushdef([gl_Positive], [$gl_positive])])dnl 35 | AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [ 36 | gl_save_compiler_FLAGS="$gl_Flags" 37 | gl_AS_VAR_APPEND(m4_defn([gl_Flags]), 38 | [" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["]) 39 | AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])], 40 | [AS_VAR_SET(gl_Warn, [yes])], 41 | [AS_VAR_SET(gl_Warn, [no])]) 42 | gl_Flags="$gl_save_compiler_FLAGS" 43 | ]) 44 | AS_VAR_IF(gl_Warn, [yes], [$2], [$3]) 45 | m4_popdef([gl_Positive])dnl 46 | AS_VAR_POPDEF([gl_Flags])dnl 47 | AS_VAR_POPDEF([gl_Warn])dnl 48 | ]) 49 | 50 | # gl_UNKNOWN_WARNINGS_ARE_ERRORS 51 | # ------------------------------ 52 | # Clang doesn't complain about unknown warning options unless one also 53 | # specifies -Wunknown-warning-option -Werror. Detect this. 54 | AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS], 55 | [gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option], 56 | [gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'], 57 | [gl_unknown_warnings_are_errors=])]) 58 | 59 | # gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS], 60 | # [PROGRAM = AC_LANG_PROGRAM()]) 61 | # --------------------------------------------- 62 | # Adds parameter to WARN_CFLAGS if the compiler supports it when 63 | # compiling PROGRAM. For example, gl_WARN_ADD([-Wparentheses]). 64 | # 65 | # If VARIABLE is a variable name, AC_SUBST it. 66 | AC_DEFUN([gl_WARN_ADD], 67 | [AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) 68 | gl_COMPILER_OPTION_IF([$1], 69 | [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_CFLAGS]], [[$2]]), [" $1"])], 70 | [], 71 | [$3]) 72 | m4_ifval([$2], 73 | [AS_LITERAL_IF([$2], [AC_SUBST([$2])])], 74 | [AC_SUBST([WARN_CFLAGS])])dnl 75 | ]) 76 | 77 | # Local Variables: 78 | # mode: autoconf 79 | # End: 80 | -------------------------------------------------------------------------------- /u2f-host/error.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #define ERR(name, desc) { name, #name, desc } 22 | 23 | typedef struct 24 | { 25 | int rc; 26 | const char *name; 27 | const char *description; 28 | } err_t; 29 | 30 | static const err_t errors[] = { 31 | ERR (U2FH_OK, "successful return"), 32 | ERR (U2FH_MEMORY_ERROR, "out of memory or other memory error"), 33 | ERR (U2FH_TRANSPORT_ERROR, "error in transport layer"), 34 | ERR (U2FH_JSON_ERROR, "error in JSON handling"), 35 | ERR (U2FH_BASE64_ERROR, "base64 error"), 36 | ERR (U2FH_NO_U2F_DEVICE, "cannot find U2F device"), 37 | ERR (U2FH_AUTHENTICATOR_ERROR, "authenticator error"), 38 | ERR (U2FH_TIMEOUT_ERROR, "timeout error"), 39 | ERR (U2FH_SIZE_ERROR, "size error, buffer to small"), 40 | }; 41 | 42 | /** 43 | * u2fh_strerror: 44 | * @err: error code 45 | * 46 | * Convert return code to human readable string explanation of the 47 | * reason for the particular error code. 48 | * 49 | * This string can be used to output a diagnostic message to the user. 50 | * 51 | * This function is one of few in the library that can be used without 52 | * a successful call to u2fh_global_init(). 53 | * 54 | * Return value: Returns a pointer to a statically allocated string 55 | * containing an explanation of the error code @err. 56 | **/ 57 | const char * 58 | u2fh_strerror (int err) 59 | { 60 | static const char *unknown = "Unknown libu2f-host error"; 61 | const char *p; 62 | 63 | if (-err < 0 || -err >= (int) (sizeof (errors) / sizeof (errors[0]))) 64 | return unknown; 65 | 66 | p = errors[-err].description; 67 | if (!p) 68 | p = unknown; 69 | 70 | return p; 71 | } 72 | 73 | /** 74 | * u2fh_strerror_name: 75 | * @err: error code 76 | * 77 | * Convert return code to human readable string representing the error 78 | * code symbol itself. For example, u2fh_strerror_name(%U2FH_OK) 79 | * returns the string "U2FH_OK". 80 | * 81 | * This string can be used to output a diagnostic message to the user. 82 | * 83 | * This function is one of few in the library that can be used without 84 | * a successful call to u2fh_global_init(). 85 | * 86 | * Return value: Returns a pointer to a statically allocated string 87 | * containing a string version of the error code @err, or NULL if 88 | * the error code is not known. 89 | **/ 90 | const char * 91 | u2fh_strerror_name (int err) 92 | { 93 | if (-err < 0 || -err >= (int) (sizeof (errors) / sizeof (errors[0]))) 94 | return NULL; 95 | 96 | return errors[-err].name; 97 | } 98 | -------------------------------------------------------------------------------- /gl/stddef.in.h: -------------------------------------------------------------------------------- 1 | /* A substitute for POSIX 2008 , for platforms that have issues. 2 | 3 | Copyright (C) 2009-2015 Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, see . */ 17 | 18 | /* Written by Eric Blake. */ 19 | 20 | /* 21 | * POSIX 2008 for platforms that have issues. 22 | * 23 | */ 24 | 25 | #if __GNUC__ >= 3 26 | @PRAGMA_SYSTEM_HEADER@ 27 | #endif 28 | @PRAGMA_COLUMNS@ 29 | 30 | #if defined __need_wchar_t || defined __need_size_t \ 31 | || defined __need_ptrdiff_t || defined __need_NULL \ 32 | || defined __need_wint_t 33 | /* Special invocation convention inside gcc header files. In 34 | particular, gcc provides a version of that blindly 35 | redefines NULL even when __need_wint_t was defined, even though 36 | wint_t is not normally provided by . Hence, we must 37 | remember if special invocation has ever been used to obtain wint_t, 38 | in which case we need to clean up NULL yet again. */ 39 | 40 | # if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T) 41 | # ifdef __need_wint_t 42 | # define _GL_STDDEF_WINT_T 43 | # endif 44 | # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ 45 | # endif 46 | 47 | #else 48 | /* Normal invocation convention. */ 49 | 50 | # ifndef _@GUARD_PREFIX@_STDDEF_H 51 | 52 | /* The include_next requires a split double-inclusion guard. */ 53 | 54 | # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ 55 | 56 | /* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ 57 | # if (@REPLACE_NULL@ \ 58 | && (!defined _@GUARD_PREFIX@_STDDEF_H || defined _GL_STDDEF_WINT_T)) 59 | # undef NULL 60 | # ifdef __cplusplus 61 | /* ISO C++ says that the macro NULL must expand to an integer constant 62 | expression, hence '((void *) 0)' is not allowed in C++. */ 63 | # if __GNUG__ >= 3 64 | /* GNU C++ has a __null macro that behaves like an integer ('int' or 65 | 'long') but has the same size as a pointer. Use that, to avoid 66 | warnings. */ 67 | # define NULL __null 68 | # else 69 | # define NULL 0L 70 | # endif 71 | # else 72 | # define NULL ((void *) 0) 73 | # endif 74 | # endif 75 | 76 | # ifndef _@GUARD_PREFIX@_STDDEF_H 77 | # define _@GUARD_PREFIX@_STDDEF_H 78 | 79 | /* Some platforms lack wchar_t. */ 80 | #if !@HAVE_WCHAR_T@ 81 | # define wchar_t int 82 | #endif 83 | 84 | /* Some platforms lack max_align_t. */ 85 | #if !@HAVE_MAX_ALIGN_T@ 86 | typedef union 87 | { 88 | char *__p; 89 | double __d; 90 | long double __ld; 91 | long int __i; 92 | } max_align_t; 93 | #endif 94 | 95 | # endif /* _@GUARD_PREFIX@_STDDEF_H */ 96 | # endif /* _@GUARD_PREFIX@_STDDEF_H */ 97 | #endif /* __need_XXX */ 98 | -------------------------------------------------------------------------------- /u2f-host/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(CheckIncludeFiles) 2 | include(CheckFunctionExists) 3 | 4 | # ========== 5 | # Check for stdint.h presence 6 | # ========== 7 | check_include_files(stdint.h HAVE_STDINT_H) 8 | 9 | # ========== 10 | # Configure version 11 | # ========== 12 | set(U2FH_VERSION_MAJOR 1) 13 | set(U2FH_VERSION_MINOR 1) 14 | set(U2FH_VERSION_PATCH 1) 15 | set(U2FH_VERSION_NUMBER "0x010101") 16 | set(VERSION "1.1.1") 17 | set(LT_CURRENT 1) 18 | set(LT_AGE, 1) 19 | set(LT_REVISION, 1) 20 | configure_file(u2f-host-version.h.in u2f-host-version.h) 21 | 22 | # ========== 23 | # Other configurations 24 | # ========== 25 | configure_file(config.h.cmake.in config.h) 26 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 27 | 28 | # ========== 29 | # Source files 30 | # ========== 31 | set(SOURCE authenticate.c cdecode.c cencode.c devs.c error.c global.c register.c u2fmisc.c version.c) 32 | source_group(sources FILES ${SOURCE}) 33 | include_directories(.) 34 | set(HEADERS u2f-host.h u2f-host-types.h internal.h) 35 | source_group(headers FILES ${HEADERS}) 36 | set(HEADERS_B64 b64/cdecode.h b64/cencode.h) 37 | source_group(headers\\b64 FILES ${HEADERS_B64}) 38 | set(HEADERS_INC inc/u2f.h inc/u2f_hid.h) 39 | source_group(headers\\inc FILES ${HEADERS_INC}) 40 | 41 | # ========== 42 | # Add support gnulib files 43 | # ========== 44 | set(GL_DIR ${CMAKE_SOURCE_DIR}/gl) 45 | set(SOURCE_GL ${GL_DIR}/sha256.c ${GL_DIR}/check-version.c ${GL_DIR}/strverscmp.c) 46 | set_source_files_properties(${GL_DIR}/check-version.c PROPERTIES COMPILE_DEFINITIONS VERSION="${VERSION}") 47 | source_group(sources\\gl FILES ${SOURCE_GL}) 48 | include_directories(${GL_DIR}) 49 | set(HEADERS_GL ${GL_DIR}/sha256.h ${GL_DIR}/check-version.h) 50 | source_group(headers\\gl FILES ${HEADERS_GL}) 51 | configure_file(${GL_DIR}/stdalign.in.h stdalign.h) 52 | 53 | # ========== 54 | # Import hidapi 55 | # ========== 56 | add_library(hidapi SHARED IMPORTED) 57 | set(HIDAPI_DIR hidapi CACHE PATH "Path to hidapi library") 58 | set(HIDAPI_BIN_DIR ${HIDAPI_DIR}/windows) 59 | 60 | set_target_properties(hidapi PROPERTIES 61 | IMPORTED_LOCATION_DEBUG ${HIDAPI_BIN_DIR}/Debug/hidapi.dll 62 | IMPORTED_IMPLIB_DEBUG ${HIDAPI_BIN_DIR}/Debug/hidapi.lib 63 | IMPORTED_LOCATION_RELEASE ${HIDAPI_BIN_DIR}/Release/hidapi.dll 64 | IMPORTED_IMPLIB_RELEASE ${HIDAPI_BIN_DIR}/Release/hidapi.lib 65 | INTERFACE_INCLUDE_DIRECTORIES ${HIDAPI_DIR}/hidapi) 66 | 67 | # ========== 68 | # Import json-c 69 | # ========== 70 | add_library(json-c SHARED IMPORTED) 71 | set(JSON-C_DIR json-c CACHE PATH "Path to json-c library") 72 | set(JSON-C_BIN_DIR ${JSON-C_DIR}) 73 | 74 | set_target_properties(json-c PROPERTIES 75 | IMPORTED_LOCATION_DEBUG ${JSON-C_BIN_DIR}/Debug/json-c.dll 76 | IMPORTED_IMPLIB_DEBUG ${JSON-C_BIN_DIR}/Debug/json-c.lib 77 | IMPORTED_LOCATION_RELEASE ${JSON-C_BIN_DIR}/Release/json-c.dll 78 | IMPORTED_IMPLIB_RELEASE ${JSON-C_BIN_DIR}/Release/json-c.lib 79 | INTERFACE_INCLUDE_DIRECTORIES ${JSON-C_DIR}) 80 | 81 | # ========== 82 | # Build as library 83 | # ========== 84 | add_library(u2f-host SHARED ${SOURCE} ${SOURCE_GL} ${HEADERS} ${HEADERS_B64} ${HEADERS_INC} ${HEADERS_STDINT} ${HEADERS_GL}) 85 | if(WIN32) 86 | set_target_properties(u2f-host PROPERTIES OUTPUT_NAME "libu2f-host-${LT_CURRENT}" VERSION ${VERSION} ) 87 | else() 88 | set_target_properties(u2f-host PROPERTIES OUTPUT_NAME "libu2f-host" VERSION "${LT_CURRENT}.${LT_AGE}.${LT_REVISION}" SOVERSION ${LT_CURRENT} ) 89 | endif() 90 | target_link_libraries(u2f-host hidapi json-c) 91 | -------------------------------------------------------------------------------- /u2f-host/cencode.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | 20 | /* 21 | cencoder.c - c source to a base64 encoding algorithm implementation 22 | 23 | This is part of the libb64 project, and has been placed in the public domain. 24 | For details, see http://sourceforge.net/projects/libb64 25 | */ 26 | 27 | #include 28 | 29 | const int CHARS_PER_LINE = 72; 30 | 31 | void 32 | base64_init_encodestate (base64_encodestate * state_in) 33 | { 34 | state_in->step = step_A; 35 | state_in->result = 0; 36 | state_in->stepcount = 0; 37 | } 38 | 39 | char 40 | base64_encode_value (char value_in) 41 | { 42 | static const char *encoding = 43 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; 44 | if (value_in > 63) 45 | return '='; 46 | return encoding[(int) value_in]; 47 | } 48 | 49 | int 50 | base64_encode_block (const char *plaintext_in, int length_in, char *code_out, 51 | base64_encodestate * state_in) 52 | { 53 | const char *plainchar = plaintext_in; 54 | const char *const plaintextend = plaintext_in + length_in; 55 | char *codechar = code_out; 56 | char result; 57 | char fragment; 58 | 59 | result = state_in->result; 60 | 61 | switch (state_in->step) 62 | { 63 | while (1) 64 | { 65 | case step_A: 66 | if (plainchar == plaintextend) 67 | { 68 | state_in->result = result; 69 | state_in->step = step_A; 70 | return codechar - code_out; 71 | } 72 | fragment = *plainchar++; 73 | result = (fragment & 0x0fc) >> 2; 74 | *codechar++ = base64_encode_value (result); 75 | result = (fragment & 0x003) << 4; 76 | case step_B: 77 | if (plainchar == plaintextend) 78 | { 79 | state_in->result = result; 80 | state_in->step = step_B; 81 | return codechar - code_out; 82 | } 83 | fragment = *plainchar++; 84 | result |= (fragment & 0x0f0) >> 4; 85 | *codechar++ = base64_encode_value (result); 86 | result = (fragment & 0x00f) << 2; 87 | case step_C: 88 | if (plainchar == plaintextend) 89 | { 90 | state_in->result = result; 91 | state_in->step = step_C; 92 | return codechar - code_out; 93 | } 94 | fragment = *plainchar++; 95 | result |= (fragment & 0x0c0) >> 6; 96 | *codechar++ = base64_encode_value (result); 97 | result = (fragment & 0x03f) >> 0; 98 | *codechar++ = base64_encode_value (result); 99 | 100 | ++(state_in->stepcount); 101 | if (state_in->stepcount == CHARS_PER_LINE / 4) 102 | { 103 | /* *codechar++ = '\n'; */ 104 | state_in->stepcount = 0; 105 | } 106 | } 107 | } 108 | /* control should not reach here */ 109 | return codechar - code_out; 110 | } 111 | 112 | int 113 | base64_encode_blockend (char *code_out, base64_encodestate * state_in) 114 | { 115 | char *codechar = code_out; 116 | 117 | switch (state_in->step) 118 | { 119 | case step_B: 120 | case step_C: 121 | *codechar++ = base64_encode_value (state_in->result); 122 | break; 123 | case step_A: 124 | break; 125 | } 126 | *codechar++ = '\0'; 127 | 128 | return codechar - code_out; 129 | } 130 | -------------------------------------------------------------------------------- /macosx.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | LIBJSONVERSION=0.12.1 17 | HIDAPIHASH=a6a622ffb680c55da0de787ff93b80280498330f 18 | PACKAGE=libu2f-host 19 | 20 | all: usage doit 21 | 22 | .PHONY: usage 23 | usage: 24 | @if test -z "$(VERSION)"; then \ 25 | echo "Try this instead:"; \ 26 | echo " make VERSION=[VERSION]"; \ 27 | echo "For example:"; \ 28 | echo " make VERSION=1.6.0"; \ 29 | exit 1; \ 30 | fi 31 | 32 | doit: 33 | rm -rf tmp && mkdir tmp && cd tmp && \ 34 | mkdir -p root/licenses && \ 35 | cp ../json-c-$(LIBJSONVERSION).tar.gz . || \ 36 | curl -O -L https://s3.amazonaws.com/json-c_releases/releases/json-c-$(LIBJSONVERSION).tar.gz && \ 37 | tar xfz json-c-$(LIBJSONVERSION).tar.gz && \ 38 | cd json-c-$(LIBJSONVERSION) && \ 39 | ./configure --prefix=$(PWD)/tmp$(ARCH)/root CFLAGS=-mmacosx-version-min=10.6 && \ 40 | make install check && \ 41 | cp COPYING $(PWD)/tmp$(ARCH)/root/licenses/json-c.txt && \ 42 | cd .. && \ 43 | git clone https://github.com/signal11/hidapi.git && \ 44 | cd hidapi && \ 45 | git checkout $(HIDAPIHASH) && \ 46 | ./bootstrap && \ 47 | ./configure --prefix=$(PWD)/tmp$(ARCH)/root CFLAGS=-mmacosx-version-min=10.6 && \ 48 | make install check && \ 49 | cp LICENSE-gpl3.txt $(PWD)/tmp$(ARCH)/root/licenses/hidapi.txt && \ 50 | cd .. && \ 51 | cp ../$(PACKAGE)-$(VERSION).tar.xz . && \ 52 | tar xfJ $(PACKAGE)-$(VERSION).tar.xz && \ 53 | cd $(PACKAGE)-$(VERSION)/ && \ 54 | PKG_CONFIG_PATH=$(PWD)/tmp$(ARCH)/root/lib/pkgconfig ./configure --prefix=$(PWD)/tmp$(ARCH)/root CFLAGS=-mmacosx-version-min=10.6 && \ 55 | make install check && \ 56 | install_name_tool -id @executable_path/../lib/libjson-c.2.dylib $(PWD)/tmp/root/lib/libjson-c.2.dylib && \ 57 | install_name_tool -id @executable_path/../lib/libhidapi.0.dylib $(PWD)/tmp/root/lib/libhidapi.0.dylib && \ 58 | install_name_tool -id @executable_path/../lib/libu2f-host.0.dylib $(PWD)/tmp/root/lib/libu2f-host.0.dylib && \ 59 | install_name_tool -change $(PWD)/tmp/root/lib/libjson-c.2.dylib @executable_path/../lib/libjson-c.2.dylib $(PWD)/tmp/root/lib/libu2f-host.0.dylib && \ 60 | install_name_tool -change $(PWD)/tmp/root/lib/libhidapi.0.dylib @executable_path/../lib/libhidapi.0.dylib $(PWD)/tmp/root/lib/libu2f-host.0.dylib && \ 61 | for executable in $(PWD)/tmp/root/bin/*; do \ 62 | install_name_tool -change $(PWD)/tmp/root/lib/libjson-c.2.dylib @executable_path/../lib/libjson-c.2.dylib $$executable ; \ 63 | install_name_tool -change $(PWD)/tmp/root/lib/libhidapi.0.dylib @executable_path/../lib/libhidapi.0.dylib $$executable ; \ 64 | install_name_tool -change $(PWD)/tmp/root/lib/libu2f-host.0.dylib @executable_path/../lib/libu2f-host.0.dylib $$executable ; \ 65 | done && \ 66 | rm $(PWD)/tmp/root/lib/*.la && \ 67 | rm -rf $(PWD)/tmp/root/lib/pkgconfig && \ 68 | cp COPYING $(PWD)/tmp$(ARCH)/root/licenses/$(PACKAGE).txt && \ 69 | cd .. && \ 70 | cd root && \ 71 | zip -r ../../$(PACKAGE)-$(VERSION)-mac.zip * 72 | 73 | upload: 74 | @if test ! -d "$(YUBICO_WWW_REPO)"; then \ 75 | echo "www repo not found!"; \ 76 | echo "Make sure that YUBICO_WWW_REPO is set"; \ 77 | exit 1; \ 78 | fi 79 | gpg --detach-sign --default-key $(PGPKEYID) $(PACKAGE)-$(VERSION)-mac.zip 80 | gpg --verify $(PACKAGE)-$(VERSION)-mac.zip.sig 81 | $(YUBICO_WWW_REPO)/publish $(PACKAGE) $(VERSION) $(PACKAGE)-$(VERSION)-mac.zip* 82 | -------------------------------------------------------------------------------- /u2f-host/cdecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | 20 | /* 21 | cdecoder.c - c source to a base64 decoding algorithm implementation 22 | 23 | This is part of the libb64 project, and has been placed in the public domain. 24 | For details, see http://sourceforge.net/projects/libb64 25 | */ 26 | 27 | #include 28 | 29 | int 30 | base64_decode_value (char value_in) 31 | { 32 | static const char decoding[] = 33 | { 62, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, 34 | -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 35 | 19, 20, 21, 22, 23, 24, 25, 36 | -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37 | 38, 39, 40, 41, 42, 43, 44, 38 | 45, 46, 47, 48, 49, 50, 51 39 | }; 40 | static const char decoding_size = sizeof (decoding); 41 | value_in -= 45; 42 | if (value_in < 0 || value_in >= decoding_size) 43 | return -1; 44 | return decoding[(int) value_in]; 45 | } 46 | 47 | void 48 | base64_init_decodestate (base64_decodestate * state_in) 49 | { 50 | state_in->step = step_a; 51 | state_in->plainchar = 0; 52 | } 53 | 54 | int 55 | base64_decode_block (const char *code_in, const int length_in, 56 | char *plaintext_out, base64_decodestate * state_in) 57 | { 58 | const char *codechar = code_in; 59 | char *plainchar = plaintext_out; 60 | char fragment; 61 | 62 | *plainchar = state_in->plainchar; 63 | 64 | switch (state_in->step) 65 | { 66 | while (1) 67 | { 68 | case step_a: 69 | do 70 | { 71 | if (codechar == code_in + length_in) 72 | { 73 | state_in->step = step_a; 74 | state_in->plainchar = *plainchar; 75 | return plainchar - plaintext_out; 76 | } 77 | fragment = (char) base64_decode_value (*codechar++); 78 | } 79 | while (fragment < 0); 80 | *plainchar = (fragment & 0x03f) << 2; 81 | case step_b: 82 | do 83 | { 84 | if (codechar == code_in + length_in) 85 | { 86 | state_in->step = step_b; 87 | state_in->plainchar = *plainchar; 88 | return plainchar - plaintext_out; 89 | } 90 | fragment = (char) base64_decode_value (*codechar++); 91 | } 92 | while (fragment < 0); 93 | *plainchar++ |= (fragment & 0x030) >> 4; 94 | *plainchar = (fragment & 0x00f) << 4; 95 | case step_c: 96 | do 97 | { 98 | if (codechar == code_in + length_in) 99 | { 100 | state_in->step = step_c; 101 | state_in->plainchar = *plainchar; 102 | return plainchar - plaintext_out; 103 | } 104 | fragment = (char) base64_decode_value (*codechar++); 105 | } 106 | while (fragment < 0); 107 | *plainchar++ |= (fragment & 0x03c) >> 2; 108 | *plainchar = (fragment & 0x003) << 6; 109 | case step_d: 110 | do 111 | { 112 | if (codechar == code_in + length_in) 113 | { 114 | state_in->step = step_d; 115 | state_in->plainchar = *plainchar; 116 | return plainchar - plaintext_out; 117 | } 118 | fragment = (char) base64_decode_value (*codechar++); 119 | } 120 | while (fragment < 0); 121 | *plainchar++ |= (fragment & 0x03f); 122 | } 123 | } 124 | /* control should not reach here */ 125 | return plainchar - plaintext_out; 126 | } 127 | -------------------------------------------------------------------------------- /gtk-doc/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | # We require automake 1.6 at least. 4 | AUTOMAKE_OPTIONS = 1.6 5 | 6 | # This is a blank Makefile.am for using gtk-doc. 7 | # Copy this to your project's API docs directory and modify the variables to 8 | # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples 9 | # of using the various options. 10 | 11 | # The name of the module, e.g. 'glib'. 12 | DOC_MODULE=u2f-host 13 | 14 | # Uncomment for versioned docs and specify the version of the module, e.g. '2'. 15 | #DOC_MODULE_VERSION=2 16 | 17 | 18 | # The top-level XML file (SGML in the past). You can change this if you want to. 19 | DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml 20 | 21 | # Directories containing the source code. 22 | # gtk-doc will search all .c and .h files beneath these paths 23 | # for inline comments documenting functions and macros. 24 | # e.g. DOC_SOURCE_DIR=$(top_srcdir)/gtk $(top_srcdir)/gdk 25 | DOC_SOURCE_DIR=$(top_srcdir)/u2f-host $(top_builddir)/u2f-host 26 | 27 | # Extra options to pass to gtkdoc-scangobj. Not normally needed. 28 | SCANGOBJ_OPTIONS= 29 | 30 | # Extra options to supply to gtkdoc-scan. 31 | # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" 32 | SCAN_OPTIONS= 33 | 34 | # Extra options to supply to gtkdoc-mkdb. 35 | # e.g. MKDB_OPTIONS=--xml-mode --output-format=xml 36 | MKDB_OPTIONS=--xml-mode --output-format=xml 37 | 38 | # Extra options to supply to gtkdoc-mktmpl 39 | # e.g. MKTMPL_OPTIONS=--only-section-tmpl 40 | MKTMPL_OPTIONS= 41 | 42 | # Extra options to supply to gtkdoc-mkhtml 43 | MKHTML_OPTIONS= 44 | 45 | # Extra options to supply to gtkdoc-fixref. Not normally needed. 46 | # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html 47 | FIXXREF_OPTIONS= 48 | 49 | # Used for dependencies. The docs will be rebuilt if any of these change. 50 | # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h 51 | # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c 52 | HFILE_GLOB=$(top_srcdir)/u2f-host/*.h $(top_builddir)/u2f-host/*.h 53 | CFILE_GLOB=$(top_srcdir)/u2f-host/*.c 54 | 55 | # Extra header to include when scanning, which are not under DOC_SOURCE_DIR 56 | # e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h 57 | EXTRA_HFILES= 58 | 59 | # Header files or dirs to ignore when scanning. Use base file/dir names 60 | # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code 61 | IGNORE_HFILES=internal.h sha256.h cdecode.h cencode.h u2f.h u2f_hid.h 62 | 63 | # Images to copy into HTML directory. 64 | # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png 65 | HTML_IMAGES= 66 | 67 | # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). 68 | # e.g. content_files=running.sgml building.sgml changes-2.0.sgml 69 | content_files= 70 | 71 | # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded 72 | # These files must be listed here *and* in content_files 73 | # e.g. expand_content_files=running.sgml 74 | expand_content_files= 75 | 76 | # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. 77 | # Only needed if you are using gtkdoc-scangobj to dynamically query widget 78 | # signals and properties. 79 | # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) 80 | # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) 81 | GTKDOC_CFLAGS= 82 | GTKDOC_LIBS= 83 | 84 | # This includes the standard gtk-doc make rules, copied by gtkdocize. 85 | include $(srcdir)/gtk-doc.make 86 | 87 | # Other files to distribute 88 | # e.g. EXTRA_DIST += version.xml.in 89 | EXTRA_DIST += 90 | 91 | # Files not to distribute 92 | # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types 93 | # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt 94 | #DISTCLEANFILES += 95 | 96 | # Comment this out if you want 'make check' to test you doc status 97 | # and run some sanity checks 98 | if ENABLE_GTK_DOC 99 | TESTS_ENVIRONMENT = cd $(srcdir) && \ 100 | DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ 101 | SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) 102 | #TESTS = $(GTKDOC_CHECK) 103 | endif 104 | 105 | -include $(top_srcdir)/git.mk 106 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | libu2f-host NEWS -- History of user visible changes. 2 | 3 | * Version 1.1.11 (unreleased) 4 | 5 | * Version 1.1.10 (released 2019-05-15) 6 | 7 | ** Add new devices to udev rules. 8 | 9 | ** Fix a potentially uninitialized buffer. 10 | 11 | * Version 1.1.9 (released 2019-03-06) 12 | 13 | ** Fix CID copying from the init response. 14 | This broke compatibility with some devices. 15 | 16 | * Version 1.1.8 (released 2019-03-05) 17 | 18 | ** Add udev rules. 19 | 20 | ** Drop 70-old-u2f.rules and use 70-u2f.rules for everything. 21 | 22 | ** Use a random nonce for setting up CID to prevent fingerprinting. 23 | 24 | ** Parse the response to init in a more stable way. 25 | The old parser could leak 4 bytes of uninitialized stack back to the device. 26 | Reported by Christian Reitter. 27 | 28 | * Version 1.1.7 (released 2019-01-08) 29 | 30 | ** Fix for trusting length from deivce in device init. 31 | Reported by Christian Reitter. 32 | 33 | ** Fix for buffer overflow when receiving data from device. 34 | 35 | ** Add udev rules for some new devices. 36 | 37 | * Version 1.1.6 (released 2018-05-15) 38 | 39 | ** Change waiting logic on authenticate to allow for faster feedback. 40 | 41 | * Version 1.1.5 (released 2018-03-07) 42 | 43 | ** Fix refcount when adding json_objects. 44 | 45 | ** Handle fido2 keepalive. 46 | 47 | ** Add udev rules for more devices. 48 | 49 | * Version 1.1.4 (released 2017-09-01) 50 | 51 | ** Added more u2f devices to the udev rulesets. 52 | 53 | ** Increase buffer size, allowing for bigger certificates. 54 | 55 | ** Add u2f.conf.sample for FreeBSD permission handling. 56 | 57 | * Version 1.1.3 (released 2016-10-04) 58 | 59 | ** Added more u2f devices to the udev rulesets. 60 | 61 | ** Fixup mac builds. 62 | 63 | * Version 1.1.2 (released 2016-06-22) 64 | 65 | ** Make authenticate return U2FH_OK if touch is set to not needed. 66 | Also minor fixes to error output of authenticate. 67 | 68 | ** Documentation fixes. 69 | 70 | ** Compilation fixes on visual studio. 71 | 72 | ** Add udev rules for Feitian devices. 73 | 74 | ** Add optional cmake build. 75 | 76 | ** Change license of the commandline tool to LGPL 2.1+ 77 | 78 | * Version 1.1.1 (released 2016-03-14) 79 | 80 | ** Use correct index in u2fh_devs_discover() 81 | 82 | ** Fix an issue where we left the authenticate loop early. 83 | 84 | ** Fix an issue where authenticate remembered which devices to skip. 85 | 86 | ** Stop validating the scheme of the origin. 87 | 88 | ** Fixup a crash in u2fh_devs_discover() with closing unplugged devices. 89 | 90 | ** Documentation fixes. 91 | 92 | * Version 1.1.0 (released 2016-02-15) 93 | 94 | ** Add udev rules for more devices. 95 | 96 | ** Don't return success when no data is received. 97 | 98 | ** Fix typos. 99 | 100 | ** Make send_apdu send data like chrome does. 101 | 102 | ** Don't release json object that we don't own no more. 103 | 104 | ** Don't do memcmp on uninitialized memory. 105 | 106 | ** Add u2fh_authenticate2() and u2fh_register2(). 107 | 108 | ** Remove base64 padding (required by spec). 109 | 110 | ** Use unsigned ints to prevent buffer overflows. 111 | 112 | * Version 1.0.0 (released 2015-08-27) 113 | 114 | ** Add udev rules for older version of udev. 115 | 116 | ** Add pam:// as an allowed protocol. 117 | 118 | ** Stop using sleep(), use Sleep() on windows and usleep() on others. 119 | 120 | ** Fixup tool name in help and manpage. 121 | 122 | ** Add a timeout to the register and authenticate actions. 123 | 124 | * Version 0.0.4 (released 2015-01-22) 125 | 126 | ** Add an exponential growing timeout for slow devices (PlugUp). 127 | 128 | * Version 0.0.3 (released 2015-01-08) 129 | 130 | ** Change license to LGPLv2+ for the library. 131 | 132 | ** Some improvements to internal communication code. 133 | ** Some debug mode improvements, from Bram Vandoren. 134 | 135 | * Version 0.0.2 (released 2014-11-28) 136 | 137 | ** Add more devices to udev. 138 | 139 | * Version 0.0.1 (released 2014-10-29) 140 | 141 | ** Use semantic versioning. 142 | ** Correct json key for keyHandle in signResponse 143 | ** Fix the udev rule 144 | ** Add option to install udev rule 145 | 146 | * Version 0.0 (released 2014-09-16) 147 | 148 | ** Initial release. 149 | -------------------------------------------------------------------------------- /gl/sha256.h: -------------------------------------------------------------------------------- 1 | /* Declarations of functions and data types used for SHA256 and SHA224 sum 2 | library functions. 3 | Copyright (C) 2005-2006, 2008-2015 Free Software Foundation, Inc. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . */ 17 | 18 | #ifndef SHA256_H 19 | # define SHA256_H 1 20 | 21 | # include 22 | # include 23 | 24 | # if HAVE_OPENSSL_SHA256 25 | # include 26 | # endif 27 | 28 | # ifdef __cplusplus 29 | extern "C" { 30 | # endif 31 | 32 | enum { SHA224_DIGEST_SIZE = 224 / 8 }; 33 | enum { SHA256_DIGEST_SIZE = 256 / 8 }; 34 | 35 | # if HAVE_OPENSSL_SHA256 36 | # define GL_OPENSSL_NAME 224 37 | # include "gl_openssl.h" 38 | # define GL_OPENSSL_NAME 256 39 | # include "gl_openssl.h" 40 | # else 41 | /* Structure to save state of computation between the single steps. */ 42 | struct sha256_ctx 43 | { 44 | uint32_t state[8]; 45 | 46 | uint32_t total[2]; 47 | size_t buflen; 48 | uint32_t buffer[32]; 49 | }; 50 | 51 | /* Initialize structure containing state of computation. */ 52 | extern void sha256_init_ctx (struct sha256_ctx *ctx); 53 | extern void sha224_init_ctx (struct sha256_ctx *ctx); 54 | 55 | /* Starting with the result of former calls of this function (or the 56 | initialization function update the context for the next LEN bytes 57 | starting at BUFFER. 58 | It is necessary that LEN is a multiple of 64!!! */ 59 | extern void sha256_process_block (const void *buffer, size_t len, 60 | struct sha256_ctx *ctx); 61 | 62 | /* Starting with the result of former calls of this function (or the 63 | initialization function update the context for the next LEN bytes 64 | starting at BUFFER. 65 | It is NOT required that LEN is a multiple of 64. */ 66 | extern void sha256_process_bytes (const void *buffer, size_t len, 67 | struct sha256_ctx *ctx); 68 | 69 | /* Process the remaining bytes in the buffer and put result from CTX 70 | in first 32 (28) bytes following RESBUF. The result is always in little 71 | endian byte order, so that a byte-wise output yields to the wanted 72 | ASCII representation of the message digest. */ 73 | extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf); 74 | extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf); 75 | 76 | 77 | /* Put result from CTX in first 32 (28) bytes following RESBUF. The result is 78 | always in little endian byte order, so that a byte-wise output yields 79 | to the wanted ASCII representation of the message digest. */ 80 | extern void *sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf); 81 | extern void *sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf); 82 | 83 | 84 | /* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER. The 85 | result is always in little endian byte order, so that a byte-wise 86 | output yields to the wanted ASCII representation of the message 87 | digest. */ 88 | extern void *sha256_buffer (const char *buffer, size_t len, void *resblock); 89 | extern void *sha224_buffer (const char *buffer, size_t len, void *resblock); 90 | 91 | # endif 92 | /* Compute SHA256 (SHA224) message digest for bytes read from STREAM. The 93 | resulting message digest number will be written into the 32 (28) bytes 94 | beginning at RESBLOCK. */ 95 | extern int sha256_stream (FILE *stream, void *resblock); 96 | extern int sha224_stream (FILE *stream, void *resblock); 97 | 98 | 99 | # ifdef __cplusplus 100 | } 101 | # endif 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /gl/gl_openssl.h: -------------------------------------------------------------------------------- 1 | /* gl_openssl.h -- wrap openssl crypto hash routines in gnulib interface 2 | 3 | Copyright (C) 2013-2015 Free Software Foundation, Inc. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . */ 17 | 18 | /* Written by Pádraig Brady */ 19 | 20 | #ifndef GL_OPENSSL_NAME 21 | # error "Please define GL_OPENSSL_NAME to 1,5,256 etc." 22 | #endif 23 | 24 | #ifndef _GL_INLINE_HEADER_BEGIN 25 | # error "Please include config.h first." 26 | #endif 27 | _GL_INLINE_HEADER_BEGIN 28 | #ifndef GL_OPENSSL_INLINE 29 | # define GL_OPENSSL_INLINE _GL_INLINE 30 | #endif 31 | 32 | /* Concatenate two preprocessor tokens. */ 33 | #define _GLCRYPTO_CONCAT_(prefix, suffix) prefix##suffix 34 | #define _GLCRYPTO_CONCAT(prefix, suffix) _GLCRYPTO_CONCAT_ (prefix, suffix) 35 | 36 | #if GL_OPENSSL_NAME == 5 37 | # define OPENSSL_ALG md5 38 | #else 39 | # define OPENSSL_ALG _GLCRYPTO_CONCAT (sha, GL_OPENSSL_NAME) 40 | #endif 41 | 42 | /* Context type mappings. */ 43 | #if BASE_OPENSSL_TYPE != GL_OPENSSL_NAME 44 | # undef BASE_OPENSSL_TYPE 45 | # if GL_OPENSSL_NAME == 224 46 | # define BASE_OPENSSL_TYPE 256 47 | # elif GL_OPENSSL_NAME == 384 48 | # define BASE_OPENSSL_TYPE 512 49 | # endif 50 | # define md5_CTX MD5_CTX 51 | # define sha1_CTX SHA_CTX 52 | # define sha224_CTX SHA256_CTX 53 | # define sha224_ctx sha256_ctx 54 | # define sha256_CTX SHA256_CTX 55 | # define sha384_CTX SHA512_CTX 56 | # define sha384_ctx sha512_ctx 57 | # define sha512_CTX SHA512_CTX 58 | # undef _gl_CTX 59 | # undef _gl_ctx 60 | # define _gl_CTX _GLCRYPTO_CONCAT (OPENSSL_ALG, _CTX) /* openssl type. */ 61 | # define _gl_ctx _GLCRYPTO_CONCAT (OPENSSL_ALG, _ctx) /* gnulib type. */ 62 | 63 | struct _gl_ctx { _gl_CTX CTX; }; 64 | #endif 65 | 66 | /* Function name mappings. */ 67 | #define md5_prefix MD5 68 | #define sha1_prefix SHA1 69 | #define sha224_prefix SHA224 70 | #define sha256_prefix SHA256 71 | #define sha384_prefix SHA384 72 | #define sha512_prefix SHA512 73 | #define _GLCRYPTO_PREFIX _GLCRYPTO_CONCAT (OPENSSL_ALG, _prefix) 74 | #define OPENSSL_FN(suffix) _GLCRYPTO_CONCAT (_GLCRYPTO_PREFIX, suffix) 75 | #define GL_CRYPTO_FN(suffix) _GLCRYPTO_CONCAT (OPENSSL_ALG, suffix) 76 | 77 | GL_OPENSSL_INLINE void 78 | GL_CRYPTO_FN (_init_ctx) (struct _gl_ctx *ctx) 79 | { (void) OPENSSL_FN (_Init) ((_gl_CTX *) ctx); } 80 | 81 | /* These were never exposed by gnulib. */ 82 | #if ! (GL_OPENSSL_NAME == 224 || GL_OPENSSL_NAME == 384) 83 | GL_OPENSSL_INLINE void 84 | GL_CRYPTO_FN (_process_bytes) (const void *buf, size_t len, struct _gl_ctx *ctx) 85 | { OPENSSL_FN (_Update) ((_gl_CTX *) ctx, buf, len); } 86 | 87 | GL_OPENSSL_INLINE void 88 | GL_CRYPTO_FN (_process_block) (const void *buf, size_t len, struct _gl_ctx *ctx) 89 | { GL_CRYPTO_FN (_process_bytes) (buf, len, ctx); } 90 | #endif 91 | 92 | GL_OPENSSL_INLINE void * 93 | GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void *res) 94 | { OPENSSL_FN (_Final) ((unsigned char *) res, (_gl_CTX *) ctx); return res; } 95 | 96 | GL_OPENSSL_INLINE void * 97 | GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void *res) 98 | { return OPENSSL_FN () ((const unsigned char *) buf, len, (unsigned char *) res); } 99 | 100 | GL_OPENSSL_INLINE void * 101 | GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void *res) 102 | { 103 | /* Assume any unprocessed bytes in ctx are not to be ignored. */ 104 | _gl_CTX tmp_ctx = *(_gl_CTX *) ctx; 105 | OPENSSL_FN (_Final) ((unsigned char *) res, &tmp_ctx); 106 | return res; 107 | } 108 | 109 | /* Undef so we can include multiple times. */ 110 | #undef GL_CRYPTO_FN 111 | #undef OPENSSL_FN 112 | #undef _GLCRYPTO_PREFIX 113 | #undef OPENSSL_ALG 114 | #undef GL_OPENSSL_NAME 115 | 116 | _GL_INLINE_HEADER_END 117 | -------------------------------------------------------------------------------- /src/u2f-host.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "cmdline.h" 28 | 29 | int 30 | main (int argc, char *argv[]) 31 | { 32 | int exit_code = EXIT_FAILURE; 33 | struct gengetopt_args_info args_info; 34 | char challenge[BUFSIZ]; 35 | size_t chal_len; 36 | char response[2048] = {0}; 37 | size_t response_len = sizeof (response); 38 | u2fh_devs *devs = NULL; 39 | u2fh_cmdflags flags = 0; 40 | u2fh_rc rc; 41 | 42 | if (cmdline_parser (argc, argv, &args_info) != 0) 43 | exit (EXIT_FAILURE); 44 | 45 | if (args_info.help_given) 46 | { 47 | cmdline_parser_print_help (); 48 | printf ("\nReport bugs at .\n"); 49 | exit (EXIT_SUCCESS); 50 | } 51 | 52 | chal_len = fread (challenge, 1, sizeof (challenge), stdin); 53 | if (!feof (stdin) || ferror (stdin)) 54 | { 55 | perror ("read"); 56 | exit (EXIT_FAILURE); 57 | } 58 | 59 | rc = u2fh_global_init (args_info.debug_flag ? U2FH_DEBUG : 0); 60 | if (rc != U2FH_OK) 61 | { 62 | fprintf (stderr, "error: u2fh_global_init (%d): %s\n", rc, 63 | u2fh_strerror (rc)); 64 | exit (EXIT_FAILURE); 65 | } 66 | 67 | rc = u2fh_devs_init (&devs); 68 | if (rc != U2FH_OK) 69 | { 70 | fprintf (stderr, "error: u2fh_devs_init (%d): %s\n", rc, 71 | u2fh_strerror (rc)); 72 | goto done; 73 | } 74 | 75 | rc = u2fh_devs_discover (devs, NULL); 76 | if (rc != U2FH_OK) 77 | { 78 | fprintf (stderr, "error: u2fh_devs_discover (%d): %s\n", rc, 79 | u2fh_strerror (rc)); 80 | goto done; 81 | } 82 | 83 | switch (args_info.action_arg) 84 | { 85 | case action_arg_register: 86 | case action_arg_authenticate: 87 | if (args_info.origin_arg == NULL) 88 | { 89 | fprintf (stderr, "error: origin URL empty, use -o to specify it\n"); 90 | exit (EXIT_FAILURE); 91 | } 92 | 93 | if (args_info.action_arg == action_arg_register) 94 | { 95 | rc = u2fh_register2 (devs, challenge, args_info.origin_arg, 96 | response, &response_len, 97 | args_info.touch_flag ? 0 : 98 | U2FH_REQUEST_USER_PRESENCE); 99 | } 100 | else 101 | { 102 | rc = u2fh_authenticate2 (devs, challenge, args_info.origin_arg, 103 | response, &response_len, 104 | args_info.touch_flag ? 0 : 105 | U2FH_REQUEST_USER_PRESENCE); 106 | } 107 | break; 108 | case action_arg_sendrecv: 109 | { 110 | uint8_t command; 111 | unsigned char out[2048]; 112 | size_t outlen = sizeof (out); 113 | if (args_info.command_arg == NULL) 114 | { 115 | fprintf (stderr, "error: empty sendrecv command.\n"); 116 | exit (EXIT_FAILURE); 117 | } 118 | sscanf (args_info.command_arg, "%hhx", &command); 119 | rc = 120 | u2fh_sendrecv (devs, 0, command, challenge, chal_len - 1, out, 121 | &outlen); 122 | } 123 | break; 124 | case action__NULL: 125 | default: 126 | fprintf (stderr, "error: unknown action.\n"); 127 | goto done; 128 | } 129 | if (rc != U2FH_OK) 130 | { 131 | fprintf (stderr, "error (%d): %s\n", rc, u2fh_strerror (rc)); 132 | goto done; 133 | } 134 | 135 | if (strlen (response)) 136 | { 137 | printf ("%s\n", response); 138 | } 139 | 140 | exit_code = EXIT_SUCCESS; 141 | 142 | done: 143 | u2fh_devs_done (devs); 144 | u2fh_global_done (); 145 | 146 | exit (exit_code); 147 | } 148 | -------------------------------------------------------------------------------- /gl/strverscmp.c: -------------------------------------------------------------------------------- 1 | /* Compare strings while treating digits characters numerically. 2 | Copyright (C) 1997, 2000, 2002, 2004, 2006, 2009-2015 Free Software 3 | Foundation, Inc. 4 | This file is part of the GNU C Library. 5 | Contributed by Jean-François Bignolles , 1997. 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU Lesser General Public License as published by 9 | the Free Software Foundation; either version 2.1, or (at your option) 10 | any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License along 18 | with this program; if not, see . */ 19 | 20 | #if !_LIBC 21 | # include 22 | #endif 23 | 24 | #include 25 | #include 26 | 27 | /* states: S_N: normal, S_I: comparing integral part, S_F: comparing 28 | fractional parts, S_Z: idem but with leading Zeroes only */ 29 | #define S_N 0x0 30 | #define S_I 0x4 31 | #define S_F 0x8 32 | #define S_Z 0xC 33 | 34 | /* result_type: CMP: return diff; LEN: compare using len_diff/diff */ 35 | #define CMP 2 36 | #define LEN 3 37 | 38 | 39 | /* ISDIGIT differs from isdigit, as follows: 40 | - Its arg may be any int or unsigned int; it need not be an unsigned char 41 | or EOF. 42 | - It's typically faster. 43 | POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to 44 | isdigit unless it's important to use the locale's definition 45 | of "digit" even when the host does not conform to POSIX. */ 46 | #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) 47 | 48 | #undef __strverscmp 49 | #undef strverscmp 50 | 51 | #ifndef weak_alias 52 | # define __strverscmp strverscmp 53 | #endif 54 | 55 | /* Compare S1 and S2 as strings holding indices/version numbers, 56 | returning less than, equal to or greater than zero if S1 is less than, 57 | equal to or greater than S2 (for more info, see the texinfo doc). 58 | */ 59 | 60 | int 61 | __strverscmp (const char *s1, const char *s2) 62 | { 63 | const unsigned char *p1 = (const unsigned char *) s1; 64 | const unsigned char *p2 = (const unsigned char *) s2; 65 | unsigned char c1, c2; 66 | int state; 67 | int diff; 68 | 69 | /* Symbol(s) 0 [1-9] others (padding) 70 | Transition (10) 0 (01) d (00) x (11) - */ 71 | static const unsigned int next_state[] = 72 | { 73 | /* state x d 0 - */ 74 | /* S_N */ S_N, S_I, S_Z, S_N, 75 | /* S_I */ S_N, S_I, S_I, S_I, 76 | /* S_F */ S_N, S_F, S_F, S_F, 77 | /* S_Z */ S_N, S_F, S_Z, S_Z 78 | }; 79 | 80 | static const int result_type[] = 81 | { 82 | /* state x/x x/d x/0 x/- d/x d/d d/0 d/- 83 | 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */ 84 | 85 | /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, 86 | CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 87 | /* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP, 88 | 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, 89 | /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, 90 | CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 91 | /* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP, 92 | -1, CMP, CMP, CMP 93 | }; 94 | 95 | if (p1 == p2) 96 | return 0; 97 | 98 | c1 = *p1++; 99 | c2 = *p2++; 100 | /* Hint: '0' is a digit too. */ 101 | state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0)); 102 | 103 | while ((diff = c1 - c2) == 0 && c1 != '\0') 104 | { 105 | state = next_state[state]; 106 | c1 = *p1++; 107 | c2 = *p2++; 108 | state |= (c1 == '0') + (ISDIGIT (c1) != 0); 109 | } 110 | 111 | state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))]; 112 | 113 | switch (state) 114 | { 115 | case CMP: 116 | return diff; 117 | 118 | case LEN: 119 | while (ISDIGIT (*p1++)) 120 | if (!ISDIGIT (*p2++)) 121 | return 1; 122 | 123 | return ISDIGIT (*p2) ? -1 : diff; 124 | 125 | default: 126 | return state; 127 | } 128 | } 129 | #ifdef weak_alias 130 | weak_alias (__strverscmp, strverscmp) 131 | #endif 132 | -------------------------------------------------------------------------------- /u2f.conf.sample: -------------------------------------------------------------------------------- 1 | # Allow members of group u2f to access U2F devices 2 | 3 | # Yubico Yubikey 4 | notify 100 { 5 | match "system" "USB"; 6 | match "subsystem" "DEVICE"; 7 | match "type" "ATTACH"; 8 | match "vendor" "0x1050"; 9 | match "product" "(0x0113|0x0114|0x0115|0x0116|0x0120|0x0121|0x0200|0x0402|0x0403|0x0406|0x0407|0x0410)"; 10 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 11 | }; 12 | 13 | # Happlink (formerly Plug-Up) Security KEY 14 | notify 100 { 15 | match "system" "USB"; 16 | match "subsystem" "DEVICE"; 17 | match "type" "ATTACH"; 18 | match "vendor" "0x2581"; 19 | match "product" "0xf1d0"; 20 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 21 | }; 22 | 23 | # Neowave Keydo and Keydo AES 24 | notify 100 { 25 | match "system" "USB"; 26 | match "subsystem" "DEVICE"; 27 | match "type" "ATTACH"; 28 | match "vendor" "0x1e0d"; 29 | match "product" "(0xf1d0|0xf1ae)"; 30 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 31 | }; 32 | 33 | # HyperSecu HyperFIDO 34 | notify 100 { 35 | match "system" "USB"; 36 | match "subsystem" "DEVICE"; 37 | match "type" "ATTACH"; 38 | match "vendor" "(0x096e|0x2ccf)"; 39 | match "product" "0x0880"; 40 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 41 | }; 42 | 43 | # Feitian ePass FIDO, BioPass FIDO2 44 | notify 100 { 45 | match "system" "USB"; 46 | match "subsystem" "DEVICE"; 47 | match "type" "ATTACH"; 48 | match "vendor" "0x096e"; 49 | match "product" "(0x0850|0x0852|0x0853|0x0854|0x0856|0x0858|0x085a|0x085b|0x085d|0x0866|0x0867)"; 50 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 51 | }; 52 | 53 | # JaCarta U2F 54 | notify 100 { 55 | match "system" "USB"; 56 | match "subsystem" "DEVICE"; 57 | match "type" "ATTACH"; 58 | match "vendor" "0x24dc"; 59 | match "product" "0x0101|0x0501"; 60 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 61 | }; 62 | 63 | # U2F Zero 64 | notify 100 { 65 | match "system" "USB"; 66 | match "subsystem" "DEVICE"; 67 | match "type" "ATTACH"; 68 | match "vendor" "0x10c4"; 69 | match "product" "0x8acf"; 70 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 71 | }; 72 | 73 | # VASCO SeccureClick 74 | notify 100 { 75 | match "system" "USB"; 76 | match "subsystem" "DEVICE"; 77 | match "type" "ATTACH"; 78 | match "vendor" "0x1a44"; 79 | match "product" "0x00bb"; 80 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 81 | }; 82 | 83 | # Bluink Key 84 | notify 100 { 85 | match "system" "USB"; 86 | match "subsystem" "DEVICE"; 87 | match "type" "ATTACH"; 88 | match "vendor" "0x2abe"; 89 | match "product" "0x1002"; 90 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 91 | }; 92 | 93 | # Thetis Key 94 | notify 100 { 95 | match "system" "USB"; 96 | match "subsystem" "DEVICE"; 97 | match "type" "ATTACH"; 98 | match "vendor" "0x1ea8"; 99 | match "product" "0xf025"; 100 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 101 | }; 102 | 103 | # Nitrokey FIDO U2F, Nitrokey FIDO2, Safetech SafeKey 104 | notify 100 { 105 | match "system" "USB"; 106 | match "subsystem" "DEVICE"; 107 | match "type" "ATTACH"; 108 | match "vendor" "0x20a0"; 109 | match "product" "(0x4287|0x42b1|0x42b3)"; 110 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 111 | }; 112 | 113 | # Google Titan U2F 114 | notify 100 { 115 | match "system" "USB"; 116 | match "subsystem" "DEVICE"; 117 | match "type" "ATTACH"; 118 | match "vendor" "0x18d1"; 119 | match "product" "0x5026"; 120 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 121 | }; 122 | 123 | # Tomu board + chopstx U2F + SoloKeys 124 | notify 100 { 125 | match "system" "USB"; 126 | match "subsystem" "DEVICE"; 127 | match "type" "ATTACH"; 128 | match "vendor" "0x0483"; 129 | match "product" "(0xcdab|0xa2ca)"; 130 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 131 | }; 132 | 133 | # SoloKeys 134 | notify 100 { 135 | match "system" "USB"; 136 | match "subsystem" "DEVICE"; 137 | match "type" "ATTACH"; 138 | match "vendor" "0x1209"; 139 | match "product" "(0x5070|0x50b0)"; 140 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 141 | }; 142 | 143 | # GoTrust Idem Key 144 | notify 100 { 145 | match "system" "USB"; 146 | match "subsystem" "DEVICE"; 147 | match "type" "ATTACH"; 148 | match "vendor" "0x1fc9"; 149 | match "product" "0xf143"; 150 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 151 | }; 152 | 153 | # ellipticSecure MIRKey 154 | notify 100 { 155 | match "system" "USB"; 156 | match "subsystem" "DEVICE"; 157 | match "type" "ATTACH"; 158 | match "vendor" "0x0483"; 159 | match "product" "0xa2ac"; 160 | action "chgrp u2f /dev/$cdev; chmod g+rw /dev/$cdev"; 161 | }; 162 | -------------------------------------------------------------------------------- /gl/m4/extern-inline.m4: -------------------------------------------------------------------------------- 1 | dnl 'extern inline' a la ISO C99. 2 | 3 | dnl Copyright 2012-2015 Free Software Foundation, Inc. 4 | dnl This file is free software; the Free Software Foundation 5 | dnl gives unlimited permission to copy and/or distribute it, 6 | dnl with or without modifications, as long as this notice is preserved. 7 | 8 | AC_DEFUN([gl_EXTERN_INLINE], 9 | [ 10 | AH_VERBATIM([extern_inline], 11 | [/* Please see the Gnulib manual for how to use these macros. 12 | 13 | Suppress extern inline with HP-UX cc, as it appears to be broken; see 14 | . 15 | 16 | Suppress extern inline with Sun C in standards-conformance mode, as it 17 | mishandles inline functions that call each other. E.g., for 'inline void f 18 | (void) { } inline void g (void) { f (); }', c99 incorrectly complains 19 | 'reference to static identifier "f" in extern inline function'. 20 | This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16. 21 | 22 | Suppress extern inline (with or without __attribute__ ((__gnu_inline__))) 23 | on configurations that mistakenly use 'static inline' to implement 24 | functions or macros in standard C headers like . For example, 25 | if isdigit is mistakenly implemented via a static inline function, 26 | a program containing an extern inline function that calls isdigit 27 | may not work since the C standard prohibits extern inline functions 28 | from calling static functions. This bug is known to occur on: 29 | 30 | OS X 10.8 and earlier; see: 31 | http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html 32 | 33 | DragonFly; see 34 | http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log 35 | 36 | FreeBSD; see: 37 | http://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00104.html 38 | 39 | OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and 40 | for clang but remains for g++; see . 41 | Assume DragonFly and FreeBSD will be similar. */ 42 | #if (((defined __APPLE__ && defined __MACH__) \ 43 | || defined __DragonFly__ || defined __FreeBSD__) \ 44 | && (defined __header_inline \ 45 | ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \ 46 | && ! defined __clang__) \ 47 | : ((! defined _DONT_USE_CTYPE_INLINE_ \ 48 | && (defined __GNUC__ || defined __cplusplus)) \ 49 | || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \ 50 | && defined __GNUC__ && ! defined __cplusplus)))) 51 | # define _GL_EXTERN_INLINE_STDHEADER_BUG 52 | #endif 53 | #if ((__GNUC__ \ 54 | ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ 55 | : (199901L <= __STDC_VERSION__ \ 56 | && !defined __HP_cc \ 57 | && !(defined __SUNPRO_C && __STDC__))) \ 58 | && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) 59 | # define _GL_INLINE inline 60 | # define _GL_EXTERN_INLINE extern inline 61 | # define _GL_EXTERN_INLINE_IN_USE 62 | #elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \ 63 | && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) 64 | # if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__ 65 | /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ 66 | # define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) 67 | # else 68 | # define _GL_INLINE extern inline 69 | # endif 70 | # define _GL_EXTERN_INLINE extern 71 | # define _GL_EXTERN_INLINE_IN_USE 72 | #else 73 | # define _GL_INLINE static _GL_UNUSED 74 | # define _GL_EXTERN_INLINE static _GL_UNUSED 75 | #endif 76 | 77 | /* In GCC, suppress bogus "no previous prototype for 'FOO'" 78 | and "no previous declaration for 'FOO'" diagnostics, 79 | when FOO is an inline function in the header; see 80 | and 81 | . */ 82 | #if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) 83 | # if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ 84 | # define _GL_INLINE_HEADER_CONST_PRAGMA 85 | # else 86 | # define _GL_INLINE_HEADER_CONST_PRAGMA \ 87 | _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") 88 | # endif 89 | # define _GL_INLINE_HEADER_BEGIN \ 90 | _Pragma ("GCC diagnostic push") \ 91 | _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ 92 | _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \ 93 | _GL_INLINE_HEADER_CONST_PRAGMA 94 | # define _GL_INLINE_HEADER_END \ 95 | _Pragma ("GCC diagnostic pop") 96 | #else 97 | # define _GL_INLINE_HEADER_BEGIN 98 | # define _GL_INLINE_HEADER_END 99 | #endif]) 100 | ]) 101 | -------------------------------------------------------------------------------- /gl/m4/absolute-header.m4: -------------------------------------------------------------------------------- 1 | # absolute-header.m4 serial 16 2 | dnl Copyright (C) 2006-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Derek Price. 8 | 9 | # gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...) 10 | # --------------------------------------- 11 | # Find the absolute name of a header file, testing first if the header exists. 12 | # If the header were sys/inttypes.h, this macro would define 13 | # ABSOLUTE_SYS_INTTYPES_H to the '""' quoted absolute name of sys/inttypes.h 14 | # in config.h 15 | # (e.g. '#define ABSOLUTE_SYS_INTTYPES_H "///usr/include/sys/inttypes.h"'). 16 | # The three "///" are to pacify Sun C 5.8, which otherwise would say 17 | # "warning: #include of /usr/include/... may be non-portable". 18 | # Use '""', not '<>', so that the /// cannot be confused with a C99 comment. 19 | # Note: This macro assumes that the header file is not empty after 20 | # preprocessing, i.e. it does not only define preprocessor macros but also 21 | # provides some type/enum definitions or function/variable declarations. 22 | AC_DEFUN([gl_ABSOLUTE_HEADER], 23 | [AC_REQUIRE([AC_CANONICAL_HOST]) 24 | AC_LANG_PREPROC_REQUIRE()dnl 25 | dnl FIXME: gl_absolute_header and ac_header_exists must be used unquoted 26 | dnl until we can assume autoconf 2.64 or newer. 27 | m4_foreach_w([gl_HEADER_NAME], [$1], 28 | [AS_VAR_PUSHDEF([gl_absolute_header], 29 | [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl 30 | AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>], 31 | m4_defn([gl_absolute_header]), 32 | [AS_VAR_PUSHDEF([ac_header_exists], 33 | [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl 34 | AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl 35 | if test AS_VAR_GET(ac_header_exists) = yes; then 36 | gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME])) 37 | fi 38 | AS_VAR_POPDEF([ac_header_exists])dnl 39 | ])dnl 40 | AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])), 41 | ["AS_VAR_GET(gl_absolute_header)"], 42 | [Define this to an absolute name of <]m4_defn([gl_HEADER_NAME])[>.]) 43 | AS_VAR_POPDEF([gl_absolute_header])dnl 44 | ])dnl 45 | ])# gl_ABSOLUTE_HEADER 46 | 47 | # gl_ABSOLUTE_HEADER_ONE(HEADER) 48 | # ------------------------------ 49 | # Like gl_ABSOLUTE_HEADER, except that: 50 | # - it assumes that the header exists, 51 | # - it uses the current CPPFLAGS, 52 | # - it does not cache the result, 53 | # - it is silent. 54 | AC_DEFUN([gl_ABSOLUTE_HEADER_ONE], 55 | [ 56 | AC_REQUIRE([AC_CANONICAL_HOST]) 57 | AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote([$1])[[>]])]) 58 | dnl AIX "xlc -E" and "cc -E" omit #line directives for header files 59 | dnl that contain only a #include of other header files and no 60 | dnl non-comment tokens of their own. This leads to a failure to 61 | dnl detect the absolute name of , , 62 | dnl and others. The workaround is to force preservation of comments 63 | dnl through option -C. This ensures all necessary #line directives 64 | dnl are present. GCC supports option -C as well. 65 | case "$host_os" in 66 | aix*) gl_absname_cpp="$ac_cpp -C" ;; 67 | *) gl_absname_cpp="$ac_cpp" ;; 68 | esac 69 | changequote(,) 70 | case "$host_os" in 71 | mingw*) 72 | dnl For the sake of native Windows compilers (excluding gcc), 73 | dnl treat backslash as a directory separator, like /. 74 | dnl Actually, these compilers use a double-backslash as 75 | dnl directory separator, inside the 76 | dnl # line "filename" 77 | dnl directives. 78 | gl_dirsep_regex='[/\\]' 79 | ;; 80 | *) 81 | gl_dirsep_regex='\/' 82 | ;; 83 | esac 84 | dnl A sed expression that turns a string into a basic regular 85 | dnl expression, for use within "/.../". 86 | gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' 87 | gl_header_literal_regex=`echo '$1' \ 88 | | sed -e "$gl_make_literal_regex_sed"` 89 | gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ 90 | s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ 91 | s|^/[^/]|//&| 92 | p 93 | q 94 | }' 95 | changequote([,]) 96 | dnl eval is necessary to expand gl_absname_cpp. 97 | dnl Ultrix and Pyramid sh refuse to redirect output of eval, 98 | dnl so use subshell. 99 | AS_VAR_SET([gl_cv_absolute_]AS_TR_SH([[$1]]), 100 | [`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | 101 | sed -n "$gl_absolute_header_sed"`]) 102 | ]) 103 | -------------------------------------------------------------------------------- /gl/stdalign.in.h: -------------------------------------------------------------------------------- 1 | /* A substitute for ISO C11 . 2 | 3 | Copyright 2011-2015 Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, see . */ 17 | 18 | /* Written by Paul Eggert and Bruno Haible. */ 19 | 20 | #ifndef _GL_STDALIGN_H 21 | #define _GL_STDALIGN_H 22 | 23 | /* ISO C11 for platforms that lack it. 24 | 25 | References: 26 | ISO C11 (latest free draft 27 | ) 28 | sections 6.5.3.4, 6.7.5, 7.15. 29 | C++11 (latest free draft 30 | ) 31 | section 18.10. */ 32 | 33 | /* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment 34 | requirement of a structure member (i.e., slot or field) that is of 35 | type TYPE, as an integer constant expression. 36 | 37 | This differs from GCC's __alignof__ operator, which can yield a 38 | better-performing alignment for an object of that type. For 39 | example, on x86 with GCC, __alignof__ (double) and __alignof__ 40 | (long long) are 8, whereas alignof (double) and alignof (long long) 41 | are 4 unless the option '-malign-double' is used. 42 | 43 | The result cannot be used as a value for an 'enum' constant, if you 44 | want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. 45 | 46 | Include for offsetof. */ 47 | #include 48 | 49 | /* FreeBSD 9.1 , included by and lots of other 50 | standard headers, defines conflicting implementations of _Alignas 51 | and _Alignof that are no better than ours; override them. */ 52 | #undef _Alignas 53 | #undef _Alignof 54 | 55 | #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 56 | # ifdef __cplusplus 57 | # if 201103 <= __cplusplus 58 | # define _Alignof(type) alignof (type) 59 | # else 60 | template struct __alignof_helper { char __a; __t __b; }; 61 | # define _Alignof(type) offsetof (__alignof_helper, __b) 62 | # endif 63 | # else 64 | # define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) 65 | # endif 66 | #endif 67 | #define alignof _Alignof 68 | #define __alignof_is_defined 1 69 | 70 | /* alignas (A), also known as _Alignas (A), aligns a variable or type 71 | to the alignment A, where A is an integer constant expression. For 72 | example: 73 | 74 | int alignas (8) foo; 75 | struct s { int a; int alignas (8) bar; }; 76 | 77 | aligns the address of FOO and the offset of BAR to be multiples of 8. 78 | 79 | A should be a power of two that is at least the type's alignment 80 | and at most the implementation's alignment limit. This limit is 81 | 2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable 82 | to MSVC through at least version 10.0, A should be an integer 83 | constant, as MSVC does not support expressions such as 1 << 3. 84 | To be portable to Sun C 5.11, do not align auto variables to 85 | anything stricter than their default alignment. 86 | 87 | The following C11 requirements are not supported here: 88 | 89 | - If A is zero, alignas has no effect. 90 | - alignas can be used multiple times; the strictest one wins. 91 | - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). 92 | 93 | */ 94 | 95 | #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 96 | # if defined __cplusplus && 201103 <= __cplusplus 97 | # define _Alignas(a) alignas (a) 98 | # elif ((defined __APPLE__ && defined __MACH__ \ 99 | ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \ 100 | : __GNUC__) \ 101 | || __HP_cc || __HP_aCC || __IBMC__ || __IBMCPP__ \ 102 | || __ICC || 0x5110 <= __SUNPRO_C) 103 | # define _Alignas(a) __attribute__ ((__aligned__ (a))) 104 | # elif 1300 <= _MSC_VER 105 | # define _Alignas(a) __declspec (align (a)) 106 | # endif 107 | #endif 108 | #if defined _Alignas || (defined __STDC_VERSION && 201112 <= __STDC_VERSION__) 109 | # define alignas _Alignas 110 | # define __alignas_is_defined 1 111 | #endif 112 | 113 | #endif /* _GL_STDALIGN_H */ 114 | -------------------------------------------------------------------------------- /gl/m4/onceonly.m4: -------------------------------------------------------------------------------- 1 | # onceonly.m4 serial 9 2 | dnl Copyright (C) 2002-2003, 2005-2006, 2008-2015 Free Software Foundation, 3 | dnl Inc. 4 | dnl 5 | dnl This file is free software; you can redistribute it and/or modify 6 | dnl it under the terms of the GNU General Public License as published by 7 | dnl the Free Software Foundation; either version 3 of the License, or 8 | dnl (at your option) any later version. 9 | dnl 10 | dnl This file is distributed in the hope that it will be useful, 11 | dnl but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | dnl GNU General Public License for more details. 14 | dnl 15 | dnl You should have received a copy of the GNU General Public License 16 | dnl along with this file. If not, see . 17 | dnl 18 | dnl As a special exception to the GNU General Public License, 19 | dnl this file may be distributed as part of a program 20 | dnl that contains a configuration script generated by Autoconf, under 21 | dnl the same distribution terms as the rest of that program. 22 | 23 | dnl This file defines some "once only" variants of standard autoconf macros. 24 | dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS 25 | dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS 26 | dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS 27 | dnl AC_REQUIRE([AC_FUNC_STRCOLL]) like AC_FUNC_STRCOLL 28 | dnl The advantage is that the check for each of the headers/functions/decls 29 | dnl will be put only once into the 'configure' file. It keeps the size of 30 | dnl the 'configure' file down, and avoids redundant output when 'configure' 31 | dnl is run. 32 | dnl The drawback is that the checks cannot be conditionalized. If you write 33 | dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi 34 | dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to 35 | dnl empty, and the check will be inserted before the body of the AC_DEFUNed 36 | dnl function. 37 | 38 | dnl The original code implemented AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE 39 | dnl in terms of AC_DEFUN and AC_REQUIRE. This implementation uses diversions to 40 | dnl named sections DEFAULTS and INIT_PREPARE in order to check all requested 41 | dnl headers at once, thus reducing the size of 'configure'. It is known to work 42 | dnl with autoconf 2.57..2.62 at least . The size reduction is ca. 9%. 43 | 44 | dnl Autoconf version 2.59 plus gnulib is required; this file is not needed 45 | dnl with Autoconf 2.60 or greater. But note that autoconf's implementation of 46 | dnl AC_CHECK_DECLS_ONCE expects a comma-separated list of symbols as first 47 | dnl argument! 48 | AC_PREREQ([2.59]) 49 | 50 | # AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of 51 | # AC_CHECK_HEADERS(HEADER1 HEADER2 ...). 52 | AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ 53 | : 54 | m4_foreach_w([gl_HEADER_NAME], [$1], [ 55 | AC_DEFUN([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, 56 | [./-], [___])), [ 57 | m4_divert_text([INIT_PREPARE], 58 | [gl_header_list="$gl_header_list gl_HEADER_NAME"]) 59 | gl_HEADERS_EXPANSION 60 | AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_HEADER_NAME])), 61 | [Define to 1 if you have the <]m4_defn([gl_HEADER_NAME])[> header file.]) 62 | ]) 63 | AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, 64 | [./-], [___]))) 65 | ]) 66 | ]) 67 | m4_define([gl_HEADERS_EXPANSION], [ 68 | m4_divert_text([DEFAULTS], [gl_header_list=]) 69 | AC_CHECK_HEADERS([$gl_header_list]) 70 | m4_define([gl_HEADERS_EXPANSION], []) 71 | ]) 72 | 73 | # AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of 74 | # AC_CHECK_FUNCS(FUNC1 FUNC2 ...). 75 | AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ 76 | : 77 | m4_foreach_w([gl_FUNC_NAME], [$1], [ 78 | AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [ 79 | m4_divert_text([INIT_PREPARE], 80 | [gl_func_list="$gl_func_list gl_FUNC_NAME"]) 81 | gl_FUNCS_EXPANSION 82 | AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_FUNC_NAME])), 83 | [Define to 1 if you have the ']m4_defn([gl_FUNC_NAME])[' function.]) 84 | ]) 85 | AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME])) 86 | ]) 87 | ]) 88 | m4_define([gl_FUNCS_EXPANSION], [ 89 | m4_divert_text([DEFAULTS], [gl_func_list=]) 90 | AC_CHECK_FUNCS([$gl_func_list]) 91 | m4_define([gl_FUNCS_EXPANSION], []) 92 | ]) 93 | 94 | # AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of 95 | # AC_CHECK_DECLS(DECL1, DECL2, ...). 96 | AC_DEFUN([AC_CHECK_DECLS_ONCE], [ 97 | : 98 | m4_foreach_w([gl_DECL_NAME], [$1], [ 99 | AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [ 100 | AC_CHECK_DECLS(m4_defn([gl_DECL_NAME])) 101 | ]) 102 | AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME])) 103 | ]) 104 | ]) 105 | -------------------------------------------------------------------------------- /m4/gtk-doc.m4: -------------------------------------------------------------------------------- 1 | # -*- mode: autoconf -*- 2 | # 3 | # gtk-doc.m4 - configure macro to check for gtk-doc 4 | # Copyright (C) 2003 James Henstridge 5 | # 2007-2017 Stefan Sauer 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | # As a special exception, the above copyright owner gives unlimited 21 | # permission to copy, distribute and modify the configure scripts that 22 | # are the output of Autoconf when processing the Macro. You need not 23 | # follow the terms of the GNU General Public License when using or 24 | # distributing such scripts, even though portions of the text of the 25 | # Macro appear in them. The GNU General Public License (GPL) does govern 26 | # all other use of the material that constitutes the Autoconf Macro. 27 | 28 | # serial 2 29 | 30 | dnl Usage: 31 | dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) 32 | AC_DEFUN([GTK_DOC_CHECK], 33 | [ 34 | AC_REQUIRE([PKG_PROG_PKG_CONFIG]) 35 | AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first 36 | AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first 37 | 38 | ifelse([$1],[],[gtk_doc_requires="gtk-doc"],[gtk_doc_requires="gtk-doc >= $1"]) 39 | AC_MSG_CHECKING([for gtk-doc]) 40 | PKG_CHECK_EXISTS([$gtk_doc_requires],[have_gtk_doc=yes],[have_gtk_doc=no]) 41 | AC_MSG_RESULT($have_gtk_doc) 42 | 43 | if test "$have_gtk_doc" = "no"; then 44 | AC_MSG_WARN([ 45 | You will not be able to create source packages with 'make dist' 46 | because $gtk_doc_requires is not found.]) 47 | fi 48 | 49 | dnl check for tools we added during development 50 | dnl Use AC_CHECK_PROG to avoid the check target using an absolute path that 51 | dnl may not be writable by the user. Currently, automake requires that the 52 | dnl test name must end in '.test'. 53 | dnl https://bugzilla.gnome.org/show_bug.cgi?id=701638 54 | AC_CHECK_PROG([GTKDOC_CHECK],[gtkdoc-check],[gtkdoc-check.test]) 55 | AC_PATH_PROG([GTKDOC_CHECK_PATH],[gtkdoc-check]) 56 | AC_PATH_PROGS([GTKDOC_REBASE],[gtkdoc-rebase],[true]) 57 | AC_PATH_PROG([GTKDOC_MKPDF],[gtkdoc-mkpdf]) 58 | 59 | dnl for overriding the documentation installation directory 60 | AC_ARG_WITH([html-dir], 61 | AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, 62 | [with_html_dir='${datadir}/gtk-doc/html']) 63 | HTML_DIR="$with_html_dir" 64 | AC_SUBST([HTML_DIR]) 65 | 66 | dnl enable/disable documentation building 67 | AC_ARG_ENABLE([gtk-doc], 68 | AS_HELP_STRING([--enable-gtk-doc], 69 | [use gtk-doc to build documentation [[default=no]]]),, 70 | [enable_gtk_doc=no]) 71 | 72 | AC_MSG_CHECKING([whether to build gtk-doc documentation]) 73 | AC_MSG_RESULT($enable_gtk_doc) 74 | 75 | if test "x$enable_gtk_doc" = "xyes" && test "$have_gtk_doc" = "no"; then 76 | AC_MSG_ERROR([ 77 | You must have $gtk_doc_requires installed to build documentation for 78 | $PACKAGE_NAME. Please install gtk-doc or disable building the 79 | documentation by adding '--disable-gtk-doc' to '[$]0'.]) 80 | fi 81 | 82 | dnl don't check for glib if we build glib 83 | if test "x$PACKAGE_NAME" != "xglib"; then 84 | dnl don't fail if someone does not have glib 85 | PKG_CHECK_MODULES(GTKDOC_DEPS, glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0,,[:]) 86 | fi 87 | 88 | dnl enable/disable output formats 89 | AC_ARG_ENABLE([gtk-doc-html], 90 | AS_HELP_STRING([--enable-gtk-doc-html], 91 | [build documentation in html format [[default=yes]]]),, 92 | [enable_gtk_doc_html=yes]) 93 | AC_ARG_ENABLE([gtk-doc-pdf], 94 | AS_HELP_STRING([--enable-gtk-doc-pdf], 95 | [build documentation in pdf format [[default=no]]]),, 96 | [enable_gtk_doc_pdf=no]) 97 | 98 | if test -z "$GTKDOC_MKPDF"; then 99 | enable_gtk_doc_pdf=no 100 | fi 101 | 102 | if test -z "$AM_DEFAULT_VERBOSITY"; then 103 | AM_DEFAULT_VERBOSITY=1 104 | fi 105 | AC_SUBST([AM_DEFAULT_VERBOSITY]) 106 | 107 | AM_CONDITIONAL([HAVE_GTK_DOC], [test x$have_gtk_doc = xyes]) 108 | AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes]) 109 | AM_CONDITIONAL([GTK_DOC_BUILD_HTML], [test x$enable_gtk_doc_html = xyes]) 110 | AM_CONDITIONAL([GTK_DOC_BUILD_PDF], [test x$enable_gtk_doc_pdf = xyes]) 111 | AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"]) 112 | AM_CONDITIONAL([GTK_DOC_USE_REBASE], [test -n "$GTKDOC_REBASE"]) 113 | ]) 114 | -------------------------------------------------------------------------------- /70-u2f.rules: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1, or (at your option) 6 | # any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with this program; if not, see . 15 | 16 | # this udev file should be used with udev 188 and newer 17 | ACTION!="add|change", GOTO="u2f_end" 18 | 19 | # Yubico YubiKey 20 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113|0114|0115|0116|0120|0121|0200|0402|0403|0406|0407|0410", TAG+="uaccess", GROUP="plugdev", MODE="0660" 21 | 22 | # Happlink (formerly Plug-Up) Security KEY 23 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0", TAG+="uaccess", GROUP="plugdev", MODE="0660" 24 | 25 | # Neowave Keydo and Keydo AES 26 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1e0d", ATTRS{idProduct}=="f1d0|f1ae", TAG+="uaccess", GROUP="plugdev", MODE="0660" 27 | 28 | # HyperSecu HyperFIDO 29 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e|2ccf", ATTRS{idProduct}=="0880", TAG+="uaccess", GROUP="plugdev", MODE="0660" 30 | 31 | # Feitian ePass FIDO, BioPass FIDO2 32 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0850|0852|0853|0854|0856|0858|085a|085b|085d|0866|0867", TAG+="uaccess", GROUP="plugdev", MODE="0660" 33 | 34 | # JaCarta U2F 35 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="24dc", ATTRS{idProduct}=="0101|0501", TAG+="uaccess", GROUP="plugdev", MODE="0660" 36 | 37 | # U2F Zero 38 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", MODE="0660" 39 | 40 | # VASCO SecureClick 41 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1a44", ATTRS{idProduct}=="00bb", TAG+="uaccess", GROUP="plugdev", MODE="0660" 42 | 43 | # Bluink Key 44 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2abe", ATTRS{idProduct}=="1002", TAG+="uaccess", GROUP="plugdev", MODE="0660" 45 | 46 | # Thetis Key 47 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1ea8", ATTRS{idProduct}=="f025", TAG+="uaccess", GROUP="plugdev", MODE="0660" 48 | 49 | # Nitrokey FIDO U2F, Nitrokey FIDO2, Safetech SafeKey 50 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="4287|42b1|42b3", TAG+="uaccess", GROUP="plugdev", MODE="0660" 51 | 52 | # Google Titan U2F 53 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="5026", TAG+="uaccess", GROUP="plugdev", MODE="0660" 54 | 55 | # Tomu board + chopstx U2F + SoloKeys 56 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="cdab|a2ca", TAG+="uaccess", GROUP="plugdev", MODE="0660" 57 | 58 | # SoloKeys 59 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5070|50b0", TAG+="uaccess", GROUP="plugdev", MODE="0660" 60 | 61 | # Trezor 62 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", TAG+="uaccess", GROUP="plugdev", MODE="0660" 63 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", TAG+="uaccess", GROUP="plugdev", MODE="0660" 64 | 65 | # Infineon FIDO 66 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="058b", ATTRS{idProduct}=="022d", TAG+="uaccess", GROUP="plugdev", MODE="0660" 67 | 68 | # Ledger Blue, Nano S and Nano X 69 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0000|0001|0004|0005|0015|1005|1015|4005|4015", TAG+="uaccess", GROUP="plugdev", MODE="0660" 70 | 71 | # Kensington VeriMark 72 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="06cb", ATTRS{idProduct}=="0088", TAG+="uaccess", GROUP="plugdev", MODE="0660" 73 | 74 | # Longmai mFIDO 75 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="4c4d", ATTRS{idProduct}=="f703", TAG+="uaccess", GROUP="plugdev", MODE="0660" 76 | 77 | # eWBM FIDO2 - Goldengate 310, 320, 500, 450 78 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="4a1a|4c2a|5c2f|f47c", TAG+="uaccess", GROUP="plugdev", MODE="0660" 79 | 80 | # OnlyKey (FIDO2 / U2F) 81 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", TAG+="uaccess", GROUP="plugdev", MODE="0660" 82 | 83 | # GoTrust Idem Key 84 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="f143", TAG+="uaccess", GROUP="plugdev", MODE="0660" 85 | 86 | # ellipticSecure MIRKey 87 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ac", TAG+="uaccess", GROUP="plugdev", MODE="0660" 88 | 89 | LABEL="u2f_end" 90 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | # Having a separate GNUmakefile lets me 'include' the dynamically 2 | # generated rules created via cfg.mk (package-local configuration) 3 | # as well as maint.mk (generic maintainer rules). 4 | # This makefile is used only if you run GNU Make. 5 | # It is necessary if you want to build targets usually of interest 6 | # only to the maintainer. 7 | 8 | # Copyright (C) 2001, 2003, 2006-2015 Free Software Foundation, Inc. 9 | 10 | # This program is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | 23 | # If the user runs GNU make but has not yet run ./configure, 24 | # give them a diagnostic. 25 | _gl-Makefile := $(wildcard [M]akefile) 26 | ifneq ($(_gl-Makefile),) 27 | 28 | # Make tar archive easier to reproduce. 29 | export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner 30 | 31 | # Allow the user to add to this in the Makefile. 32 | ALL_RECURSIVE_TARGETS = 33 | 34 | include Makefile 35 | 36 | # Some projects override e.g., _autoreconf here. 37 | -include $(srcdir)/cfg.mk 38 | 39 | # Allow cfg.mk to override these. 40 | _build-aux ?= build-aux 41 | _autoreconf ?= autoreconf -v 42 | 43 | include $(srcdir)/maint.mk 44 | 45 | # Ensure that $(VERSION) is up to date for dist-related targets, but not 46 | # for others: rerunning autoreconf and recompiling everything isn't cheap. 47 | _have-git-version-gen := \ 48 | $(shell test -f $(srcdir)/$(_build-aux)/git-version-gen && echo yes) 49 | ifeq ($(_have-git-version-gen)0,yes$(MAKELEVEL)) 50 | _is-dist-target ?= $(filter-out %clean, \ 51 | $(filter maintainer-% dist% alpha beta stable,$(MAKECMDGOALS))) 52 | _is-install-target ?= $(filter-out %check, $(filter install%,$(MAKECMDGOALS))) 53 | ifneq (,$(_is-dist-target)$(_is-install-target)) 54 | _curr-ver := $(shell cd $(srcdir) \ 55 | && $(_build-aux)/git-version-gen \ 56 | .tarball-version \ 57 | $(git-version-gen-tag-sed-script)) 58 | ifneq ($(_curr-ver),$(VERSION)) 59 | ifeq ($(_curr-ver),UNKNOWN) 60 | $(info WARNING: unable to verify if $(VERSION) is the correct version) 61 | else 62 | ifneq (,$(_is-install-target)) 63 | # GNU Coding Standards state that 'make install' should not cause 64 | # recompilation after 'make all'. But as long as changing the version 65 | # string alters config.h, the cost of having 'make all' always have an 66 | # up-to-date version is prohibitive. So, as a compromise, we merely 67 | # warn when installing a version string that is out of date; the user 68 | # should run 'autoreconf' (or something like 'make distcheck') to 69 | # fix the version, 'make all' to propagate it, then 'make install'. 70 | $(info WARNING: version string $(VERSION) is out of date;) 71 | $(info run '$(MAKE) _version' to fix it) 72 | else 73 | $(info INFO: running autoreconf for new version string: $(_curr-ver)) 74 | GNUmakefile: _version 75 | touch GNUmakefile 76 | endif 77 | endif 78 | endif 79 | endif 80 | endif 81 | 82 | .PHONY: _version 83 | _version: 84 | cd $(srcdir) && rm -rf autom4te.cache .version && $(_autoreconf) 85 | $(MAKE) $(AM_MAKEFLAGS) Makefile 86 | 87 | else 88 | 89 | .DEFAULT_GOAL := abort-due-to-no-makefile 90 | srcdir = . 91 | 92 | # The package can override .DEFAULT_GOAL to run actions like autoreconf. 93 | -include ./cfg.mk 94 | 95 | # Allow cfg.mk to override these. 96 | _build-aux ?= build-aux 97 | _autoreconf ?= autoreconf -v 98 | 99 | include ./maint.mk 100 | 101 | ifeq ($(.DEFAULT_GOAL),abort-due-to-no-makefile) 102 | $(MAKECMDGOALS): abort-due-to-no-makefile 103 | endif 104 | 105 | abort-due-to-no-makefile: 106 | @echo There seems to be no Makefile in this directory. 1>&2 107 | @echo "You must run ./configure before running 'make'." 1>&2 108 | @exit 1 109 | 110 | endif 111 | 112 | # Tell version 3.79 and up of GNU make to not build goals in this 113 | # directory in parallel, in case someone tries to build multiple 114 | # targets, and one of them can cause a recursive target to be invoked. 115 | 116 | # Only set this if Automake doesn't provide it. 117 | AM_RECURSIVE_TARGETS ?= $(RECURSIVE_TARGETS:-recursive=) \ 118 | $(RECURSIVE_CLEAN_TARGETS:-recursive=) \ 119 | dist distcheck tags ctags 120 | 121 | ALL_RECURSIVE_TARGETS += $(AM_RECURSIVE_TARGETS) 122 | 123 | ifneq ($(word 2, $(MAKECMDGOALS)), ) 124 | ifneq ($(filter $(ALL_RECURSIVE_TARGETS), $(MAKECMDGOALS)), ) 125 | .NOTPARALLEL: 126 | endif 127 | endif 128 | -------------------------------------------------------------------------------- /gl/m4/longlong.m4: -------------------------------------------------------------------------------- 1 | # longlong.m4 serial 17 2 | dnl Copyright (C) 1999-2007, 2009-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Paul Eggert. 8 | 9 | # Define HAVE_LONG_LONG_INT if 'long long int' works. 10 | # This fixes a bug in Autoconf 2.61, and can be faster 11 | # than what's in Autoconf 2.62 through 2.68. 12 | 13 | # Note: If the type 'long long int' exists but is only 32 bits large 14 | # (as on some very old compilers), HAVE_LONG_LONG_INT will not be 15 | # defined. In this case you can treat 'long long int' like 'long int'. 16 | 17 | AC_DEFUN([AC_TYPE_LONG_LONG_INT], 18 | [ 19 | AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) 20 | AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], 21 | [ac_cv_type_long_long_int=yes 22 | if test "x${ac_cv_prog_cc_c99-no}" = xno; then 23 | ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int 24 | if test $ac_cv_type_long_long_int = yes; then 25 | dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. 26 | dnl If cross compiling, assume the bug is not important, since 27 | dnl nobody cross compiles for this platform as far as we know. 28 | AC_RUN_IFELSE( 29 | [AC_LANG_PROGRAM( 30 | [[@%:@include 31 | @%:@ifndef LLONG_MAX 32 | @%:@ define HALF \ 33 | (1LL << (sizeof (long long int) * CHAR_BIT - 2)) 34 | @%:@ define LLONG_MAX (HALF - 1 + HALF) 35 | @%:@endif]], 36 | [[long long int n = 1; 37 | int i; 38 | for (i = 0; ; i++) 39 | { 40 | long long int m = n << i; 41 | if (m >> i != n) 42 | return 1; 43 | if (LLONG_MAX / 2 < m) 44 | break; 45 | } 46 | return 0;]])], 47 | [], 48 | [ac_cv_type_long_long_int=no], 49 | [:]) 50 | fi 51 | fi]) 52 | if test $ac_cv_type_long_long_int = yes; then 53 | AC_DEFINE([HAVE_LONG_LONG_INT], [1], 54 | [Define to 1 if the system has the type 'long long int'.]) 55 | fi 56 | ]) 57 | 58 | # Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. 59 | # This fixes a bug in Autoconf 2.61, and can be faster 60 | # than what's in Autoconf 2.62 through 2.68. 61 | 62 | # Note: If the type 'unsigned long long int' exists but is only 32 bits 63 | # large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT 64 | # will not be defined. In this case you can treat 'unsigned long long int' 65 | # like 'unsigned long int'. 66 | 67 | AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], 68 | [ 69 | AC_CACHE_CHECK([for unsigned long long int], 70 | [ac_cv_type_unsigned_long_long_int], 71 | [ac_cv_type_unsigned_long_long_int=yes 72 | if test "x${ac_cv_prog_cc_c99-no}" = xno; then 73 | AC_LINK_IFELSE( 74 | [_AC_TYPE_LONG_LONG_SNIPPET], 75 | [], 76 | [ac_cv_type_unsigned_long_long_int=no]) 77 | fi]) 78 | if test $ac_cv_type_unsigned_long_long_int = yes; then 79 | AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], 80 | [Define to 1 if the system has the type 'unsigned long long int'.]) 81 | fi 82 | ]) 83 | 84 | # Expands to a C program that can be used to test for simultaneous support 85 | # of 'long long' and 'unsigned long long'. We don't want to say that 86 | # 'long long' is available if 'unsigned long long' is not, or vice versa, 87 | # because too many programs rely on the symmetry between signed and unsigned 88 | # integer types (excluding 'bool'). 89 | AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], 90 | [ 91 | AC_LANG_PROGRAM( 92 | [[/* For now, do not test the preprocessor; as of 2007 there are too many 93 | implementations with broken preprocessors. Perhaps this can 94 | be revisited in 2012. In the meantime, code should not expect 95 | #if to work with literals wider than 32 bits. */ 96 | /* Test literals. */ 97 | long long int ll = 9223372036854775807ll; 98 | long long int nll = -9223372036854775807LL; 99 | unsigned long long int ull = 18446744073709551615ULL; 100 | /* Test constant expressions. */ 101 | typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) 102 | ? 1 : -1)]; 103 | typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 104 | ? 1 : -1)]; 105 | int i = 63;]], 106 | [[/* Test availability of runtime routines for shift and division. */ 107 | long long int llmax = 9223372036854775807ll; 108 | unsigned long long int ullmax = 18446744073709551615ull; 109 | return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) 110 | | (llmax / ll) | (llmax % ll) 111 | | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) 112 | | (ullmax / ull) | (ullmax % ull));]]) 113 | ]) 114 | -------------------------------------------------------------------------------- /u2f-host/inc/u2f.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | // Common U2F raw message format header. 19 | // 2014-08-14 J Ehrensvard, Yubico, Inc. 20 | 21 | #ifndef __U2F_H_INCLUDED__ 22 | #define __U2F_H_INCLUDED__ 23 | 24 | // Visual studio 2008 and earlier are missing stdint.h 25 | #if defined _MSC_VER && _MSC_VER <= 1500 && !defined HAVE_STDINT_H 26 | typedef unsigned char uint8_t; 27 | typedef unsigned short uint16_t; 28 | typedef unsigned int uint32_t; 29 | typedef unsigned long int uint64_t; 30 | #else 31 | #include 32 | #endif 33 | 34 | #ifdef __cplusplus 35 | extern "C" 36 | { 37 | #endif 38 | 39 | // General constants 40 | 41 | #define U2F_EC_KEY_SIZE 32 // EC key size in bytes 42 | #define U2F_EC_POINT_SIZE ((U2F_EC_KEY_SIZE * 2) + 1) // Size of EC point 43 | #define U2F_MAX_KH_SIZE 128 // Max size of key handle 44 | #define U2F_MAX_ATT_CERT_SIZE 1024 // Max size of attestation certificate 45 | #define U2F_MAX_EC_SIG_SIZE 72 // Max size of DER coded EC signature 46 | #define U2F_CTR_SIZE 4 // Size of counter field 47 | #define U2F_APPID_SIZE 32 // Size of application id 48 | #define U2F_CHAL_SIZE 32 // Size of challenge 49 | 50 | #define ENC_SIZE(x) ((x + 7) & 0xfff8) 51 | 52 | // EC (uncompressed) point 53 | 54 | #define U2F_POINT_UNCOMPRESSED 0x04 // Uncompressed point format 55 | 56 | typedef struct 57 | { 58 | uint8_t pointFormat; // Point type 59 | uint8_t x[U2F_EC_KEY_SIZE]; // X-value 60 | uint8_t y[U2F_EC_KEY_SIZE]; // Y-value 61 | } U2F_EC_POINT; 62 | 63 | // U2F native commands 64 | 65 | #define U2F_REGISTER 0x01 // Registration command 66 | #define U2F_AUTHENTICATE 0x02 // Authenticate/sign command 67 | #define U2F_VERSION 0x03 // Read version string command 68 | 69 | #define U2F_VENDOR_FIRST 0x40 // First vendor defined command 70 | #define U2F_VENDOR_LAST 0x7f // Last vendor defined command 71 | 72 | // U2F_CMD_REGISTER command defines 73 | 74 | #define U2F_REGISTER_ID 0x05 // Version 2 registration identifier 75 | #define U2F_REGISTER_HASH_ID 0x00 // Version 2 hash identintifier 76 | 77 | typedef struct 78 | { 79 | uint8_t chal[U2F_CHAL_SIZE]; // Challenge 80 | uint8_t appId[U2F_APPID_SIZE]; // Application id 81 | } U2F_REGISTER_REQ; 82 | 83 | typedef struct 84 | { 85 | uint8_t registerId; // Registration identifier (U2F_REGISTER_ID_V2) 86 | U2F_EC_POINT pubKey; // Generated public key 87 | uint8_t keyHandleLen; // Length of key handle 88 | uint8_t keyHandleCertSig[U2F_MAX_KH_SIZE + // Key handle 89 | U2F_MAX_ATT_CERT_SIZE + // Attestation certificate 90 | U2F_MAX_EC_SIG_SIZE]; // Registration signature 91 | } U2F_REGISTER_RESP; 92 | 93 | // U2F_CMD_AUTHENTICATE command defines 94 | 95 | // Authentication control byte 96 | 97 | #define U2F_AUTH_ENFORCE 0x03 // Enforce user presence and sign 98 | #define U2F_AUTH_CHECK_ONLY 0x07 // Check only 99 | #define U2F_AUTH_FLAG_TUP 0x01 // Test of user presence set 100 | 101 | typedef struct 102 | { 103 | uint8_t chal[U2F_CHAL_SIZE]; // Challenge 104 | uint8_t appId[U2F_APPID_SIZE]; // Application id 105 | uint8_t keyHandleLen; // Length of key handle 106 | uint8_t keyHandle[U2F_MAX_KH_SIZE]; // Key handle 107 | } U2F_AUTHENTICATE_REQ; 108 | 109 | typedef struct 110 | { 111 | uint8_t flags; // U2F_AUTH_FLAG_ values 112 | uint8_t ctr[U2F_CTR_SIZE]; // Counter field (big-endian) 113 | uint8_t sig[U2F_MAX_EC_SIG_SIZE]; // Signature 114 | } U2F_AUTHENTICATE_RESP; 115 | 116 | // Common raw message format (ISO7816-4:2005 mapping) 117 | 118 | typedef struct 119 | { 120 | uint8_t cla; // Class - reserved 121 | uint8_t ins; // U2F instruction 122 | uint8_t p1; // U2F parameter 1 123 | uint8_t p2; // U2F parameter 2 124 | uint8_t lc1; // Length field, set to zero 125 | uint8_t lc2; // Length field, MSB 126 | uint8_t lc3; // Length field, LSB 127 | uint8_t data[1]; // Data field 128 | } U2F_MSG; 129 | 130 | // Command status responses 131 | 132 | #define U2F_SW_NO_ERROR 0x9000 // SW_NO_ERROR 133 | #define U2F_SW_WRONG_DATA 0x6984 // SW_WRONG_DATA 134 | #define U2F_SW_CONDITIONS_NOT_SATISFIED 0x6985 // SW_CONDITIONS_NOT_SATISFIED 135 | #define U2F_SW_INS_NOT_SUPPORTED 0x6d00 // SW_INS_NOT_SUPPORTED 136 | #define U2F_SW_CLA_NOT_SUPPORTED 0x6e00 // SW_CLA_NOT_SUPPORTED 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | 142 | #endif // __U2F_H_INCLUDED__ 143 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2013-2015 Yubico AB 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, eithe version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | AC_INIT([libu2f-host], [1.1.11], [yubico-devel@googlegroups.com]) 17 | AC_CONFIG_MACRO_DIR([m4]) 18 | AC_CONFIG_HEADERS([config.h]) 19 | AC_CONFIG_AUX_DIR([build-aux]) 20 | 21 | # http://www.gnu.org/s/libtool/manual/html_node/Updating-version-info.html 22 | AC_SUBST(LT_CURRENT, 1) # Interfaces removed: CURRENT++, AGE=0, REVISION=0 23 | AC_SUBST(LT_AGE, 1) # Interfaces added: CURRENT++, AGE++, REVISION=0 24 | AC_SUBST(LT_REVISION, 11) # No interfaces changed: REVISION++ 25 | 26 | AM_INIT_AUTOMAKE([gnits dist-xz no-dist-gzip std-options -Wall]) 27 | AM_SILENT_RULES([yes]) 28 | 29 | AC_PROG_CC 30 | gl_EARLY 31 | AM_PROG_AR 32 | LT_INIT([win32-dll]) 33 | 34 | GTK_DOC_CHECK(1.1) 35 | AM_MISSING_PROG(HELP2MAN, help2man, $missing_dir) 36 | AM_MISSING_PROG(HELP2ADOC, help2adoc, $missing_dir) 37 | 38 | PKG_CHECK_MODULES([LIBJSON], [json-c], [], [ 39 | PKG_CHECK_MODULES([LIBJSON], [json])]) 40 | 41 | # Check for json_object_to_json_string_ext, needed for pretty printing. 42 | am_save_CFLAGS="$CFLAGS" 43 | am_save_LIBS="$LIBS" 44 | CFLAGS="$CFLAGS $LIBJESON_CFLAGS" 45 | LIBS="$LIBS $LIBJSON_LIBS" 46 | AC_CHECK_FUNCS([json_object_to_json_string_ext]) 47 | AC_CHECK_FUNCS([json_object_object_get_ex]) 48 | CFLAGS=$am_save_CFLAGS 49 | LIBS=$am_save_LIBS 50 | 51 | PKG_CHECK_MODULES([HIDAPI], [hidapi], [], [ 52 | PKG_CHECK_MODULES([HIDAPI], [hidapi-hidraw])]) 53 | 54 | gl_INIT 55 | 56 | AC_ARG_ENABLE([gcc-warnings], 57 | [AS_HELP_STRING([--enable-gcc-warnings], 58 | [turn on lots of GCC warnings (for developers)])], 59 | [case $enableval in 60 | yes|no) ;; 61 | *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;; 62 | esac 63 | gl_gcc_warnings=$enableval], 64 | [gl_gcc_warnings=no] 65 | ) 66 | 67 | if test "$gl_gcc_warnings" = yes; then 68 | nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings 69 | nw="$nw -Wpadded" # Struct's arenot padded 70 | nw="$nw -Wc++-compat" # We don't care strongly about C++ compilers 71 | nw="$nw -Wtraditional" # Warns on #elif which we use often 72 | nw="$nw -Wtraditional-conversion" # Too many warnings for now 73 | nw="$nw -Wconversion" # Too many warnings for now 74 | nw="$nw -Wsuggest-attribute=pure" # Is it worth using attributes? 75 | nw="$nw -Wsuggest-attribute=const" # Is it worth using attributes? 76 | 77 | gl_MANYWARN_ALL_GCC([ws]) 78 | gl_MANYWARN_COMPLEMENT(ws, [$ws], [$nw]) 79 | for w in $ws; do 80 | gl_WARN_ADD([$w]) 81 | done 82 | 83 | gl_WARN_ADD([-fdiagnostics-show-option]) 84 | fi 85 | 86 | AC_SUBST([U2FH_VERSION_MAJOR], 87 | `echo $PACKAGE_VERSION | sed 's/\(.*\)\..*\..*/\1/g'`) 88 | AC_SUBST([U2FH_VERSION_MINOR], 89 | `echo $PACKAGE_VERSION | sed 's/.*\.\(.*\)\..*/\1/g'`) 90 | AC_SUBST([U2FH_VERSION_PATCH], 91 | `echo $PACKAGE_VERSION | sed 's/.*\..*\.\(.*\)/\1/g'`) 92 | AC_SUBST([U2FH_VERSION_NUMBER], 93 | `printf "0x%02x%02x%02x" $U2FH_VERSION_MAJOR \ 94 | $U2FH_VERSION_MINOR $U2FH_VERSION_PATCH`) 95 | 96 | AC_ARG_WITH([udevrulesdir], 97 | AS_HELP_STRING([--with-udevrulesdir=DIR], [Install udev rules into this directory]), 98 | [], []) 99 | AC_SUBST([udevrulesdir], [$with_udevrulesdir]) 100 | 101 | dnl check for random device 102 | AC_CACHE_CHECK(for random device, ac_cv_have_dev_random, 103 | [if test -r "/dev/urandom" ; then 104 | ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi]) 105 | if test "$ac_cv_have_dev_random" = yes; then 106 | AC_DEFINE([HAVE_DEV_URANDOM], 1, [Discovered a random device]) 107 | fi 108 | 109 | PKG_CHECK_MODULES([UDEV], [udev], 110 | udevrulesfile=70-u2f.rules, 111 | udevrulesfile="" 112 | ) 113 | AC_SUBST([udevrulesfile], [$udevrulesfile]) 114 | 115 | AC_CONFIG_FILES([ 116 | Makefile 117 | gl/Makefile 118 | gtk-doc/Makefile 119 | src/Makefile 120 | tests/Makefile 121 | u2f-host/Makefile 122 | u2f-host/u2f-host-version.h 123 | u2f-host/u2f-host.pc 124 | ]) 125 | AC_OUTPUT 126 | 127 | AC_MSG_NOTICE([summary of build options: 128 | 129 | version: ${VERSION} shared $LT_CURRENT:$LT_REVISION:$LT_AGE major $U2FH_VERSION_MAJOR minor $U2FH_VERSION_MINOR patch $U2FH_VERSION_PATCH number $U2FH_VERSION_NUMBER 130 | Host type: ${host} 131 | Install prefix: ${prefix} 132 | udev rules: ${with_udevrulesdir:-N/A} 133 | udev rulefile: ${udevrulesfile} 134 | Compiler: ${CC} 135 | Shared library: ${enable_shared} 136 | Static library: ${enable_static} 137 | JSON CFLAGS: $LIBJSON_CFLAGS 138 | JSON LIBS: $LIBJSON_LIBS 139 | HIDAPI CFLAGS: $HIDAPI_CFLAGS 140 | HIDAPI LIBS: $HIDAPI_LIBS 141 | ]) 142 | -------------------------------------------------------------------------------- /u2f-host/inc/u2f_hid.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | // Common U2F HID transport header. 19 | // 2014-08-21 J Ehrensvard, Yubico, Inc. 20 | 21 | #ifndef __U2FHID_H_INCLUDED__ 22 | #define __U2FHID_H_INCLUDED__ 23 | 24 | // Visual studio 2008 and earlier are missing stdint.h 25 | #if defined _MSC_VER && _MSC_VER <= 1500 && !defined HAVE_STDINT_H 26 | typedef unsigned char uint8_t; 27 | typedef unsigned short uint16_t; 28 | typedef unsigned int uint32_t; 29 | typedef unsigned long int uint64_t; 30 | #else 31 | #include 32 | #endif 33 | 34 | #ifdef __cplusplus 35 | extern "C" 36 | { 37 | #endif 38 | 39 | // Size of HID reports 40 | 41 | #define HID_RPT_SIZE 64 // Default size of raw HID report 42 | 43 | // Frame layout - command- and continuation frames 44 | 45 | #define CID_BROADCAST 0xffffffff // Broadcast channel id 46 | 47 | #define TYPE_MASK 0x80 // Frame type mask 48 | #define TYPE_INIT 0x80 // Initial frame identifier 49 | #define TYPE_CONT 0x00 // Continuation frame identifier 50 | 51 | typedef struct 52 | { 53 | uint32_t cid; // Channel identifier 54 | union 55 | { 56 | uint8_t type; // Frame type - b7 defines type 57 | struct 58 | { 59 | uint8_t cmd; // Command - b7 set 60 | uint8_t bcnth; // Message byte count - high part 61 | uint8_t bcntl; // Message byte count - low part 62 | uint8_t data[HID_RPT_SIZE - 7]; // Data payload 63 | } init; 64 | struct 65 | { 66 | uint8_t seq; // Sequence number - b7 cleared 67 | uint8_t data[HID_RPT_SIZE - 5]; // Data payload 68 | } cont; 69 | }; 70 | } U2FHID_FRAME; 71 | 72 | #define FRAME_TYPE(f) ((f).type & TYPE_MASK) 73 | #define FRAME_CMD(f) ((f).init.cmd & ~TYPE_MASK) 74 | #define MSG_LEN(f) (((f).init.bcnth << 8) + (f).init.bcntl) 75 | #define FRAME_SEQ(f) ((f).cont.seq & ~TYPE_MASK) 76 | 77 | // HID usage- and usage-page definitions 78 | 79 | #define FIDO_USAGE_PAGE 0xf1d0 // FIDO alliance HID usage page 80 | #define FIDO_USAGE_U2FHID 0x01 // U2FHID usage for top-level collection 81 | #define FIDO_USAGE_DATA_IN 0x20 // Raw IN data report 82 | #define FIDO_USAGE_DATA_OUT 0x21 // Raw OUT data report 83 | 84 | // General constants 85 | 86 | #define U2FHID_IF_VERSION 2 // Current interface implementation version 87 | #define U2FHID_FRAME_TIMEOUT 500 // Default frame timeout in ms 88 | #define U2FHID_TRANS_TIMEOUT 3000 // Default message timeout in ms 89 | 90 | // U2FHID native commands 91 | 92 | #define U2FHID_PING (TYPE_INIT | 0x01) // Echo data through local processor only 93 | #define U2FHID_MSG (TYPE_INIT | 0x03) // Send U2F message frame 94 | #define U2FHID_LOCK (TYPE_INIT | 0x04) // Send lock channel command 95 | #define U2FHID_INIT (TYPE_INIT | 0x06) // Channel initialization 96 | #define U2FHID_WINK (TYPE_INIT | 0x08) // Send device identification wink 97 | #define U2FHID_ERROR (TYPE_INIT | 0x3f) // Error response 98 | 99 | #define U2FHID_VENDOR_FIRST (TYPE_INIT | 0x40) // First vendor defined command 100 | #define U2FHID_VENDOR_LAST (TYPE_INIT | 0x7f) // Last vendor defined command 101 | 102 | // U2FHID_INIT command defines 103 | 104 | #define INIT_NONCE_SIZE 8 // Size of channel initialization challenge 105 | #define CAPFLAG_WINK 0x01 // Device supports WINK command 106 | #define CAPFLAG_LOCK 0x02 // Device supports LOCK command 107 | 108 | typedef struct 109 | { 110 | uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce 111 | } U2FHID_INIT_REQ; 112 | 113 | typedef struct 114 | { 115 | uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce 116 | uint32_t cid; // Channel identifier 117 | uint8_t versionInterface; // Interface version 118 | uint8_t versionMajor; // Major version number 119 | uint8_t versionMinor; // Minor version number 120 | uint8_t versionBuild; // Build version number 121 | uint8_t capFlags; // Capabilities flags 122 | } U2FHID_INIT_RESP; 123 | 124 | // Low-level error codes. Return as negatives. 125 | 126 | #define ERR_NONE 0x00 // No error 127 | #define ERR_INVALID_CMD 0x01 // Invalid command 128 | #define ERR_INVALID_PAR 0x02 // Invalid parameter 129 | #define ERR_INVALID_LEN 0x03 // Invalid message length 130 | #define ERR_INVALID_SEQ 0x04 // Invalid message sequencing 131 | #define ERR_MSG_TIMEOUT 0x05 // Message has timed out 132 | #define ERR_CHANNEL_BUSY 0x06 // Channel busy 133 | #define ERR_LOCK_REQUIRED 0x0a // Command requires channel lock 134 | #define ERR_INVALID_CID 0x0b // Command not allowed on this cid 135 | #define ERR_OTHER 0x7f // Other unspecified error 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif 140 | 141 | #endif // __U2FHID_H_INCLUDED__ 142 | -------------------------------------------------------------------------------- /gl/m4/extensions.m4: -------------------------------------------------------------------------------- 1 | # serial 13 -*- Autoconf -*- 2 | # Enable extensions on systems that normally disable them. 3 | 4 | # Copyright (C) 2003, 2006-2015 Free Software Foundation, Inc. 5 | # This file is free software; the Free Software Foundation 6 | # gives unlimited permission to copy and/or distribute it, 7 | # with or without modifications, as long as this notice is preserved. 8 | 9 | # This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git 10 | # Autoconf. Perhaps we can remove this once we can assume Autoconf 11 | # 2.70 or later everywhere, but since Autoconf mutates rapidly 12 | # enough in this area it's likely we'll need to redefine 13 | # AC_USE_SYSTEM_EXTENSIONS for quite some time. 14 | 15 | # If autoconf reports a warning 16 | # warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS 17 | # or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS 18 | # the fix is 19 | # 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked 20 | # but always AC_REQUIREd, 21 | # 2) to ensure that for each occurrence of 22 | # AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 23 | # or 24 | # AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) 25 | # the corresponding gnulib module description has 'extensions' among 26 | # its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS 27 | # invocation occurs in gl_EARLY, not in gl_INIT. 28 | 29 | # AC_USE_SYSTEM_EXTENSIONS 30 | # ------------------------ 31 | # Enable extensions on systems that normally disable them, 32 | # typically due to standards-conformance issues. 33 | # 34 | # Remember that #undef in AH_VERBATIM gets replaced with #define by 35 | # AC_DEFINE. The goal here is to define all known feature-enabling 36 | # macros, then, if reports of conflicts are made, disable macros that 37 | # cause problems on some platforms (such as __EXTENSIONS__). 38 | AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], 39 | [AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl 40 | AC_BEFORE([$0], [AC_RUN_IFELSE])dnl 41 | 42 | AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) 43 | if test "$MINIX" = yes; then 44 | AC_DEFINE([_POSIX_SOURCE], [1], 45 | [Define to 1 if you need to in order for 'stat' and other 46 | things to work.]) 47 | AC_DEFINE([_POSIX_1_SOURCE], [2], 48 | [Define to 2 if the system does not provide POSIX.1 features 49 | except with this defined.]) 50 | AC_DEFINE([_MINIX], [1], 51 | [Define to 1 if on MINIX.]) 52 | AC_DEFINE([_NETBSD_SOURCE], [1], 53 | [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) 54 | fi 55 | 56 | dnl Use a different key than __EXTENSIONS__, as that name broke existing 57 | dnl configure.ac when using autoheader 2.62. 58 | AH_VERBATIM([USE_SYSTEM_EXTENSIONS], 59 | [/* Enable extensions on AIX 3, Interix. */ 60 | #ifndef _ALL_SOURCE 61 | # undef _ALL_SOURCE 62 | #endif 63 | /* Enable general extensions on OS X. */ 64 | #ifndef _DARWIN_C_SOURCE 65 | # undef _DARWIN_C_SOURCE 66 | #endif 67 | /* Enable GNU extensions on systems that have them. */ 68 | #ifndef _GNU_SOURCE 69 | # undef _GNU_SOURCE 70 | #endif 71 | /* Use GNU style printf and scanf. */ 72 | #ifndef __USE_MINGW_ANSI_STDIO 73 | # undef __USE_MINGW_ANSI_STDIO 74 | #endif 75 | /* Enable threading extensions on Solaris. */ 76 | #ifndef _POSIX_PTHREAD_SEMANTICS 77 | # undef _POSIX_PTHREAD_SEMANTICS 78 | #endif 79 | /* Enable extensions on HP NonStop. */ 80 | #ifndef _TANDEM_SOURCE 81 | # undef _TANDEM_SOURCE 82 | #endif 83 | /* Enable X/Open extensions if necessary. HP-UX 11.11 defines 84 | mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of 85 | whether compiling with -Ae or -D_HPUX_SOURCE=1. */ 86 | #ifndef _XOPEN_SOURCE 87 | # undef _XOPEN_SOURCE 88 | #endif 89 | /* Enable general extensions on Solaris. */ 90 | #ifndef __EXTENSIONS__ 91 | # undef __EXTENSIONS__ 92 | #endif 93 | ]) 94 | AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], 95 | [ac_cv_safe_to_define___extensions__], 96 | [AC_COMPILE_IFELSE( 97 | [AC_LANG_PROGRAM([[ 98 | # define __EXTENSIONS__ 1 99 | ]AC_INCLUDES_DEFAULT])], 100 | [ac_cv_safe_to_define___extensions__=yes], 101 | [ac_cv_safe_to_define___extensions__=no])]) 102 | test $ac_cv_safe_to_define___extensions__ = yes && 103 | AC_DEFINE([__EXTENSIONS__]) 104 | AC_DEFINE([_ALL_SOURCE]) 105 | AC_DEFINE([_DARWIN_C_SOURCE]) 106 | AC_DEFINE([_GNU_SOURCE]) 107 | AC_DEFINE([__USE_MINGW_ANSI_STDIO]) 108 | AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) 109 | AC_DEFINE([_TANDEM_SOURCE]) 110 | AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], 111 | [ac_cv_should_define__xopen_source], 112 | [ac_cv_should_define__xopen_source=no 113 | AC_COMPILE_IFELSE( 114 | [AC_LANG_PROGRAM([[ 115 | #include 116 | mbstate_t x;]])], 117 | [], 118 | [AC_COMPILE_IFELSE( 119 | [AC_LANG_PROGRAM([[ 120 | #define _XOPEN_SOURCE 500 121 | #include 122 | mbstate_t x;]])], 123 | [ac_cv_should_define__xopen_source=yes])])]) 124 | test $ac_cv_should_define__xopen_source = yes && 125 | AC_DEFINE([_XOPEN_SOURCE], [500]) 126 | ])# AC_USE_SYSTEM_EXTENSIONS 127 | 128 | # gl_USE_SYSTEM_EXTENSIONS 129 | # ------------------------ 130 | # Enable extensions on systems that normally disable them, 131 | # typically due to standards-conformance issues. 132 | AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], 133 | [ 134 | dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. 135 | dnl gnulib does not need it. But if it gets required by third-party macros 136 | dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a 137 | dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". 138 | dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, 139 | dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. 140 | AC_REQUIRE([AC_GNU_SOURCE]) 141 | 142 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 143 | ]) 144 | -------------------------------------------------------------------------------- /gl/m4/string_h.m4: -------------------------------------------------------------------------------- 1 | # Configure a GNU-like replacement for . 2 | 3 | # Copyright (C) 2007-2015 Free Software Foundation, Inc. 4 | # This file is free software; the Free Software Foundation 5 | # gives unlimited permission to copy and/or distribute it, 6 | # with or without modifications, as long as this notice is preserved. 7 | 8 | # serial 21 9 | 10 | # Written by Paul Eggert. 11 | 12 | AC_DEFUN([gl_HEADER_STRING_H], 13 | [ 14 | dnl Use AC_REQUIRE here, so that the default behavior below is expanded 15 | dnl once only, before all statements that occur in other macros. 16 | AC_REQUIRE([gl_HEADER_STRING_H_BODY]) 17 | ]) 18 | 19 | AC_DEFUN([gl_HEADER_STRING_H_BODY], 20 | [ 21 | AC_REQUIRE([AC_C_RESTRICT]) 22 | AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) 23 | gl_NEXT_HEADERS([string.h]) 24 | 25 | dnl Check for declarations of anything we want to poison if the 26 | dnl corresponding gnulib module is not in use, and which is not 27 | dnl guaranteed by C89. 28 | gl_WARN_ON_USE_PREPARE([[#include 29 | ]], 30 | [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul 31 | strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r 32 | strerror_r strsignal strverscmp]) 33 | ]) 34 | 35 | AC_DEFUN([gl_STRING_MODULE_INDICATOR], 36 | [ 37 | dnl Use AC_REQUIRE here, so that the default settings are expanded once only. 38 | AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) 39 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) 40 | dnl Define it also as a C macro, for the benefit of the unit tests. 41 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) 42 | ]) 43 | 44 | AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], 45 | [ 46 | GNULIB_FFSL=0; AC_SUBST([GNULIB_FFSL]) 47 | GNULIB_FFSLL=0; AC_SUBST([GNULIB_FFSLL]) 48 | GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) 49 | GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) 50 | GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) 51 | GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) 52 | GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR]) 53 | GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY]) 54 | GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY]) 55 | GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL]) 56 | GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP]) 57 | GNULIB_STRNCAT=0; AC_SUBST([GNULIB_STRNCAT]) 58 | GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP]) 59 | GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN]) 60 | GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK]) 61 | GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP]) 62 | GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR]) 63 | GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR]) 64 | GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R]) 65 | GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN]) 66 | GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN]) 67 | GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR]) 68 | GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR]) 69 | GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR]) 70 | GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP]) 71 | GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP]) 72 | GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP]) 73 | GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR]) 74 | GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN]) 75 | GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK]) 76 | GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN]) 77 | GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) 78 | GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R]) 79 | GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) 80 | GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R]) 81 | GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) 82 | GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) 83 | HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) 84 | dnl Assume proper GNU behavior unless another module says otherwise. 85 | HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) 86 | HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL]) 87 | HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR]) 88 | HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) 89 | HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) 90 | HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR]) 91 | HAVE_RAWMEMCHR=1; AC_SUBST([HAVE_RAWMEMCHR]) 92 | HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY]) 93 | HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY]) 94 | HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL]) 95 | HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP]) 96 | HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP]) 97 | HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN]) 98 | HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK]) 99 | HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP]) 100 | HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) 101 | HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) 102 | HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R]) 103 | HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) 104 | HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) 105 | REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) 106 | REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) 107 | REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY]) 108 | REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) 109 | REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) 110 | REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) 111 | REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) 112 | REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) 113 | REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) 114 | REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) 115 | REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) 116 | REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) 117 | REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) 118 | REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) 119 | UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R]) 120 | ]) 121 | -------------------------------------------------------------------------------- /u2f-host/register.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | #include "internal.h" 20 | 21 | #include 22 | #include "b64/cencode.h" 23 | #include "sha256.h" 24 | 25 | static int 26 | prepare_response2 (const char *respstr, const char *bdstr, char **response, 27 | size_t * response_len) 28 | { 29 | int rc = U2FH_JSON_ERROR; 30 | struct json_object *jo = NULL, *resp = NULL, *bd = NULL; 31 | const char *reply; 32 | 33 | bd = json_object_new_string (bdstr); 34 | if (bd == NULL) 35 | goto done; 36 | resp = json_object_new_string (respstr); 37 | if (resp == NULL) 38 | goto done; 39 | 40 | jo = json_object_new_object (); 41 | if (jo == NULL) 42 | goto done; 43 | 44 | json_object_object_add (jo, "registrationData", json_object_get (resp)); 45 | json_object_object_add (jo, "clientData", json_object_get (bd)); 46 | 47 | reply = json_object_to_json_string (jo); 48 | if (*response == NULL) 49 | { 50 | *response = strdup (reply); 51 | } 52 | else 53 | { 54 | if (strlen (reply) >= *response_len) 55 | { 56 | rc = U2FH_SIZE_ERROR; 57 | *response_len = strlen (reply) + 1; 58 | goto done; 59 | } 60 | strcpy (*response, reply); 61 | } 62 | *response_len = strlen (reply); 63 | if (*response == NULL) 64 | rc = U2FH_MEMORY_ERROR; 65 | else 66 | rc = U2FH_OK; 67 | 68 | done: 69 | json_object_put (jo); 70 | json_object_put (resp); 71 | json_object_put (bd); 72 | 73 | return rc; 74 | } 75 | 76 | static int 77 | prepare_response (const unsigned char *buf, int len, const char *bd, 78 | char **response, size_t * response_len) 79 | { 80 | base64_encodestate b64ctx; 81 | char b64resp[2048]; 82 | char bdstr[2048]; 83 | int cnt; 84 | 85 | if (len > 2048) 86 | return U2FH_MEMORY_ERROR; 87 | if (strlen (bd) > 2048) 88 | return U2FH_MEMORY_ERROR; 89 | 90 | base64_init_encodestate (&b64ctx); 91 | cnt = base64_encode_block (buf, len, b64resp, &b64ctx); 92 | base64_encode_blockend (b64resp + cnt, &b64ctx); 93 | 94 | base64_init_encodestate (&b64ctx); 95 | cnt = base64_encode_block (bd, strlen (bd), bdstr, &b64ctx); 96 | base64_encode_blockend (bdstr + cnt, &b64ctx); 97 | 98 | return prepare_response2 (b64resp, bdstr, response, response_len); 99 | } 100 | 101 | #define V2CHALLEN 32 102 | 103 | #define HOSIZE 32 104 | #define NOTSATISFIED "\x69\x85" 105 | 106 | static u2fh_rc 107 | _u2fh_register (u2fh_devs * devs, 108 | const char *challenge, 109 | const char *origin, char **response, size_t * response_len, 110 | u2fh_cmdflags flags) 111 | { 112 | unsigned char data[V2CHALLEN + HOSIZE]; 113 | unsigned char buf[MAXDATASIZE]; 114 | char bd[2048]; 115 | size_t bdlen = sizeof (bd); 116 | size_t len; 117 | int rc = U2FH_JSON_ERROR; 118 | char chalb64[256]; 119 | size_t challen = sizeof (chalb64); 120 | int iterations = 0; 121 | 122 | rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen); 123 | if (rc != U2FH_OK) 124 | { 125 | return rc; 126 | } 127 | 128 | rc = prepare_browserdata (chalb64, origin, REGISTER_TYP, bd, &bdlen); 129 | if (rc != U2FH_OK) 130 | return rc; 131 | 132 | sha256_buffer (bd, bdlen, data); 133 | 134 | prepare_origin (challenge, data + V2CHALLEN); 135 | 136 | /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags 137 | flag. */ 138 | 139 | do 140 | { 141 | struct u2fdevice *dev; 142 | if (iterations++ > 15) 143 | { 144 | return U2FH_TIMEOUT_ERROR; 145 | } 146 | for (dev = devs->first; dev != NULL; dev = dev->next) 147 | { 148 | len = MAXDATASIZE; 149 | rc = send_apdu (devs, dev->id, U2F_REGISTER, data, sizeof (data), 150 | flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 0, buf, 151 | &len); 152 | if (rc != U2FH_OK) 153 | { 154 | return rc; 155 | } 156 | else if (len != 2) 157 | { 158 | break; 159 | } 160 | } 161 | if (len != 2) 162 | { 163 | break; 164 | } 165 | Sleep (1000); 166 | } 167 | while ((flags & U2FH_REQUEST_USER_PRESENCE) 168 | && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0); 169 | 170 | if (len != 2) 171 | { 172 | prepare_response (buf, len - 2, bd, response, response_len); 173 | return U2FH_OK; 174 | } 175 | return U2FH_TRANSPORT_ERROR; 176 | } 177 | 178 | /** 179 | * u2fh_register2: 180 | * @devs: a device set handle, from u2fh_devs_init() and u2fh_devs_discover(). 181 | * @challenge: string with JSON data containing the challenge. 182 | * @origin: U2F origin URL. 183 | * @response: pointer to output string with JSON data. 184 | * @response_len: pointer to length of @response 185 | * @flags: set of ORed #u2fh_cmdflags values. 186 | * 187 | * Perform the U2F Register operation. 188 | * 189 | * Returns: On success %U2FH_OK (integer 0) is returned, and on errors 190 | * an #u2fh_rc error code. 191 | */ 192 | u2fh_rc 193 | u2fh_register2 (u2fh_devs * devs, 194 | const char *challenge, 195 | const char *origin, char *response, size_t * response_len, 196 | u2fh_cmdflags flags) 197 | { 198 | return _u2fh_register (devs, challenge, origin, &response, response_len, 199 | flags); 200 | } 201 | 202 | /** 203 | * u2fh_register: 204 | * @devs: a device set handle, from u2fh_devs_init() and u2fh_devs_discover(). 205 | * @challenge: string with JSON data containing the challenge. 206 | * @origin: U2F origin URL. 207 | * @response: pointer to pointer for output data 208 | * @flags: set of ORed #u2fh_cmdflags values. 209 | * 210 | * Perform the U2F Register operation. 211 | * 212 | * Returns: On success %U2FH_OK (integer 0) is returned, and on errors 213 | * an #u2fh_rc error code. 214 | */ 215 | u2fh_rc 216 | u2fh_register (u2fh_devs * devs, 217 | const char *challenge, 218 | const char *origin, char **response, u2fh_cmdflags flags) 219 | { 220 | size_t response_len = 0; 221 | *response = NULL; 222 | return _u2fh_register (devs, challenge, origin, response, &response_len, 223 | flags); 224 | } 225 | -------------------------------------------------------------------------------- /gl/m4/manywarnings.m4: -------------------------------------------------------------------------------- 1 | # manywarnings.m4 serial 7 2 | dnl Copyright (C) 2008-2015 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | 7 | dnl From Simon Josefsson 8 | 9 | # gl_MANYWARN_COMPLEMENT(OUTVAR, LISTVAR, REMOVEVAR) 10 | # -------------------------------------------------- 11 | # Copy LISTVAR to OUTVAR except for the entries in REMOVEVAR. 12 | # Elements separated by whitespace. In set logic terms, the function 13 | # does OUTVAR = LISTVAR \ REMOVEVAR. 14 | AC_DEFUN([gl_MANYWARN_COMPLEMENT], 15 | [ 16 | gl_warn_set= 17 | set x $2; shift 18 | for gl_warn_item 19 | do 20 | case " $3 " in 21 | *" $gl_warn_item "*) 22 | ;; 23 | *) 24 | gl_warn_set="$gl_warn_set $gl_warn_item" 25 | ;; 26 | esac 27 | done 28 | $1=$gl_warn_set 29 | ]) 30 | 31 | # gl_MANYWARN_ALL_GCC(VARIABLE) 32 | # ----------------------------- 33 | # Add all documented GCC warning parameters to variable VARIABLE. 34 | # Note that you need to test them using gl_WARN_ADD if you want to 35 | # make sure your gcc understands it. 36 | AC_DEFUN([gl_MANYWARN_ALL_GCC], 37 | [ 38 | dnl First, check for some issues that only occur when combining multiple 39 | dnl gcc warning categories. 40 | AC_REQUIRE([AC_PROG_CC]) 41 | if test -n "$GCC"; then 42 | 43 | dnl Check if -W -Werror -Wno-missing-field-initializers is supported 44 | dnl with the current $CC $CFLAGS $CPPFLAGS. 45 | AC_MSG_CHECKING([whether -Wno-missing-field-initializers is supported]) 46 | AC_CACHE_VAL([gl_cv_cc_nomfi_supported], [ 47 | gl_save_CFLAGS="$CFLAGS" 48 | CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers" 49 | AC_COMPILE_IFELSE( 50 | [AC_LANG_PROGRAM([[]], [[]])], 51 | [gl_cv_cc_nomfi_supported=yes], 52 | [gl_cv_cc_nomfi_supported=no]) 53 | CFLAGS="$gl_save_CFLAGS"]) 54 | AC_MSG_RESULT([$gl_cv_cc_nomfi_supported]) 55 | 56 | if test "$gl_cv_cc_nomfi_supported" = yes; then 57 | dnl Now check whether -Wno-missing-field-initializers is needed 58 | dnl for the { 0, } construct. 59 | AC_MSG_CHECKING([whether -Wno-missing-field-initializers is needed]) 60 | AC_CACHE_VAL([gl_cv_cc_nomfi_needed], [ 61 | gl_save_CFLAGS="$CFLAGS" 62 | CFLAGS="$CFLAGS -W -Werror" 63 | AC_COMPILE_IFELSE( 64 | [AC_LANG_PROGRAM( 65 | [[void f (void) 66 | { 67 | typedef struct { int a; int b; } s_t; 68 | s_t s1 = { 0, }; 69 | } 70 | ]], 71 | [[]])], 72 | [gl_cv_cc_nomfi_needed=no], 73 | [gl_cv_cc_nomfi_needed=yes]) 74 | CFLAGS="$gl_save_CFLAGS" 75 | ]) 76 | AC_MSG_RESULT([$gl_cv_cc_nomfi_needed]) 77 | fi 78 | 79 | dnl Next, check if -Werror -Wuninitialized is useful with the 80 | dnl user's choice of $CFLAGS; some versions of gcc warn that it 81 | dnl has no effect if -O is not also used 82 | AC_MSG_CHECKING([whether -Wuninitialized is supported]) 83 | AC_CACHE_VAL([gl_cv_cc_uninitialized_supported], [ 84 | gl_save_CFLAGS="$CFLAGS" 85 | CFLAGS="$CFLAGS -Werror -Wuninitialized" 86 | AC_COMPILE_IFELSE( 87 | [AC_LANG_PROGRAM([[]], [[]])], 88 | [gl_cv_cc_uninitialized_supported=yes], 89 | [gl_cv_cc_uninitialized_supported=no]) 90 | CFLAGS="$gl_save_CFLAGS"]) 91 | AC_MSG_RESULT([$gl_cv_cc_uninitialized_supported]) 92 | 93 | fi 94 | 95 | # List all gcc warning categories. 96 | # To compare this list to your installed GCC's, run this Bash command: 97 | # 98 | # comm -3 \ 99 | # <(sed -n 's/^ *\(-[^ ]*\) .*/\1/p' manywarnings.m4 | sort) \ 100 | # <(gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort | 101 | # grep -v -x -f <( 102 | # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec)) 103 | 104 | gl_manywarn_set= 105 | for gl_manywarn_item in \ 106 | -W \ 107 | -Wabi \ 108 | -Waddress \ 109 | -Waggressive-loop-optimizations \ 110 | -Wall \ 111 | -Warray-bounds \ 112 | -Wattributes \ 113 | -Wbad-function-cast \ 114 | -Wbuiltin-macro-redefined \ 115 | -Wcast-align \ 116 | -Wchar-subscripts \ 117 | -Wclobbered \ 118 | -Wcomment \ 119 | -Wcomments \ 120 | -Wcoverage-mismatch \ 121 | -Wcpp \ 122 | -Wdate-time \ 123 | -Wdeprecated \ 124 | -Wdeprecated-declarations \ 125 | -Wdisabled-optimization \ 126 | -Wdiv-by-zero \ 127 | -Wdouble-promotion \ 128 | -Wempty-body \ 129 | -Wendif-labels \ 130 | -Wenum-compare \ 131 | -Wextra \ 132 | -Wformat-contains-nul \ 133 | -Wformat-extra-args \ 134 | -Wformat-nonliteral \ 135 | -Wformat-security \ 136 | -Wformat-y2k \ 137 | -Wformat-zero-length \ 138 | -Wfree-nonheap-object \ 139 | -Wignored-qualifiers \ 140 | -Wimplicit \ 141 | -Wimplicit-function-declaration \ 142 | -Wimplicit-int \ 143 | -Winit-self \ 144 | -Winline \ 145 | -Wint-to-pointer-cast \ 146 | -Winvalid-memory-model \ 147 | -Winvalid-pch \ 148 | -Wjump-misses-init \ 149 | -Wlogical-op \ 150 | -Wmain \ 151 | -Wmaybe-uninitialized \ 152 | -Wmissing-braces \ 153 | -Wmissing-declarations \ 154 | -Wmissing-field-initializers \ 155 | -Wmissing-include-dirs \ 156 | -Wmissing-parameter-type \ 157 | -Wmissing-prototypes \ 158 | -Wmultichar \ 159 | -Wnarrowing \ 160 | -Wnested-externs \ 161 | -Wnonnull \ 162 | -Wold-style-declaration \ 163 | -Wold-style-definition \ 164 | -Wopenmp-simd \ 165 | -Woverflow \ 166 | -Woverlength-strings \ 167 | -Woverride-init \ 168 | -Wpacked \ 169 | -Wpacked-bitfield-compat \ 170 | -Wparentheses \ 171 | -Wpointer-arith \ 172 | -Wpointer-sign \ 173 | -Wpointer-to-int-cast \ 174 | -Wpragmas \ 175 | -Wreturn-local-addr \ 176 | -Wreturn-type \ 177 | -Wsequence-point \ 178 | -Wshadow \ 179 | -Wsizeof-pointer-memaccess \ 180 | -Wstack-protector \ 181 | -Wstrict-aliasing \ 182 | -Wstrict-overflow \ 183 | -Wstrict-prototypes \ 184 | -Wsuggest-attribute=const \ 185 | -Wsuggest-attribute=format \ 186 | -Wsuggest-attribute=noreturn \ 187 | -Wsuggest-attribute=pure \ 188 | -Wswitch \ 189 | -Wswitch-default \ 190 | -Wsync-nand \ 191 | -Wsystem-headers \ 192 | -Wtrampolines \ 193 | -Wtrigraphs \ 194 | -Wtype-limits \ 195 | -Wuninitialized \ 196 | -Wunknown-pragmas \ 197 | -Wunsafe-loop-optimizations \ 198 | -Wunused \ 199 | -Wunused-but-set-parameter \ 200 | -Wunused-but-set-variable \ 201 | -Wunused-function \ 202 | -Wunused-label \ 203 | -Wunused-local-typedefs \ 204 | -Wunused-macros \ 205 | -Wunused-parameter \ 206 | -Wunused-result \ 207 | -Wunused-value \ 208 | -Wunused-variable \ 209 | -Wvarargs \ 210 | -Wvariadic-macros \ 211 | -Wvector-operation-performance \ 212 | -Wvla \ 213 | -Wvolatile-register-var \ 214 | -Wwrite-strings \ 215 | \ 216 | ; do 217 | gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item" 218 | done 219 | 220 | # gcc --help=warnings outputs an unusual form for this option; list 221 | # it here so that the above 'comm' command doesn't report a false match. 222 | gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc" 223 | 224 | # These are needed for older GCC versions. 225 | if test -n "$GCC"; then 226 | case `($CC --version) 2>/dev/null` in 227 | 'gcc (GCC) '[[0-3]].* | \ 228 | 'gcc (GCC) '4.[[0-7]].*) 229 | gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option" 230 | gl_manywarn_set="$gl_manywarn_set -funit-at-a-time" 231 | ;; 232 | esac 233 | fi 234 | 235 | # Disable specific options as needed. 236 | if test "$gl_cv_cc_nomfi_needed" = yes; then 237 | gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers" 238 | fi 239 | 240 | if test "$gl_cv_cc_uninitialized_supported" = no; then 241 | gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized" 242 | fi 243 | 244 | $1=$gl_manywarn_set 245 | ]) 246 | -------------------------------------------------------------------------------- /u2f-host/authenticate.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013-2015 Yubico AB 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2.1, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, but 10 | WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 12 | General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, see . 16 | */ 17 | 18 | #include 19 | #include "internal.h" 20 | 21 | #include 22 | #include "b64/cencode.h" 23 | #include "b64/cdecode.h" 24 | #include "sha256.h" 25 | 26 | static int 27 | prepare_response2 (const char *encstr, const char *bdstr, const char *input, 28 | char **response, size_t * response_len) 29 | { 30 | int rc = U2FH_JSON_ERROR; 31 | struct json_object *jo = NULL, *enc = NULL, *bd = NULL, *key = NULL; 32 | char keyb64[256]; 33 | size_t keylen = sizeof (keyb64); 34 | const char *reply; 35 | 36 | enc = json_object_new_string (encstr); 37 | if (enc == NULL) 38 | goto done; 39 | bd = json_object_new_string (bdstr); 40 | if (bd == NULL) 41 | goto done; 42 | 43 | rc = get_fixed_json_data (input, "keyHandle", keyb64, &keylen); 44 | if (rc != U2FH_OK) 45 | { 46 | goto done; 47 | } 48 | 49 | rc = U2FH_JSON_ERROR; 50 | key = json_object_new_string (keyb64); 51 | if (key == NULL) 52 | goto done; 53 | 54 | jo = json_object_new_object (); 55 | if (jo == NULL) 56 | goto done; 57 | 58 | json_object_object_add (jo, "signatureData", json_object_get (enc)); 59 | json_object_object_add (jo, "clientData", json_object_get (bd)); 60 | json_object_object_add (jo, "keyHandle", json_object_get (key)); 61 | 62 | reply = json_object_to_json_string (jo); 63 | if (*response == NULL) 64 | { 65 | *response = strdup (reply); 66 | } 67 | else 68 | { 69 | if (strlen (reply) >= *response_len) 70 | { 71 | rc = U2FH_SIZE_ERROR; 72 | *response_len = strlen (reply) + 1; 73 | goto done; 74 | } 75 | strcpy (*response, reply); 76 | } 77 | *response_len = strlen (reply); 78 | if (*response == NULL) 79 | rc = U2FH_MEMORY_ERROR; 80 | else 81 | rc = U2FH_OK; 82 | 83 | done: 84 | json_object_put (jo); 85 | json_object_put (enc); 86 | json_object_put (bd); 87 | json_object_put (key); 88 | 89 | return rc; 90 | } 91 | 92 | static int 93 | prepare_response (const unsigned char *buf, int len, const char *bd, 94 | const char *input, char **response, size_t * response_len) 95 | { 96 | base64_encodestate b64ctx; 97 | char b64enc[2048]; 98 | char bdstr[2048]; 99 | int cnt; 100 | 101 | if (len > 2048) 102 | return U2FH_MEMORY_ERROR; 103 | if (strlen (bd) > 2048) 104 | return U2FH_MEMORY_ERROR; 105 | 106 | base64_init_encodestate (&b64ctx); 107 | cnt = base64_encode_block (buf, len, b64enc, &b64ctx); 108 | base64_encode_blockend (b64enc + cnt, &b64ctx); 109 | 110 | base64_init_encodestate (&b64ctx); 111 | cnt = base64_encode_block (bd, strlen (bd), bdstr, &b64ctx); 112 | base64_encode_blockend (bdstr + cnt, &b64ctx); 113 | 114 | return prepare_response2 (b64enc, bdstr, input, response, response_len); 115 | } 116 | 117 | #define CHALLBINLEN 32 118 | #define HOSIZE 32 119 | #define MAXKHLEN 128 120 | #define NOTSATISFIED "\x69\x85" 121 | 122 | static u2fh_rc 123 | _u2fh_authenticate (u2fh_devs * devs, 124 | const char *challenge, 125 | const char *origin, char **response, 126 | size_t * response_len, u2fh_cmdflags flags) 127 | { 128 | unsigned char data[CHALLBINLEN + HOSIZE + MAXKHLEN + 1]; 129 | unsigned char buf[MAXDATASIZE]; 130 | char bd[2048]; 131 | size_t bdlen = sizeof (bd); 132 | size_t len; 133 | int rc; 134 | char chalb64[256]; 135 | size_t challen = sizeof (chalb64); 136 | char khb64[256]; 137 | size_t kh64len = sizeof (khb64); 138 | base64_decodestate b64; 139 | size_t khlen; 140 | int iterations = 0; 141 | 142 | rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen); 143 | if (rc != U2FH_OK) 144 | return rc; 145 | 146 | rc = prepare_browserdata (chalb64, origin, AUTHENTICATE_TYP, bd, &bdlen); 147 | if (rc != U2FH_OK) 148 | return rc; 149 | 150 | sha256_buffer (bd, bdlen, data); 151 | 152 | prepare_origin (challenge, data + CHALLBINLEN); 153 | 154 | /* confusion between key_handle and keyHandle */ 155 | rc = get_fixed_json_data (challenge, "keyHandle", khb64, &kh64len); 156 | if (rc != U2FH_OK) 157 | return rc; 158 | 159 | base64_init_decodestate (&b64); 160 | khlen = base64_decode_block (khb64, kh64len, 161 | data + HOSIZE + CHALLBINLEN + 1, &b64); 162 | data[HOSIZE + CHALLBINLEN] = khlen; 163 | 164 | /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags 165 | flag. */ 166 | 167 | do 168 | { 169 | struct u2fdevice *dev; 170 | 171 | if (iterations > 0 && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0) 172 | { 173 | Sleep (1000); 174 | } 175 | for (dev = devs->first; dev != NULL; dev = dev->next) 176 | { 177 | unsigned char tmp_buf[MAXDATASIZE]; 178 | if (iterations == 0) 179 | { 180 | dev->skipped = 0; 181 | } 182 | else if (dev->skipped != 0) 183 | { 184 | continue; 185 | } 186 | len = MAXDATASIZE; 187 | rc = send_apdu (devs, dev->id, U2F_AUTHENTICATE, data, 188 | HOSIZE + CHALLBINLEN + khlen + 1, 189 | flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 7, tmp_buf, 190 | &len); 191 | if (rc != U2FH_OK) 192 | { 193 | return rc; 194 | } 195 | else if (len != 2) 196 | { 197 | memcpy (buf, tmp_buf, len); 198 | break; 199 | } 200 | else if (memcmp (tmp_buf, NOTSATISFIED, 2) != 0) 201 | { 202 | dev->skipped = 1; 203 | } 204 | else 205 | { 206 | memcpy (buf, tmp_buf, len); 207 | } 208 | } 209 | if (iterations++ > 15) 210 | { 211 | return U2FH_TIMEOUT_ERROR; 212 | } 213 | } 214 | while ((flags & U2FH_REQUEST_USER_PRESENCE) 215 | && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0); 216 | 217 | if (len == 2 && memcmp (buf, NOTSATISFIED, 2) != 0) 218 | { 219 | return U2FH_AUTHENTICATOR_ERROR; 220 | } 221 | else if ((flags & U2FH_REQUEST_USER_PRESENCE) == 0 222 | && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0) 223 | { 224 | return U2FH_OK; 225 | } 226 | if (len != 2) 227 | { 228 | prepare_response (buf, len - 2, bd, challenge, response, response_len); 229 | return U2FH_OK; 230 | } 231 | 232 | return U2FH_TRANSPORT_ERROR; 233 | } 234 | 235 | /** 236 | * u2fh_authenticate2: 237 | * @devs: a device handle, from u2fh_devs_init() and u2fh_devs_discover(). 238 | * @challenge: string with JSON data containing the challenge. 239 | * @origin: U2F origin URL. 240 | * @response: pointer to string for output data 241 | * @response_len: pointer to length of @response 242 | * @flags: set of ORed #u2fh_cmdflags values. 243 | * 244 | * Perform the U2F Authenticate operation. 245 | * 246 | * Returns: On success %U2FH_OK (integer 0) is returned, and on errors 247 | * an #u2fh_rc error code. 248 | */ 249 | u2fh_rc 250 | u2fh_authenticate2 (u2fh_devs * devs, 251 | const char *challenge, 252 | const char *origin, char *response, size_t * response_len, 253 | u2fh_cmdflags flags) 254 | { 255 | return _u2fh_authenticate (devs, challenge, origin, &response, response_len, 256 | flags); 257 | } 258 | 259 | /** 260 | * u2fh_authenticate: 261 | * @devs: a device handle, from u2fh_devs_init() and u2fh_devs_discover(). 262 | * @challenge: string with JSON data containing the challenge. 263 | * @origin: U2F origin URL. 264 | * @response: pointer to pointer for output data 265 | * @flags: set of ORed #u2fh_cmdflags values. 266 | * 267 | * Perform the U2F Authenticate operation. 268 | * 269 | * Returns: On success %U2FH_OK (integer 0) is returned, and on errors 270 | * an #u2fh_rc error code. 271 | */ 272 | u2fh_rc 273 | u2fh_authenticate (u2fh_devs * devs, 274 | const char *challenge, 275 | const char *origin, char **response, u2fh_cmdflags flags) 276 | { 277 | size_t response_len = 0; 278 | 279 | *response = NULL; 280 | return _u2fh_authenticate (devs, challenge, origin, response, &response_len, 281 | flags); 282 | } 283 | --------------------------------------------------------------------------------