# Nitrokey Authenticator
A TOTP authenticator application, that is a drop-in relplacement for
[Google Authenticator](https://www.google-authenticator.com/),
[Authy's](https://authy.com/) TOTP authentication feature and alike.
The significant difference between this applications and the ones mentioned
above is that the secret, that the server generates for you and embeds into
the QR code, that you scan with your favorite Authenticator app, is stored
in the memory of your
[Nitrokey PRO2](https://shop.nitrokey.com/shop/product/nk-pro-2-nitrokey-pro-2-3),
or [LibremKey](https://puri.sm/products/librem-key/) USB stick

## Viable alternative: Yubico Authenticator
In principle this application in very similar to
[Yubico Authenticator](https://www.yubico.com/products/services-software/download/yubico-authenticator/),
that stores the secrets in your [Yubikey](https://www.yubico.com/).

### Caveats
Yubico Authenticator is great software and I've used it a lot. But it's a
proprietary software that works with proprietary hardware. You can't know
everything, that the authenticator app is doing. Nor can you audit Yubikey's
firmware. If you truly care about openess of the software, you're running,
you're out of luck with Yubico Authenticator.

Yubico Authenticator supports couple of plaftorms, you might care about:

* Windows
* GNU/Linux
* MacOS
* Android
* iOS

If you prefer BSD-family open-source system, you're out of luck.

# Installing and using
It's early into development process, so you're not installing it system-wide.
You only get and compile the source code.

## Steps for PureOS Amber (Stable)
Follow these steps only if you intend to install NitrokeyAuthenticator on
PureOS Amber (Stable as of July, 2020). NitrokeyAuthenticator depends on
zbar version 0.23.1, which is not available in PureOS Amber, thus we'll need to
back-port it from PureOS Byzantium (Testing):
```bash
$ sudo apt install -y devscripts dh-exec dh-sequence-python3 libdbus-1-dev libgtk2.0-dev \
  libjpeg-dev libmagick++-dev libqt5x11extras5-dev libv4l-dev libx11-dev pkg-config \
  python3-dev:any qtbase5-dev xmlto libgtk-3-dev
$ cd
$ dget https://repo.pureos.net/pureos/pool/main/z/zbar/zbar_0.23.1-1.dsc
$ cd zbar-0.23.1
$ debuild -us -uc
```
It'll build correctly, but lintial will complain loudly -- you'll see something like this:
```bash
E: zbar changes: bad-distribution-in-changes-file unstable
E: zbar changes: changed-by-invalid-for-derivative Boyuan Yang <byang@debian.org> (should use @puri.sm email addresses)
E: zbar source: python3-depends-but-no-python3-helper python3-zbar
E: zbar source: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbar source: invalid-field-for-derivative maintainer: G??rkan Myczko <gurkan@phys.ethz.ch> (!= PureOS Maintainers <pureos-project@lists.puri.sm>)
E: zbar source: invalid-field-for-derivative uploaders: Boyuan Yang <byang@debian.org>, (field must be empty)
E: zbar source: invalid-field-for-derivative vcs-git: https://salsa.debian.org/debian/zbar.git (must point to https://source.puri.sm/pureos/group/pkg.git)
E: zbar source: invalid-field-for-derivative ... use --no-tag-display-limit to see all (or pipe to a file/program)
W: zbar source: newer-standards-version 4.5.0 (current is 4.3.0)
E: libzbar-dev: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbarqt-dev: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbar0-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbarqt0-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libbarcode-zbar-perl-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbarcam-qt-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbargtk0: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbarqt0: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libbarcode-zbar-perl: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbarcam-gtk: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
W: zbarcam-gtk: binary-without-manpage usr/bin/zbarcam-gtk
E: python3-zbar-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: python3-zbar: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbarcam-qt: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
W: zbarcam-qt: binary-without-manpage usr/bin/zbarcam-qt
E: libzbargtk0-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbar-tools-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbar0: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbarcam-gtk-dbgsym: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: zbar-tools: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
E: libzbargtk-dev: invalid-version-number-for-derivative 0.23.1-1 (must end with pureosX)
Finished running lintian.
```
But zbar has built correctly and now you'll see a bunch of `.deb` files. You need only 3 of them:
```bash
$ cd ..
$ sudo apt install ./libzbar0_0.23.1-1_amd64.deb ./libzbar-dev_0.23.1-1_amd64.deb \
  ./libzbarqt0_0.23.1-1_amd64.deb ./libzbarqt-dev_0.23.1-1_amd64.deb
```
At this point, you have zbar in a correct version.

## Install prerequisites
If you're using Debian or any of its derivatives (including
[PureOS](https://www.pureos.net/)), the following will pull in all
compile-time and run-time dependencies:
```bash
$ sudo apt install -y build-essential cmake git pkg-config libgtest-dev qtbase5-dev \
  qttools5-dev libzbarqt-dev libhidapi-dev libboost-log-dev scdaemon
```

## Getting the source code
```bash
$ cd
$ mkdir nitrokey_authenticator_building
$ cd nitrokey_authenticator_building
$ git clone https://salsa.debian.org/patryk/nitrokeyauthenticator.git
$ cd nitrokeyauthenticator
$ git submodule init
$ git submodule update
```

## Hacking libnitrokey to recognize LibremKey
We're using [libnitrokey](https://github.com/Nitrokey/libnitrokey/) to talk to
Nitrokey PRO2 and LibremKey. If you're using Nitrokey PRO2, you can use libnitrokey 3.5,
or older. But LibremKey will only work with libnitrokey 3.6 or newer. If 3.6 is not there
in your distro's repo, you can pull it from git. In master branch LibremKey is already
supported, so you can temporarily compile it yourself (you have the
code already -- you downloaded it using `git submodule` above.

## And finally build
```bash
$ cd
$ cd nitrokey_authenticator_building
$ mkdir build_nitrokeyauthenticator
$ cd build_nitrokeyauthenticator
```
Now, if you wish to hack around, you'll probably want to build unit tests. If you only want to use the app,
you can skip building tests. To build tests:
```bash
cmake -DPACKAGE_TESTS=ON ../nitrokeyauthenticator
```

To skip tests:
```bash
$ cmake ../nitrokeyauthenticator
```

And finally compile the app and install it to `/usr/local/bin`. Since for now we're also installing the (yet)
unreleased version of libnitrokey, we also have to run `ldconfig` as root:
```bash
$ make
$ sudo make install
$ sudo ldconfig
```

And you can run it now:
```bash
$ NitrokeyAuthenticator
```

## Hacking
For testing we're using [GoogleTest](https://github.com/google/googletest). We're documenting APIs
using [Doxygen](http://doxygen.nl/). We also have a simple
[pipeline](https://salsa.debian.org/patryk/nitrokeyauthenticator/-/blob/master/.gitlab-ci.yml), that
build the code and runs unit tests. Look [here](https://salsa.debian.org/patryk/nitrokeyauthenticator/pipelines/137696)
for an example execution of the pipeline. There are 2 stages: `build_debian` and `test_debian`.

All unit tests are contained within `tests` target. If you want to run tests against actual
USB key, put them within `dontAddToCTest` target -- it will not be executed automatically
by the pipeline. You can run it, however, to test any Nitrokey PRO2/LibremKey integration.
Bear in mind, however, that those tests will mess up any TOTP slots, you might have on your
key. Thus, don't run it against the key, you use for your authentication. Better to have a
separate spare key for development and testing.

Typical workflow, after running `cmake`, is:
```bash
$ # Modify the code
$ make
$ ctest ../nitrokeyauthenticator
$ # Repeat
```

