Giter VIP home page Giter VIP logo

nitrokey / libnitrokey Goto Github PK

View Code? Open in Web Editor NEW
64.0 10.0 34.0 2.06 MB

Communicate with Nitrokey devices in a clean and easy manner

Home Page: https://nitrokey.com/

License: GNU Lesser General Public License v3.0

C++ 58.94% C 11.53% CMake 1.88% Shell 0.42% Python 25.08% QMake 0.62% Meson 1.04% Dockerfile 0.09% Makefile 0.40%
nitrokey nitrokey-stick-devices python hotp security password-vault otp c-plus-plus library encrypted-store

libnitrokey's Introduction

libnitrokey

libnitrokey is a project to communicate with Nitrokey Pro and Storage devices in a clean and easy manner. Written in C++14, testable with py.test and Catch frameworks, with C API, Python access (through CFFI and C API, in future with Pybind11).

The development of this project is aimed to make it itself a living documentation of communication protocol between host and the Nitrokey stick devices. The command packets' format is described here: Pro v0.7, Pro v0.8, Storage. Handling and additional operations are described here: NitrokeyManager.cc.

A C++14 complying compiler is required due to heavy use of variable templates. For feature support tables please check table 1 or table 2.

libnitrokey is developed and tested with a variety of compilers, starting from g++ 6.2 and clang 3.8. We use Travis CI to test builds also on g++ 5.4 and under OSX compilers starting up from xcode 9 environment.

Getting sources

This repository uses git submodules. To clone please use git's --recursive option like in:

git clone --recursive https://github.com/Nitrokey/libnitrokey.git

or for already cloned repository:

git clone https://github.com/Nitrokey/libnitrokey.git
cd libnitrokey
git submodule update --init --recursive

Dependencies

Following libraries are needed to use libnitrokey on Linux (names of the packages on Ubuntu):

Build

libnitrokey uses CMake as its main build system. As a secondary option it offers building through Qt's qMake.

Docker Isolated Build

To run a docker isolated build it suffices to run the helper command:

# build docker image, and execute the build
$ make docker-build-all

Currently, Ubuntu 22.04 is used as a build base. Results will be placed in the ./build/ directory.

Additionally, it is possible to check if the Debian package of selected version is able to build itself with the following command:

# for the default 3.7 URL
$ make docker-package

# for the customized DGET url
$ make docker-package DOCKERCMD="make ci-package DGET_URL=https://people.debian.org/~patryk/tmp/libnitrokey/libnitrokey_3.7-1.dsc"

Qt

A Qt's .pro project file is provided for direct compilation and for inclusion to other projects. Using it directly is not recommended due to lack of dependencies check and not implemented library versioning. Compilation is tested with Qt 5.6 and greater.

Quick start example:

mkdir -p build
cd build
qmake ..
make -j2

Windows and Visual Studio 2017

Lately Visual Studio has started handling CMake files directly. After opening the project's directory it should recognize it and initialize build system. Afterwards please run:

  1. CMake -> Cache -> View Cache CMakeLists.txt -> CMakeLists.txt to edit settings
  2. CMake -> Build All to build

It is possible too to use CMake GUI directly with its settings editor.

CMake

To compile please run following sequence of commands:

# assuming current dir is ./libnitrokey/
mkdir -p build
cd build
cmake .. <OPTIONS>
make -j2

By default (with empty <OPTIONS> string) this will create in build/ directory a shared library (.so, .dll or .dynlib). If you wish to build static version you can use as <OPTIONS> string -DBUILD_SHARED_LIBS=OFF.

All options could be listed with cmake .. -L or instead cmake a ccmake .. tool could be used for configuration (where .. is the path to directory with CMakeLists.txt file). ccmake shows also description of the build parameters.

If you have trouble compiling or running the library you can check .travis.yml file for configuration details. This file is used by Travis CI service to make test builds on OSX and Ubuntu 14.04.

Other build options (all take either ON or OFF):

  • ADD_ASAN - add tests for memory leaks and out-of-bounds access
  • ADD_TSAN - add tests for threads race, needs USE_CLANG
  • COMPILE_TESTS - compile C++ tests
  • COMPILE_OFFLINE_TESTS - compile C++ tests, that do not require any device to be connected
  • LOG_VOLATILE_DATA (default: OFF) - include secrets in log (PWS passwords, PINs etc)
  • NO_LOG (default: OFF) - do not compile LOG statements - will make library smaller, but without any diagnostic messages

Meson

Note: Meson build is currently not tested. Please file a ticket in case it would not work for you.

It is possible to use Meson and Ninja to build the project as well. Please run:

meson builddir <OPTIONS>
meson configure builddir # to show available build flags
ninja -C builddir

Using libnitrokey with Python

To use libnitrokey with Python a CFFI library is required (either 2.7+ or 3.0+). It can be installed with:

pip install --user cffi # for python 2.x
pip3 install cffi # for python 3.x

Python2

Note: Python 2 is not supported anymore.

Just import it, read the C API header and it is done! You have access to the library. Here is an example (in Python 2) printing HOTP code for Pro or Storage device, assuming it is run in root directory (full example):

Code snippet (click to show)
#!/usr/bin/env python2
import cffi

ffi = cffi.FFI()
get_string = ffi.string

def get_library():
    fp = 'NK_C_API.h'  # path to C API header

    declarations = []
    with open(fp, 'r') as f:
        declarations = f.readlines()

    cnt = 0
    a = iter(declarations)
    for declaration in a:
        if declaration.strip().startswith('NK_C_API'):
            declaration = declaration.replace('NK_C_API', '').strip()
            while ';' not in declaration:
                declaration += (next(a)).strip()
            # print(declaration)
            ffi.cdef(declaration, override=True)
            cnt +=1
    print('Imported {} declarations'.format(cnt))


    C = None
    import os, sys
    path_build = os.path.join(".", "build")
    paths = [
            os.environ.get('LIBNK_PATH', None),
            os.path.join(path_build,"libnitrokey.so"),
            os.path.join(path_build,"libnitrokey.dylib"),
            os.path.join(path_build,"libnitrokey.dll"),
            os.path.join(path_build,"nitrokey.dll"),
    ]
    for p in paths:
        if not p: continue
        print("Trying " +p)
        p = os.path.abspath(p)
        if os.path.exists(p):
            print("Found: "+p)
            C = ffi.dlopen(p)
            break
        else:
            print("File does not exist: " + p)
    if not C:
        print("No library file found")
        sys.exit(1)

    return C


def get_hotp_code(lib, i):
    return lib.NK_get_hotp_code(i)


libnitrokey = get_library()
libnitrokey.NK_set_debug(False)  # do not show debug messages (log library only)

hotp_slot_code = get_hotp_code(libnitrokey, 1)
print('Getting HOTP code from Nitrokey device: ')
print(hotp_slot_code)
libnitrokey.NK_logout()  # disconnect device

In case no devices are connected, a friendly message will be printed. All available functions for C and Python are listed in NK_C_API.h. Please check Documentation section below.

Python3

Just import it, read the C API header and it is done! You have access to the library. Here is an example (in Python 3) printing HOTP code for Pro or Storage device, assuming it is run in root directory (full example):

Code snippet (click to show)
#!/usr/bin/env python3
import cffi

ffi = cffi.FFI()
get_string = ffi.string

def get_library():
    fp = 'NK_C_API.h'  # path to C API header

    declarations = []
    with open(fp, 'r') as f:
        declarations = f.readlines()

    cnt = 0
    a = iter(declarations)
    for declaration in a:
        if declaration.strip().startswith('NK_C_API'):
            declaration = declaration.replace('NK_C_API', '').strip()
            while ';' not in declaration:
                declaration += (next(a)).strip()
            # print(declaration)
            ffi.cdef(declaration, override=True)
            cnt +=1
    print('Imported {} declarations'.format(cnt))


    C = None
    import os, sys
    path_build = os.path.join(".", "build")
    paths = [
            os.environ.get('LIBNK_PATH', None),
            os.path.join(path_build,"libnitrokey.so"),
            os.path.join(path_build,"libnitrokey.dylib"),
            os.path.join(path_build,"libnitrokey.dll"),
            os.path.join(path_build,"nitrokey.dll"),
    ]
    for p in paths:
        if not p: continue
        print("Trying " +p)
        p = os.path.abspath(p)
        if os.path.exists(p):
            print("Found: "+p)
            C = ffi.dlopen(p)
            break
        else:
            print("File does not exist: " + p)
    if not C:
        print("No library file found")
        sys.exit(1)

    return C


def get_hotp_code(lib, i):
    return lib.NK_get_hotp_code(i)

def connect_device(lib):
	# lib.NK_login('S'.encode('ascii'))  # connect only to Nitrokey Storage device
	# lib.NK_login('P'.encode('ascii'))  # connect only to Nitrokey Pro device
	device_connected = lib.NK_login_auto()  # connect to any Nitrokey Stick
	if device_connected:
		print('Connected to Nitrokey device!')
	else:
	    print('Could not connect to Nitrokey device!')
	    exit()

libnitrokey = get_library()
libnitrokey.NK_set_debug(False)  # do not show debug messages (log library only)

connect_device(libnitrokey)

hotp_slot_code = get_hotp_code(libnitrokey, 1)
print('Getting HOTP code from Nitrokey device: ')
print(ffi.string(hotp_slot_code).decode('ascii'))
libnitrokey.NK_logout()  # disconnect device

In case no devices are connected, a friendly message will be printed. All available functions for C and Python are listed in NK_C_API.h. Please check Documentation section below.

Documentation

The documentation of C API is included in the sources (can be generated with make doc if Doxygen is installed). Please check NK_C_API.h (C API) for high level commands and libnitrokey/NitrokeyManager.h (C++ API). All devices' commands are listed along with packet format in libnitrokey/stick10_commands.h and libnitrokey/stick20_commands.h respectively for Nitrokey Pro and Nitrokey Storage products.

Tests

Warning! Most of the tests will overwrite user data. The only user-data safe tests are specified in unittest/test_safe.cpp (see C++ tests chapter).

Warning! Before you run unittests please change both your Admin and User PINs on your Nitrostick to defaults (12345678 and 123456 respectively), or change the values in tests source code. If you do not change them, the tests might lock your device temporarily. If it's too late already, you can reset your Nitrokey using instructions from homepage.

Helper

Here are Python tests helper calls:

# setup, requires pipenv installed
$ make tests-setup
# For Nitrokey Pro
$ make tests-pro
# For Nitrokey Storage
$ make tests-storage

See below for the further information.

Python tests

libnitrokey has a great suite of tests written in Python 3 under the path: unittest/test_*.py:

  • test_pro.py - contains tests of OTP, Password Safe and PIN control functionality. Could be run on both Pro and Storage devices.
  • test_storage.py - contains tests of Encrypted Volumes functionality. Could be run only on Storage.

The tests themselves show how to handle common requests to device. Before running please install all required libraries with:

cd unittest
pip install --user -r requirements.txt

or use Python's environment managing tool like pipenv or virtualenv.

To run them please execute:

# substitute <dev> with either 'pro' or 'storage'
py.test -v test_<dev>.py
# more specific use - run tests containing in name <test_name> 5 times:
py.test -v test_<dev>.py -k <test_name> --count 5

For additional documentation please check the following for py.test installation. For better coverage randomly plugin is installed - it randomizes the test order allowing to detect unseen dependencies between the tests.

C++ tests

There are also some unit tests implemented in C++, placed in unittest directory. The only user-data safe online test set here is test_safe.cpp, which tries to connect to the device, and collect its status data. Example run for Storage:

Log (click to show)
# Storage device inserted, firmware version v0.53
$ ./test_safe
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_DEVICE_STATUS
..
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    <= GET_DEVICE_STATUS 0 1
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_PASSWORD_RETRY_COUNT
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    <= GET_PASSWORD_RETRY_COUNT 0 0
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_DEVICE_STATUS
..
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    <= GET_DEVICE_STATUS 0 1
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_USER_PASSWORD_RETRY_COUNT
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    <= GET_USER_PASSWORD_RETRY_COUNT 0 0
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_DEVICE_STATUS
...
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    <= GET_DEVICE_STATUS 0 1
 transmission_data.dissect():   _padding:
0000    00 00 00 00 00 00 00 00 00 00 00 00 00 05 2e 01   ................
0010    00 00 -- -- -- -- -- -- -- -- -- -- -- -- -- --   ..
 (int) SendCounter_u8:  0
 (int) SendDataType_u8: 3
 (int) FollowBytesFlag_u8:      0
 (int) SendSize_u8:     28

 MagicNumber_StickConfig_u16:   13080
 (int) ReadWriteFlagUncryptedVolume_u8: 1
 (int) ReadWriteFlagCryptedVolume_u8:   0
 (int) ReadWriteFlagHiddenVolume_u8:    0
 (int) versionInfo.major:       0
 (int) versionInfo.minor:       53
 (int) versionInfo.build_iteration:     0
 (int) FirmwareLocked_u8:       0
 (int) NewSDCardFound_u8:       1
 (int) NewSDCardFound_st.NewCard:       1
 (int) NewSDCardFound_st.Counter:       0
 (int) SDFillWithRandomChars_u8:        1
 ActiveSD_CardID_u32:   3670817656
 (int) VolumeActiceFlag_u8:     1
 (int) VolumeActiceFlag_st.unencrypted: 1
 (int) VolumeActiceFlag_st.encrypted:   0
 (int) VolumeActiceFlag_st.hidden:      0
 (int) NewSmartCardFound_u8:    0
 (int) UserPwRetryCount:        3
 (int) AdminPwRetryCount:       3
 ActiveSmartCardID_u32: 24122
 (int) StickKeysNotInitiated:   0

[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_DEVICE_STATUS
..
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    <= GET_DEVICE_STATUS 0 1
00005e3a
[Wed Jan  2 13:31:17 2019][DEBUG_L1]    => GET_DEVICE_STATUS
....
[Wed Jan  2 13:31:18 2019][DEBUG_L1]    <= GET_DEVICE_STATUS 0 1
[Wed Jan  2 13:31:18 2019][DEBUG_L1]    => GET_DEVICE_STATUS
...
[Wed Jan  2 13:31:18 2019][DEBUG_L1]    <= GET_DEVICE_STATUS 0 1
===============================================================================
All tests passed (18 assertions in 6 test cases)

Test's execution configuration and verbosity could be manipulated - please see ./test_safe --help for details.

The other tests sets are not written as extensively as Python tests and are rather more a C++ low level interface check used during the library development, using either low-level components, C API from NK_C_API.cc, or C++ API from NitrokeyManager.cc. Some of them are: test_HOTP.cc, test1.cc. See more in unittest directory.

Note: these are not device model agnostic, and will most probably destroy your data on the device.

Unit tests were checked on Ubuntu 16.04/16.10/17.04. To run them just execute binaries built in ./libnitrokey/build dir, after enabling them by passing -DCOMPILE_TESTS=ON option to cmake - e.g.: cmake .. -DCOMPILE_TESTS=ON && make.

The documentation of how it works could be found in nitrokey-app project's README on Github: Nitrokey-app - internals.

To peek/debug communication with device running nitrokey-app (0.x branch) in debug mode (-d switch) and checking the logs (right click on tray icon and then 'Debug') might be helpful. Latest Nitrokey App (1.x branch) uses libnitrokey to communicate with device. Once run with --dl 3 (3 or higher; range 0-5) it will print all communication to the console. Additionally crosschecking with firmware code should show how things works: report_protocol.c (for Nitrokey Pro, for Storage similarly).

Known issues / tasks

  • C++ API needs some reorganization to C++ objects (instead of pointers to byte arrays). This would be also preparation for Pybind11 integration;
  • Fix compilation warnings.

Other tasks might be listed either in TODO file or on project's issues page.

License

This project is licensed under LGPL version 3. License text can be found under LICENSE file.

Roadmap

To check what issues will be fixed and when please check milestones page.

Nitrokey USB IDs

For a list of USB identifiers for Nitrokey products, please refer to the data subdirectory.

libnitrokey's People

Contributors

alex-nitrokey avatar cornelinux avatar d-e-s-o avatar esven avatar glebfm avatar ignatenkobrain avatar jans23 avatar mmerklinger avatar monwarez avatar muellermartin avatar robin-nitrokey avatar robinkrahl avatar soapgentoo avatar szszszsz avatar tomhughes avatar waffle-iron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libnitrokey's Issues

Support for Debian 8 Jessie (G++ 4.9 with no C++14)

In re: #39

libnitrokey is practically useless in its current state for developers using the latest stable release of Debian: v8 (jessie) because jessie features g++ compiler 4.9.2. The unstable release, code named stretch, includes the c++ compiler v6.1.

Please, create another viable option to make nitrokey-app and library available for Debian 8 as I have no viable options

Correct get_time

Investigate in Nitrokey App and correct functionality of get_time command

Introduce custom allocator

Custom allocator might be put to work on additional clearing of deallocated memory as a last safety layer.

Make contributions easier

The issues labels are quite difficult to understand.
For example, what does "ready" label mean? Did you already have the feature somewhere?

Proposition of high-level API for libnitrokey [draft]

Please comment what functions should have high-level API to make libnitrokey easy to use for user or to integrate into other frameworks. Please propose a name, parameters, return value (if needed) and description what should it do. This could be later used as reference.

Example:
int32_t getHOTPCode(int slotNumber) - returns HOTP code for current counter for slot configured before, throws or returns <0 if slot is not programmed.

"no-gnu-variable-sized-type-not-at-end" command not recognized (debian, g++ 4.9.2)

I'm using Debian 8 with gnome, g++ 4.9.2. I had no luck with getting the nitrokey-app widget to appear but since that's not a requirement for my work I decided to skip that step and instead focus on the python bindings.

Unfortunately, I haven't been able to successfully build the libnitrokey project using "make" or "make CXX=g++". The first except, which I resolved, was a lib dependency that wasn't mentioned in the docs, namely libhidapi-dev. The next exception I haven't been able to resolve.

The more verbose exception, raised with "make CXX=G++" is as follows:

g++ -M log.cc -o build/log.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M NK_C_API.cc -o build/NK_C_API.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M device.cc -o build/device.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M misc.cc -o build/misc.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M command_id.cc -o build/command_id.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M NitrokeyManager.cc -o build/NitrokeyManager.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -c log.cc -o build/log.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
log.cc: In member function ‘virtual void nitrokey::log::StdlogHandler::print(const string&, nitrokey::log::Loglevel)’:
log.cc:39:16: error: ‘put_time’ is not a member of ‘std’
             << std::put_time(&tm, "%c %Z") << "]\t" << str << std::endl;
                ^
At global scope:
cc1plus: warning: unrecognized command line option "-Wno-gnu-variable-sized-type-not-at-end"
Makefile:28: recipe for target 'build/log.o' failed
make: *** [build/log.o] Error 1

Fails to built with default setting on ubuntu 14.04

I can not compile the library with a normal "make" run.

cornelius@puckel ~/src/libnitrokey-fork (git)-[toplevel] % make
clang++-3.6 -c command_id.cc -o build/command_id.o -Iinclude/ -std=c++14 -fPIC 
clang++-3.6 -c device.cc -o build/device.o -Iinclude/ -std=c++14 -fPIC 
In file included from device.cc:2:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:55:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/tuple:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/array:38:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/string:52:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:2815:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ext/string_conversions.h:43:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:120:11: error: no member named 'gets' in the global namespace
  using ::gets;
        ~~^
In file included from device.cc:6:
include/device.h:43:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
include/device.h:45:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
2 warnings and 1 error generated.
make: *** [build/device.o] Fehler 1

I need to specify additional parameters to get the library built:

cornelius@puckel ~/src/libnitrokey-fork (git)-[toplevel] % make CXXFLAGS="-std=c++14 -fPIC -stdlib=libc++" all 
clang++-3.6 -c device.cc -o build/device.o -Iinclude/ -std=c++14 -fPIC -stdlib=libc++
In file included from device.cc:6:
include/device.h:43:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
include/device.h:45:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
2 warnings generated.
clang++-3.6 -c log.cc -o build/log.o -Iinclude/ -std=c++14 -fPIC -stdlib=libc++
clang++-3.6 -c misc.cc -o build/misc.o -Iinclude/ -std=c++14 -fPIC -stdlib=libc++
misc.cc:15:40: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
    snprintf(formatbuf, 128, "%04x\t", p - pstart);
                              ~~~~     ^~~~~~~~~~
                              %04lx
1 warning generated.
clang++-3.6 -c toplevel.cc -o build/toplevel.o -Iinclude/ -std=c++14 -fPIC -stdlib=libc++
In file included from toplevel.cc:3:
In file included from include/device_proto.h:12:
include/device.h:43:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
include/device.h:45:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
In file included from toplevel.cc:3:
include/device_proto.h:48:3: warning: field '' with variable sized type 'union (anonymous union at include/device_proto.h:48:3)' not at the end
      of a struct or class is a GNU extension [-Wgnu-variable-sized-type-not-at-end]
  union {
  ^
/usr/include/c++/v1/type_traits:2867:38: note: in instantiation of template class
      'nitrokey::proto::HIDReport' requested here
    : public integral_constant {};
                                     ^
include/device_proto.h:145:22: note: in instantiation of template class
      'std::__1::is_pod >' requested here
  static_assert(std::is_pod::value,

....

Handle time-taking commands

Due to limiting reading repeats to fail early and improve responsiveness long commands are not handled correctly at the moment - e.g. FACTORY_RESET. A good solution might be to inform libraries' core (from inside NitrokeyManager.h) before running such command about that fact, so it would make additional reads repeats. Alternatively just increase read delay for execution of one command should fix this too.

Regarding 7f7cfeb.

Add Travis support

Add Travis to check compilation under different platforms:
Ubuntu/OSX:

  • g++
  • clang

set_time not always work

Check thoroughly set_time command. In Python's unit tests it looks like its is not always working despite the OK status returned by device. The tests are not real world however: set_time should be called once on each connection (session), not every time the TOTP code is requested. To investigate further is it blocking TOTP functionality.

Compilation error on G++6 (flexible array member)

In file included from /home/brain/rpmbuild/SPECS/libnitrokey/include/NitrokeyManager.h:6:0,
                 from /home/brain/rpmbuild/SPECS/libnitrokey/NitrokeyManager.cc:3:
/home/brain/rpmbuild/SPECS/libnitrokey/include/device_proto.h:137:27: error: flexible array membernitrokey::proto::EmptyPayload::_datain an otherwise emptystruct nitrokey::proto::EmptyPayloaduint8_t _data[];
                           ^
/home/brain/rpmbuild/SPECS/libnitrokey/include/device_proto.h:136:16: note: in the definition ofstruct nitrokey::proto::EmptyPayloadstruct EmptyPayload {
                ^~~~~~~~~~~~
In file included from /home/brain/rpmbuild/SPECS/libnitrokey/include/NitrokeyManager.h:6:0,
                 from /home/brain/rpmbuild/SPECS/libnitrokey/NK_C_API.h:6,
                 from /home/brain/rpmbuild/SPECS/libnitrokey/NK_C_API.cc:2:
/home/brain/rpmbuild/SPECS/libnitrokey/include/device_proto.h:137:27: error: flexible array membernitrokey::proto::EmptyPayload::_datain an otherwise emptystruct nitrokey::proto::EmptyPayloaduint8_t _data[];
                           ^
/home/brain/rpmbuild/SPECS/libnitrokey/include/device_proto.h:136:16: note: in the definition ofstruct nitrokey::proto::EmptyPayloadstruct EmptyPayload {
                ^~~~~~~~~~~~
In file included from /home/brain/rpmbuild/SPECS/libnitrokey/unittest/../include/NitrokeyManager.h:6:0,
                 from /home/brain/rpmbuild/SPECS/libnitrokey/unittest/../NK_C_API.h:6,
                 from /home/brain/rpmbuild/SPECS/libnitrokey/unittest/test_C_API.cpp:8:
/home/brain/rpmbuild/SPECS/libnitrokey/unittest/../include/device_proto.h:137:27: error: flexible array membernitrokey::proto::EmptyPayload::_datain an otherwise emptystruct nitrokey::proto::EmptyPayloaduint8_t _data[];
                           ^
/home/brain/rpmbuild/SPECS/libnitrokey/unittest/../include/device_proto.h:136:16: note: in the definition ofstruct nitrokey::proto::EmptyPayloadstruct EmptyPayload {
                ^~~~~~~~~~~~

Add README

Should contain:

  1. description and project's target
  2. build instructions
  3. approx roadmap

Editing HOTP slot not working on NK Storage

Editing HOTP slot does not changes the counter to specified one.
Ubuntu 16.10, Storage 0.43
Editing works fine on NK Pro 0.7 and 0.8.
Seems to occur also on Nitrokey App 0.6.1.

Getter for library version

Library should allow to identify itself. It should have a function returning git describe saved on compilation time, which would consist of version tag and short commit sum.

Return OTP codes as strings

Return OTP codes as strings. Codes returned now are not formatted properly (not '0'-filled left-side) thus requiring this from client.

Python OTP test cases not working on OSX in Release mode

Test cases for OTP are not working on OSX. It looks like the OTP secret is mangled somehow - instead of RFC OTP secret there is some other data.

OSX 10.12
Python 2.7, 3.6
branches tested: master, MSVC2017 (with Python 3 support)

Edit: builder: CMake

Security check

Trace all volatile information paths to make sure it is transmitted securely.

  • Clear outgoing packets
  • Clear incoming packets
  • Fix leaks
  • Check overflows for char*
  • Move to C++ objects

Fail to build branch hotp_tests on Ubuntu 14.04

I am longing to integrate the libnitrokey into my project (https://github.com/privacyidea/privacyidea) to provide a management solution for many nitrokeys.

To do so I am taking a look at the branch hotp_tests but I failed to build it.

I am on Ubuntu 14.04.
I figured out to install libc++-dev and add

CXXFLAGS = -std=c++14 -fPIC  -stdlib=libc++

in the Makefile.

But I am ending up with

cornelius@puckel ~/src/libnitrokey (git)-[hotp_tests] % LANG=en_US make
clang++-3.6 -c command_id.cc -o build/command_id.o -Iinclude/ -std=c++14 -fPIC  -stdlib=libc++
clang++-3.6 -c device.cc -o build/device.o -Iinclude/ -std=c++14 -fPIC  -stdlib=libc++
In file included from device.cc:6:
include/device.h:43:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
include/device.h:45:3: warning: declaration does not declare anything [-Wmissing-declarations]
  const;
  ^~~~~
2 warnings generated.
clang++-3.6 -c log.cc -o build/log.o -Iinclude/ -std=c++14 -fPIC  -stdlib=libc++
clang++-3.6 -c misc.cc -o build/misc.o -Iinclude/ -std=c++14 -fPIC  -stdlib=libc++
misc.cc:15:40: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
    snprintf(formatbuf, 128, "%04x\t", p - pstart);
                              ~~~~     ^~~~~~~~~~
                              %04lx
1 warning generated.
clang++-3.6 -shared build/command_id.o build/device.o build/log.o build/misc.o -lhidapi-libusb -o build/libnitrokey.so
make -C unittest
make[1]: Entering directory `/home/cornelius/src/libnitrokey/unittest'
clang++-3.6 -M test.cc -o build/test.d -I../include -ICatch/single_include/ -std=c++14 -fPIC
test.cc:2:10: fatal error: 'catch.hpp' file not found
#include "catch.hpp"
         ^
1 error generated.
make[1]: *** [build/test.d] Error 1
make[1]: Leaving directory `/home/cornelius/src/libnitrokey/unittest'
make: *** [unittest] Error 2

Are there any build instructions?

Pass binary data (OTP secrets) coded as hex values

I am integrating libnitroky in the command line client of privacyIDEA to initialize the (H)OTP slots.
I am creating a "random" OTP seed to initilize the slot with NK_write_hotp_slot.

I think I stumbled upon a small problem. Once my random bytestring contain \x00. Right at the first position. So I guess the C++ implementation interpreted this as an empty seed. And in fact the OTP values did not match.

Maybe we should allow to pass a hexlified string as seed/otp_key

Update README and documentation

Update docs to include latest changes in library.

  • Mention feedback / collaboration request in the Readme, see #102 for details.
  • List supported devices (= Pro and Storage only)

Fails to compile on ubuntu 16.04

Commit 82a0fc2 does not compile on Ubuntu 16.04 on a raspberry pi.
Older commits compile well.

It fails with the error message

NitrokeyManager.cc:201:27: error: cannot bind packed field ‘payload.nitrokey::proto::stick10::WriteToHOTPSlot::CommandPayload::slot_counter’ to ‘long long unsigned int&’
       strcpyT(payload.slot_counter, counter.c_str());

here is the complete output:

# make CXX=g++
g++ -M misc.cc -o build/misc.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M device.cc -o build/device.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M NK_C_API.cc -o build/NK_C_API.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -M NitrokeyManager.cc -o build/NitrokeyManager.d -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -c log.cc -o build/log.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -c NK_C_API.cc -o build/NK_C_API.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
In file included from include/device_proto.h:12:0,
                 from include/NitrokeyManager.h:6,
                 from NK_C_API.h:6,
                 from NK_C_API.cc:2:
include/cxx_semantics.h:4:44: warning: ‘__packed__’ attribute ignored for field of type ‘nitrokey::proto::DeviceResponse::::’ [-Wattributes]
 #define __packed __attribute__((__packed__))
                                            ^
include/device_proto.h:108:34: note: in expansion of macro ‘__packed’
                 } storage_status __packed;
                                  ^
cc1plus: warning: unrecognized command line option ‘-Wno-gnu-variable-sized-type-not-at-end’
g++ -c device.cc -o build/device.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -c misc.cc -o build/misc.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
misc.cc: In function ‘std::__cxx11::string nitrokey::misc::hexdump(const char*, size_t, bool)’:
misc.cc:44:57: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘int’ [-Wformat=]
           snprintf(formatbuf, 128, "%04lx\t", p - pstart);
                                                         ^
misc.cc:44:57: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘int’ [-Wformat=]
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-gnu-variable-sized-type-not-at-end’
g++ -c command_id.cc -o build/command_id.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
g++ -c NitrokeyManager.cc -o build/NitrokeyManager.o -Iinclude/ -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
In file included from include/device_proto.h:12:0,
                 from include/NitrokeyManager.h:6,
                 from NitrokeyManager.cc:3:
include/cxx_semantics.h:4:44: warning: ‘__packed__’ attribute ignored for field of type ‘nitrokey::proto::DeviceResponse::::’ [-Wattributes]
 #define __packed __attribute__((__packed__))
                                            ^
include/device_proto.h:108:34: note: in expansion of macro ‘__packed’
                 } storage_status __packed;
                                  ^
NitrokeyManager.cc: In member function ‘bool nitrokey::NitrokeyManager::write_HOTP_slot(uint8_t, const char*, const char*, uint64_t, bool, bool, bool, const char*, const char*)’:
NitrokeyManager.cc:201:27: error: cannot bind packed field ‘payload.nitrokey::proto::stick10::WriteToHOTPSlot::CommandPayload::slot_counter’ to ‘long long unsigned int&’
           strcpyT(payload.slot_counter, counter.c_str());
                           ^
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-gnu-variable-sized-type-not-at-end’
Makefile:28: recipe for target 'build/NitrokeyManager.o' failed
make: *** [build/NitrokeyManager.o] Error 1

CLI client

A Python CLI client might be usable for some testing and fast access.
Would be best to make it as a package.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.