nitrokey-app-1.3.2/.clang-format0000644000175000017500000000512212774475055016074 0ustar janjan00000000000000--- Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -2 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlinesLeft: false AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: false BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false BeforeCatch: false BeforeElse: false IndentBraces: false BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false ColumnLimit: 100 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] IncludeCategories: - Regex: '^"(llvm|llvm-c|clang|clang-c)/' Priority: 2 - Regex: '^(<|"(gtest|isl|json)/)' Priority: 3 - Regex: '.*' Priority: 1 IndentCaseLabels: false IndentWidth: 2 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: true MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBlockIndentWidth: 2 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: true SortIncludes: true SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp11 TabWidth: 8 UseTab: Never ... nitrokey-app-1.3.2/.github/issue_template.md0000644000175000017500000000200713221173116020402 0ustar janjan00000000000000[Please fill in below details as much as possible and remove this line and other unneded data. Please provide more details for issues occurring less often.] - Application version: [e.g. v1.1 - it is shown in `About` window] - Operating system: [name, version, 32/64 bits, kernel version (if Linux) ] - Device model and firmware version: [Pro v0.8/Storage v0.45 etc.] - Connected USB port type: [1.1/2.0/3.0] - Issue occurrency: [always/sometimes/once] ### Expected behaviour ### Current behaviour ### Steps for reproduction #### Preconditions [Device reinserted, Application just started, Application used for almost 30 minutes etc.] #### Steps 1. 2. 3. 4. ### Logs [Please take logs and attach them as text files here when needed. For UI issues or `always` frequency it is not required but might increase investigation speed. [How to take logs?](https://github.com/Nitrokey/nitrokey-app/wiki/How-to-take-logs-in-Nitrokey-App-v1.1). To attach logs please `drag and drop` log file to the edit field.] Logs attached: - nitrokey-app-1.3.2/.gitignore0000644000175000017500000000033412774475055015511 0ustar janjan00000000000000*.pro.user* build release build-*-Debug *~ *.o *.lst .* *.exe !/.travis.yml !/.gitignore moc_*.cpp ui_*.h *tags install CMakeCache.txt Makefile nitrokey-app *.*_parameters *.depends *.cmake CMakeFiles/ qrc_resources.cpp nitrokey-app-1.3.2/.gitmodules0000644000175000017500000000027713221174507015666 0ustar janjan00000000000000[submodule "libnitrokey"] path = libnitrokey url = https://github.com/Nitrokey/libnitrokey.git [submodule "cppcodec"] path = 3rdparty/cppcodec url = https://github.com/tplgy/cppcodec.git nitrokey-app-1.3.2/.travis.yml0000644000175000017500000000451213275777051015632 0ustar janjan00000000000000language: generic notifications: email: false os: - linux sudo: true #for beineri qt561 dist: trusty before_install: - sudo add-apt-repository --yes ppa:beineri/opt-qt562-trusty - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test - sudo apt-get -qq update - sudo apt-get -qq install ${AF} qt56base qt56tools qt56svg # qttools5-dev - sudo apt-get -qq install ${AF} cmake libhidapi-dev ${COMP} - sudo apt-get -qq remove gcc-4.8 g++-4.8 --purge cache: - apt script: | echo "${TRAVIS_OS_NAME}" if [ "${TRAVIS_OS_NAME}" == "linux" ]; then source /opt/qt56/bin/qt56-env.sh ; export QMAKE=/opt/qt56/bin/qmake; fi if [ "$builder" == "qmake" ]; then ${QMAKE} if [ "${TRAVIS_OS_NAME}" == "osx" ]; then make || exit 1; fi if [ "${TRAVIS_OS_NAME}" == "linux" ]; then make CXX=${CXX} CC=${CC} LINK=${CXX} || exit 1 ; fi elif [ "$builder" == "cmake" ]; then cmake -DERROR_ON_WARNING=ON . && make VERBOSE=1 || exit 1; fi env: matrix: - builder=cmake CXX=clang++-3.8 CC=clang-3.8 COMP="clang-3.8 g++-5" - builder=qmake CXX=clang++-3.8 CC=clang-3.8 COMP="clang-3.8 g++-5" - builder=cmake CXX=g++-5 CC=gcc-5 COMP=g++-5 - builder=qmake CXX=g++-5 CC=gcc-5 COMP=g++-5 - builder=qmake CXX=g++-6 CC=gcc-6 COMP=g++-6 global: - AF="-yq --no-install-suggests --no-install-recommends --force-yes" QMAKE=qmake matrix: exclude: include: - os: osx osx_image: xcode7.3 #default before_install: &before - brew update - brew install qt5 - brew unlink cmake - brew install cmake - export env: builder=cmake PATH="/usr/local/opt/qt5/bin:$PATH" CMAKE_PREFIX_PATH=/usr/local/lib/cmake MACOS_DEPLOYMENT_TARGET=10.9 - os: osx osx_image: xcode7.3 #default before_install: *before env: builder=qmake PATH="/usr/local/opt/qt5/bin:$PATH" CMAKE_PREFIX_PATH=/usr/local/lib/cmake MACOS_DEPLOYMENT_TARGET=10.9 - os: osx osx_image: xcode8.3 before_install: *before env: builder=qmake PATH="/usr/local/opt/qt5/bin:$PATH" CMAKE_PREFIX_PATH=/usr/local/lib/cmake MACOS_DEPLOYMENT_TARGET=10.9 - os: osx osx_image: xcode9.1 before_install: *before env: builder=qmake PATH="/usr/local/opt/qt5/bin:$PATH" CMAKE_PREFIX_PATH=/usr/local/lib/cmake MACOS_DEPLOYMENT_TARGET=10.9 nitrokey-app-1.3.2/3RDPARTY.txt0000644000175000017500000000042613221173116015451 0ustar janjan00000000000000This project uses the following components with proper licenses: - Qt Framework, GPLv3, https://www.qt.io - libnitrokey, LGPLv3, https://github.com/Nitrokey/libnitrokey, located in ./libnitrokey/ - cppcodec, MIT, https://github.com/tplgy/cppcodec, located in ./3rdparty/cppcodecnitrokey-app-1.3.2/CHANGELOG.md0000644000175000017500000007317713232102303015316 0ustar janjan00000000000000# Change Log ## [v1.2.1](https://github.com/Nitrokey/nitrokey-app/tree/v1.2.1) (2018-01-17) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.2...v1.2.1) **Fixed bugs:** - v.1.2-beta.4 not cooperating with VM/Virtualbox \(Windows'es 7/10 do not detect the device\) [\#300](https://github.com/Nitrokey/nitrokey-app/issues/300) **Closed issues:** - Windows 10 - device is disconnecting after 30-60 seconds [\#252](https://github.com/Nitrokey/nitrokey-app/issues/252) ## [v1.2](https://github.com/Nitrokey/nitrokey-app/tree/v1.2) (2017-12-20) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.2-beta.4...v1.2) **Closed issues:** - Wrong disconnection message on `real` disconnection [\#258](https://github.com/Nitrokey/nitrokey-app/issues/258) - macOS 10.12.5 - wrong information in the About Box - encrypted volume [\#248](https://github.com/Nitrokey/nitrokey-app/issues/248) - Setting TOTP secret with Paypal is not working [\#239](https://github.com/Nitrokey/nitrokey-app/issues/239) ## [v1.2-beta.4](https://github.com/Nitrokey/nitrokey-app/tree/v1.2-beta.4) (2017-12-01) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.2-beta.3...v1.2-beta.4) **Fixed bugs:** - OTP generation always asks for User PIN [\#250](https://github.com/Nitrokey/nitrokey-app/issues/250) **Closed issues:** - Application icon looks poor [\#297](https://github.com/Nitrokey/nitrokey-app/issues/297) - Warning for MacOS and Storage v0.48 [\#287](https://github.com/Nitrokey/nitrokey-app/issues/287) - OTP with Tutanota Mail \(codec expects padded input string\) [\#280](https://github.com/Nitrokey/nitrokey-app/issues/280) - nitrokey-app doesn't compile with latest libnitrokey [\#279](https://github.com/Nitrokey/nitrokey-app/issues/279) - About-Box confusing with NK Pro [\#272](https://github.com/Nitrokey/nitrokey-app/issues/272) - Crash on invalid base32 OTP secret [\#240](https://github.com/Nitrokey/nitrokey-app/issues/240) ## [v1.2-beta.3](https://github.com/Nitrokey/nitrokey-app/tree/v1.2-beta.3) (2017-10-17) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.2-beta.2...v1.2-beta.3) **Closed issues:** - build: udev rules and bash completion is installed in /usr/usr/... [\#275](https://github.com/Nitrokey/nitrokey-app/issues/275) - Set proper license for RPM package [\#268](https://github.com/Nitrokey/nitrokey-app/issues/268) - Configuration of Passwordsafe - wrong language shown [\#265](https://github.com/Nitrokey/nitrokey-app/issues/265) ## [v1.2-beta.2](https://github.com/Nitrokey/nitrokey-app/tree/v1.2-beta.2) (2017-09-20) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.2-beta.1...v1.2-beta.2) **Fixed bugs:** - macOS build artifacts are damaged [\#246](https://github.com/Nitrokey/nitrokey-app/issues/246) **Closed issues:** - \[osx\] "The app has been modified or damaged" [\#260](https://github.com/Nitrokey/nitrokey-app/issues/260) - Update installation instructions for Fedora [\#192](https://github.com/Nitrokey/nitrokey-app/issues/192) - Some functions not working reliably on openSUSE Tumbleweed [\#181](https://github.com/Nitrokey/nitrokey-app/issues/181) ## [v1.2-beta.1](https://github.com/Nitrokey/nitrokey-app/tree/v1.2-beta.1) (2017-06-01) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.1...v1.2-beta.1) **Implemented enhancements:** - Make the Nitrokey app more secure \(sig binary, provide checksums+GPG\) [\#110](https://github.com/Nitrokey/nitrokey-app/issues/110) **Closed issues:** - Ask user for AES key generation if there is none [\#238](https://github.com/Nitrokey/nitrokey-app/issues/238) ## [v1.1](https://github.com/Nitrokey/nitrokey-app/tree/v1.1) (2017-05-15) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.0...v1.1) **Implemented enhancements:** - Sign using Apple's Binary Signing [\#16](https://github.com/Nitrokey/nitrokey-app/issues/16) **Fixed bugs:** - Log level set too verbose by default [\#244](https://github.com/Nitrokey/nitrokey-app/issues/244) - No device is detected on Windows [\#243](https://github.com/Nitrokey/nitrokey-app/issues/243) - Cannot get PIN-protected OTP code on NK Pro 0.8 [\#242](https://github.com/Nitrokey/nitrokey-app/issues/242) **Closed issues:** - Improper temporary password [\#245](https://github.com/Nitrokey/nitrokey-app/issues/245) - Update translations [\#241](https://github.com/Nitrokey/nitrokey-app/issues/241) - Hidden volume is volatile - check on Mac [\#37](https://github.com/Nitrokey/nitrokey-app/issues/37) - Vector Icon [\#20](https://github.com/Nitrokey/nitrokey-app/issues/20) ## [v1.0](https://github.com/Nitrokey/nitrokey-app/tree/v1.0) (2017-04-26) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.0-beta.3...v1.0) **Implemented enhancements:** - Nitrokey App should be more accessible to screen reader users [\#9](https://github.com/Nitrokey/nitrokey-app/issues/9) **Closed issues:** - 'Filling SD Card' box should not be always on top [\#182](https://github.com/Nitrokey/nitrokey-app/issues/182) - Handling of sensitive data in HID transactions [\#113](https://github.com/Nitrokey/nitrokey-app/issues/113) - Insecure Password handling [\#84](https://github.com/Nitrokey/nitrokey-app/issues/84) - Send debug messages to both file and debug window [\#73](https://github.com/Nitrokey/nitrokey-app/issues/73) ## [v1.0-beta.3](https://github.com/Nitrokey/nitrokey-app/tree/v1.0-beta.3) (2017-04-11) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.0-beta.2...v1.0-beta.3) **Fixed bugs:** - NK Pro: Reset User PIN is not shown immediately in menu [\#108](https://github.com/Nitrokey/nitrokey-app/issues/108) **Closed issues:** - Warnings update from 0.6.3 [\#224](https://github.com/Nitrokey/nitrokey-app/issues/224) - automatic detection for bash\_completion directory [\#189](https://github.com/Nitrokey/nitrokey-app/issues/189) - NK Storage is not detected immediately after insertion [\#186](https://github.com/Nitrokey/nitrokey-app/issues/186) - Remove libappindicator support [\#177](https://github.com/Nitrokey/nitrokey-app/issues/177) - Windows: About window's width is same as screen width [\#29](https://github.com/Nitrokey/nitrokey-app/issues/29) ## [v1.0-beta.2](https://github.com/Nitrokey/nitrokey-app/tree/v1.0-beta.2) (2017-04-03) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v1.0-beta.1...v1.0-beta.2) **Implemented enhancements:** - UI: On first run show information about tray icon [\#111](https://github.com/Nitrokey/nitrokey-app/issues/111) **Fixed bugs:** - UI: OTP secret field not cleared after slot writing [\#237](https://github.com/Nitrokey/nitrokey-app/issues/237) - Invalid OTP code when 0's are first digit [\#236](https://github.com/Nitrokey/nitrokey-app/issues/236) - Invalid feedback on changing admin PIN [\#230](https://github.com/Nitrokey/nitrokey-app/issues/230) **Closed issues:** - Fix compilation warnings [\#235](https://github.com/Nitrokey/nitrokey-app/issues/235) - Not building on Ubuntu 16.04 [\#234](https://github.com/Nitrokey/nitrokey-app/issues/234) - Workaround for Storage crash [\#233](https://github.com/Nitrokey/nitrokey-app/issues/233) - App is very nonreactive [\#227](https://github.com/Nitrokey/nitrokey-app/issues/227) - Editing OTP slot is not working [\#209](https://github.com/Nitrokey/nitrokey-app/issues/209) - not whole sources are under GPLv3+ [\#191](https://github.com/Nitrokey/nitrokey-app/issues/191) ## [v1.0-beta.1](https://github.com/Nitrokey/nitrokey-app/tree/v1.0-beta.1) (2017-03-20) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.6.3...v1.0-beta.1) ## [v0.6.3](https://github.com/Nitrokey/nitrokey-app/tree/v0.6.3) (2017-01-23) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.6.2...v0.6.3) **Closed issues:** - Do not enable new HID protocol for Storage yet [\#218](https://github.com/Nitrokey/nitrokey-app/issues/218) - nitrokey-app keeps asking for admin PIN when trying to configure TOTP or HOTP slot [\#211](https://github.com/Nitrokey/nitrokey-app/issues/211) **Merged pull requests:** - Bump version to 0.6.3 [\#220](https://github.com/Nitrokey/nitrokey-app/pull/220) ([szszszsz](https://github.com/szszszsz)) - Disable support of new HID protocol for Storage [\#219](https://github.com/Nitrokey/nitrokey-app/pull/219) ([szszszsz](https://github.com/szszszsz)) - Debian packaging rules changes [\#217](https://github.com/Nitrokey/nitrokey-app/pull/217) ([szszszsz](https://github.com/szszszsz)) ## [v0.6.2](https://github.com/Nitrokey/nitrokey-app/tree/v0.6.2) (2017-01-03) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.6.1...v0.6.2) **Fixed bugs:** - OTP not working on Windows [\#214](https://github.com/Nitrokey/nitrokey-app/issues/214) **Merged pull requests:** - Bump version to 0.6.2 [\#216](https://github.com/Nitrokey/nitrokey-app/pull/216) ([szszszsz](https://github.com/szszszsz)) - Pack union for writing OTP slot data [\#215](https://github.com/Nitrokey/nitrokey-app/pull/215) ([szszszsz](https://github.com/szszszsz)) - Do not block on waiting for symlink to storage being available [\#213](https://github.com/Nitrokey/nitrokey-app/pull/213) ([szszszsz](https://github.com/szszszsz)) - Break asking PIN loop when user cancels it [\#212](https://github.com/Nitrokey/nitrokey-app/pull/212) ([szszszsz](https://github.com/szszszsz)) - Fix compilation warnings [\#208](https://github.com/Nitrokey/nitrokey-app/pull/208) ([szszszsz](https://github.com/szszszsz)) ## [v0.6.1](https://github.com/Nitrokey/nitrokey-app/tree/v0.6.1) (2016-12-01) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.6...v0.6.1) **Merged pull requests:** - Use native settings handler [\#206](https://github.com/Nitrokey/nitrokey-app/pull/206) ([szszszsz](https://github.com/szszszsz)) - Bump version to 0.6.1 [\#205](https://github.com/Nitrokey/nitrokey-app/pull/205) ([szszszsz](https://github.com/szszszsz)) - Add Arabic translation to resource file [\#204](https://github.com/Nitrokey/nitrokey-app/pull/204) ([szszszsz](https://github.com/szszszsz)) ## [v0.6](https://github.com/Nitrokey/nitrokey-app/tree/v0.6) (2016-11-28) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.5.1...v0.6) **Implemented enhancements:** - Support for Pro stick version 0.8 [\#190](https://github.com/Nitrokey/nitrokey-app/issues/190) **Closed issues:** - Add command line parameter to force language [\#199](https://github.com/Nitrokey/nitrokey-app/issues/199) - OTP secret field's max length changes only with text inside [\#195](https://github.com/Nitrokey/nitrokey-app/issues/195) - Fedora 23 RPM has conflicts [\#193](https://github.com/Nitrokey/nitrokey-app/issues/193) - RPM package installs in wrong directory [\#178](https://github.com/Nitrokey/nitrokey-app/issues/178) - Invisible tray icon on openSUSE Tumbleweed unless run as root [\#176](https://github.com/Nitrokey/nitrokey-app/issues/176) - Mac OS X version and missing QT libraries [\#163](https://github.com/Nitrokey/nitrokey-app/issues/163) **Merged pull requests:** - Changelog update [\#203](https://github.com/Nitrokey/nitrokey-app/pull/203) ([szszszsz](https://github.com/szszszsz)) - Update README.md [\#202](https://github.com/Nitrokey/nitrokey-app/pull/202) ([szszszsz](https://github.com/szszszsz)) - Add language CLI param [\#200](https://github.com/Nitrokey/nitrokey-app/pull/200) ([szszszsz](https://github.com/szszszsz)) - Bump version to 0.6 [\#198](https://github.com/Nitrokey/nitrokey-app/pull/198) ([szszszsz](https://github.com/szszszsz)) - Support for Nitrokey Pro 0.8 [\#196](https://github.com/Nitrokey/nitrokey-app/pull/196) ([szszszsz](https://github.com/szszszsz)) - Resolve conflict with udev rules \(for Fedora 23\) [\#194](https://github.com/Nitrokey/nitrokey-app/pull/194) ([vladimir-lu](https://github.com/vladimir-lu)) - build: set CMAKE\_BUILD\_TYPE only if not set [\#188](https://github.com/Nitrokey/nitrokey-app/pull/188) ([ignatenkobrain](https://github.com/ignatenkobrain)) - Translations: initial support for Arabic \(ar\) language [\#183](https://github.com/Nitrokey/nitrokey-app/pull/183) ([szszszsz](https://github.com/szszszsz)) - Change RPM package installation dir [\#180](https://github.com/Nitrokey/nitrokey-app/pull/180) ([szszszsz](https://github.com/szszszsz)) - Update README.md [\#179](https://github.com/Nitrokey/nitrokey-app/pull/179) ([szszszsz](https://github.com/szszszsz)) - Update changelog [\#174](https://github.com/Nitrokey/nitrokey-app/pull/174) ([szszszsz](https://github.com/szszszsz)) ## [v0.5.1](https://github.com/Nitrokey/nitrokey-app/tree/v0.5.1) (2016-10-08) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.5...v0.5.1) **Closed issues:** - Retry counters are not updated before opening About form \(NK Storage\) [\#170](https://github.com/Nitrokey/nitrokey-app/issues/170) - No failure feedback when user erases OTP slot [\#168](https://github.com/Nitrokey/nitrokey-app/issues/168) - Confirm erasing PWS slot [\#167](https://github.com/Nitrokey/nitrokey-app/issues/167) - Display NK Storage capacity in About window [\#162](https://github.com/Nitrokey/nitrokey-app/issues/162) - Abort action when device is not initialized [\#156](https://github.com/Nitrokey/nitrokey-app/issues/156) - Buffer overflow while adding OTP [\#155](https://github.com/Nitrokey/nitrokey-app/issues/155) - Provide binaries for Ubuntu via Launchpad [\#115](https://github.com/Nitrokey/nitrokey-app/issues/115) - show success dialogue when saving a new static password: [\#57](https://github.com/Nitrokey/nitrokey-app/issues/57) **Merged pull requests:** - Fix typo in debian/changelog [\#173](https://github.com/Nitrokey/nitrokey-app/pull/173) ([szszszsz](https://github.com/szszszsz)) - Bump version to 0.5.1 [\#172](https://github.com/Nitrokey/nitrokey-app/pull/172) ([szszszsz](https://github.com/szszszsz)) - Confirm erasing slot in Password Safe. Handle confirmation properly in OTP. [\#171](https://github.com/Nitrokey/nitrokey-app/pull/171) ([szszszsz](https://github.com/szszszsz)) - Abort sending command to uninitialized device [\#169](https://github.com/Nitrokey/nitrokey-app/pull/169) ([szszszsz](https://github.com/szszszsz)) - Show feedback message after saving password to Password Safe [\#166](https://github.com/Nitrokey/nitrokey-app/pull/166) ([szszszsz](https://github.com/szszszsz)) - Add to About window stick's storage capacity [\#165](https://github.com/Nitrokey/nitrokey-app/pull/165) ([szszszsz](https://github.com/szszszsz)) - Avoid buffer overflow during hex\<-\>base32 conversion [\#164](https://github.com/Nitrokey/nitrokey-app/pull/164) ([szszszsz](https://github.com/szszszsz)) - Remove issues closed as duplicate from the changelog [\#160](https://github.com/Nitrokey/nitrokey-app/pull/160) ([szszszsz](https://github.com/szszszsz)) - Add CHANGELOG.md generated with github-changelog-generator [\#159](https://github.com/Nitrokey/nitrokey-app/pull/159) ([szszszsz](https://github.com/szszszsz)) ## [v0.5](https://github.com/Nitrokey/nitrokey-app/tree/v0.5) (2016-09-28) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.4...v0.5) **Implemented enhancements:** - Improve dialogue to setup hidden volumes [\#106](https://github.com/Nitrokey/nitrokey-app/issues/106) **Fixed bugs:** - NK Pro: Impossible to write consecutive HOTP codes [\#62](https://github.com/Nitrokey/nitrokey-app/issues/62) - Exception after checking HOTP password with open configuration form [\#30](https://github.com/Nitrokey/nitrokey-app/issues/30) **Closed issues:** - Update translations before release 0.5 [\#150](https://github.com/Nitrokey/nitrokey-app/issues/150) - Sequential erasing of OTP slots not working [\#146](https://github.com/Nitrokey/nitrokey-app/issues/146) - Remove test OTP controls from configuration window [\#145](https://github.com/Nitrokey/nitrokey-app/issues/145) - PIN protect OTP not working on first request with Storage [\#144](https://github.com/Nitrokey/nitrokey-app/issues/144) - Change PIN does not work [\#143](https://github.com/Nitrokey/nitrokey-app/issues/143) - Crash when showing message box [\#142](https://github.com/Nitrokey/nitrokey-app/issues/142) - Warn about OTP secrets starting from 0x00 [\#139](https://github.com/Nitrokey/nitrokey-app/issues/139) - Send 20 null bytes as a secret on OTP edit [\#138](https://github.com/Nitrokey/nitrokey-app/issues/138) - Password Safe: Store Unicode characters in passwords [\#131](https://github.com/Nitrokey/nitrokey-app/issues/131) - Notification Window after initialization [\#130](https://github.com/Nitrokey/nitrokey-app/issues/130) - Make `Forget PIN after 10 minutes` option work again [\#109](https://github.com/Nitrokey/nitrokey-app/issues/109) - Add warning that Firmware Password can not be reset [\#103](https://github.com/Nitrokey/nitrokey-app/issues/103) - Add guidelines for contributing [\#75](https://github.com/Nitrokey/nitrokey-app/issues/75) - Improve usability of hidden volume setup form [\#72](https://github.com/Nitrokey/nitrokey-app/issues/72) - Check feedback for password changing with Nitrokey Pro [\#68](https://github.com/Nitrokey/nitrokey-app/issues/68) - Check clipboard clearing mechanism for password safe [\#54](https://github.com/Nitrokey/nitrokey-app/issues/54) - Various packaging related problems [\#11](https://github.com/Nitrokey/nitrokey-app/issues/11) **Merged pull requests:** - Bump version to 0.5.0 [\#158](https://github.com/Nitrokey/nitrokey-app/pull/158) ([szszszsz](https://github.com/szszszsz)) - Update translations before 0.5 release [\#157](https://github.com/Nitrokey/nitrokey-app/pull/157) ([szszszsz](https://github.com/szszszsz)) - Remove locations from translation files [\#154](https://github.com/Nitrokey/nitrokey-app/pull/154) ([szszszsz](https://github.com/szszszsz)) - Ask for device's reinsertion when its locked [\#153](https://github.com/Nitrokey/nitrokey-app/pull/153) ([szszszsz](https://github.com/szszszsz)) - Warn user about secret starting from 0x00 [\#152](https://github.com/Nitrokey/nitrokey-app/pull/152) ([szszszsz](https://github.com/szszszsz)) - Refactoring: mainWindow::on\_writeButton [\#151](https://github.com/Nitrokey/nitrokey-app/pull/151) ([szszszsz](https://github.com/szszszsz)) - Code refactoring in an attempt to fix \#142 [\#149](https://github.com/Nitrokey/nitrokey-app/pull/149) ([szszszsz](https://github.com/szszszsz)) - Remove test HOTP TOTP from configuration window \#145 [\#148](https://github.com/Nitrokey/nitrokey-app/pull/148) ([szszszsz](https://github.com/szszszsz)) - remember PIN for NK Pro while requesting PIN protected OTP [\#147](https://github.com/Nitrokey/nitrokey-app/pull/147) ([szszszsz](https://github.com/szszszsz)) - Readme - update links in internals section [\#141](https://github.com/Nitrokey/nitrokey-app/pull/141) ([szszszsz](https://github.com/szszszsz)) - Issue 130 Reinsert notification after initialization [\#134](https://github.com/Nitrokey/nitrokey-app/pull/134) ([szszszsz](https://github.com/szszszsz)) - Issue 131 Unicode characters for Password Safe [\#133](https://github.com/Nitrokey/nitrokey-app/pull/133) ([szszszsz](https://github.com/szszszsz)) - Issue 11 packaging related problems [\#132](https://github.com/Nitrokey/nitrokey-app/pull/132) ([szszszsz](https://github.com/szszszsz)) - Build package on launchpad 2 [\#129](https://github.com/Nitrokey/nitrokey-app/pull/129) ([szszszsz](https://github.com/szszszsz)) - Travis: remove qt5declarative depend package from build [\#128](https://github.com/Nitrokey/nitrokey-app/pull/128) ([szszszsz](https://github.com/szszszsz)) - Adjust debian package creating script for launchpad.net [\#127](https://github.com/Nitrokey/nitrokey-app/pull/127) ([szszszsz](https://github.com/szszszsz)) - Hidden setup usability fix [\#126](https://github.com/Nitrokey/nitrokey-app/pull/126) ([szszszsz](https://github.com/szszszsz)) - Add contribution guidelines [\#125](https://github.com/Nitrokey/nitrokey-app/pull/125) ([szszszsz](https://github.com/szszszsz)) - Add license copy to repository - GPLv3 [\#124](https://github.com/Nitrokey/nitrokey-app/pull/124) ([szszszsz](https://github.com/szszszsz)) - Add missing udev entry for Nitrokey Storage [\#123](https://github.com/Nitrokey/nitrokey-app/pull/123) ([szszszsz](https://github.com/szszszsz)) - Update udev rules [\#122](https://github.com/Nitrokey/nitrokey-app/pull/122) ([szszszsz](https://github.com/szszszsz)) - Code reformat only for modified files vs master branch [\#120](https://github.com/Nitrokey/nitrokey-app/pull/120) ([szszszsz](https://github.com/szszszsz)) - Issue 54 clipboard clearing [\#117](https://github.com/Nitrokey/nitrokey-app/pull/117) ([szszszsz](https://github.com/szszszsz)) - Add warning that Firmware Password can not be reset \#103 [\#116](https://github.com/Nitrokey/nitrokey-app/pull/116) ([szszszsz](https://github.com/szszszsz)) - Debian packaging patch [\#112](https://github.com/Nitrokey/nitrokey-app/pull/112) ([szszszsz](https://github.com/szszszsz)) - Issue 68 password feedback pro [\#107](https://github.com/Nitrokey/nitrokey-app/pull/107) ([szszszsz](https://github.com/szszszsz)) - Add missing forward declaration [\#105](https://github.com/Nitrokey/nitrokey-app/pull/105) ([ansiwen](https://github.com/ansiwen)) - prevent make install dirty the root filesystem, stick to the prefix [\#89](https://github.com/Nitrokey/nitrokey-app/pull/89) ([szszszsz](https://github.com/szszszsz)) - Update travis configuration for application build [\#69](https://github.com/Nitrokey/nitrokey-app/pull/69) ([szszszsz](https://github.com/szszszsz)) ## [v0.4](https://github.com/Nitrokey/nitrokey-app/tree/v0.4) (2016-07-02) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.3.2...v0.4) **Implemented enhancements:** - document CLI interface [\#24](https://github.com/Nitrokey/nitrokey-app/issues/24) **Fixed bugs:** - Only three passwords displayed [\#78](https://github.com/Nitrokey/nitrokey-app/issues/78) - NK Storage: Changing Firmware Password doesn't work [\#71](https://github.com/Nitrokey/nitrokey-app/issues/71) - NK Storage: Counter value is not written for HOTP [\#60](https://github.com/Nitrokey/nitrokey-app/issues/60) - The tray icon isn't displayed [\#43](https://github.com/Nitrokey/nitrokey-app/issues/43) - Application not compiling under qmake [\#40](https://github.com/Nitrokey/nitrokey-app/issues/40) - No feedback after changing password [\#38](https://github.com/Nitrokey/nitrokey-app/issues/38) **Closed issues:** - Limit password length for firmware password in password dialog [\#100](https://github.com/Nitrokey/nitrokey-app/issues/100) - Check feedback for firmware password changing with Nitrokey Storage [\#97](https://github.com/Nitrokey/nitrokey-app/issues/97) - Can't unlock password safe [\#96](https://github.com/Nitrokey/nitrokey-app/issues/96) - Can't configure hidden volume [\#95](https://github.com/Nitrokey/nitrokey-app/issues/95) - Readme: remove section about building from sources with QT4 [\#85](https://github.com/Nitrokey/nitrokey-app/issues/85) - Only first TOTP is valid [\#82](https://github.com/Nitrokey/nitrokey-app/issues/82) - USB 3.0: Updating progress bar during clearing SD card is not working [\#76](https://github.com/Nitrokey/nitrokey-app/issues/76) - NK Storage: About dialog does not show current retry counts [\#66](https://github.com/Nitrokey/nitrokey-app/issues/66) - Show available password retry count in change password form [\#65](https://github.com/Nitrokey/nitrokey-app/issues/65) - Warning displayed when unlocking an encrypted NTFS partition [\#58](https://github.com/Nitrokey/nitrokey-app/issues/58) - NK Storage: Erasing HOTP slot results in LED staying red on Nitrokey [\#56](https://github.com/Nitrokey/nitrokey-app/issues/56) - 'Passwords' submenu should not be shown when no passwords are available [\#53](https://github.com/Nitrokey/nitrokey-app/issues/53) - NK Storage: stick is reconnecting while wiping out SD card [\#48](https://github.com/Nitrokey/nitrokey-app/issues/48) - NK Storage: Display menu entry "lock device" only when device is unlocked [\#46](https://github.com/Nitrokey/nitrokey-app/issues/46) - NK Storage: Combine menu entries Generate Keys and Initialize Storage WIth Random Data [\#45](https://github.com/Nitrokey/nitrokey-app/issues/45) - Implement better detection of unpartitioned encrypted volume [\#42](https://github.com/Nitrokey/nitrokey-app/issues/42) - Check new translations [\#41](https://github.com/Nitrokey/nitrokey-app/issues/41) - Decouple counter and seed edit controls in TOTP/HOTP configuration form [\#31](https://github.com/Nitrokey/nitrokey-app/issues/31) - Refocus App on OS X [\#23](https://github.com/Nitrokey/nitrokey-app/issues/23) - RPM Package conflicts with system packages [\#18](https://github.com/Nitrokey/nitrokey-app/issues/18) - Specify min/max pin length in UI [\#15](https://github.com/Nitrokey/nitrokey-app/issues/15) - Admin PIN with more than 20 chars [\#12](https://github.com/Nitrokey/nitrokey-app/issues/12) - Storage: verify Update PIN when "enable firmware update" is selected [\#2](https://github.com/Nitrokey/nitrokey-app/issues/2) **Merged pull requests:** - Translations pack [\#104](https://github.com/Nitrokey/nitrokey-app/pull/104) ([szszszsz](https://github.com/szszszsz)) - Allow firmware password to have at most CS20\_MAX\_UPDATE\_PASSWORD\_LEN [\#102](https://github.com/Nitrokey/nitrokey-app/pull/102) ([szszszsz](https://github.com/szszszsz)) - Correct firmware password limit for update command [\#101](https://github.com/Nitrokey/nitrokey-app/pull/101) ([szszszsz](https://github.com/szszszsz)) - Issue 97 firmware password feedback no debug [\#99](https://github.com/Nitrokey/nitrokey-app/pull/99) ([szszszsz](https://github.com/szszszsz)) - Take status from device after AES keys initialization [\#98](https://github.com/Nitrokey/nitrokey-app/pull/98) ([szszszsz](https://github.com/szszszsz)) - Issue 78 only three passwords displayed [\#93](https://github.com/Nitrokey/nitrokey-app/pull/93) ([szszszsz](https://github.com/szszszsz)) - Issue 45 NK Storage: Combine menu entries Generate Keys and Initialize Storage WIth Random Data [\#91](https://github.com/Nitrokey/nitrokey-app/pull/91) ([szszszsz](https://github.com/szszszsz)) - Issue 82 Only first TOTP is valid when OTP is protected by user PIN [\#88](https://github.com/Nitrokey/nitrokey-app/pull/88) ([szszszsz](https://github.com/szszszsz)) - Revert "Issue 48 disable reconnecting messages while wiping" [\#83](https://github.com/Nitrokey/nitrokey-app/pull/83) ([szszszsz](https://github.com/szszszsz)) - Handle Factory Reset CLI command [\#81](https://github.com/Nitrokey/nitrokey-app/pull/81) ([szszszsz](https://github.com/szszszsz)) - Extend CLI with stick update mode [\#79](https://github.com/Nitrokey/nitrokey-app/pull/79) ([szszszsz](https://github.com/szszszsz)) - Issue 48 disable reconnecting messages while wiping [\#70](https://github.com/Nitrokey/nitrokey-app/pull/70) ([szszszsz](https://github.com/szszszsz)) - Issue 38 no feedback after changing password [\#67](https://github.com/Nitrokey/nitrokey-app/pull/67) ([szszszsz](https://github.com/szszszsz)) - Issue 60 handle both firmwares for hotp [\#64](https://github.com/Nitrokey/nitrokey-app/pull/64) ([szszszsz](https://github.com/szszszsz)) - Correcting solution for issue \#45 [\#63](https://github.com/Nitrokey/nitrokey-app/pull/63) ([szszszsz](https://github.com/szszszsz)) - Issue 31 decouple counter [\#61](https://github.com/Nitrokey/nitrokey-app/pull/61) ([szszszsz](https://github.com/szszszsz)) - Coding style for only modified files [\#59](https://github.com/Nitrokey/nitrokey-app/pull/59) ([szszszsz](https://github.com/szszszsz)) - Do not show empty passwords submenu [\#55](https://github.com/Nitrokey/nitrokey-app/pull/55) ([szszszsz](https://github.com/szszszsz)) - Reformatting code with clang-format [\#52](https://github.com/Nitrokey/nitrokey-app/pull/52) ([szszszsz](https://github.com/szszszsz)) - Revert "Add console in CONFIG += qt console" [\#51](https://github.com/Nitrokey/nitrokey-app/pull/51) ([szszszsz](https://github.com/szszszsz)) - Hiding "Lock device" from menu when no unlocked disks are available [\#50](https://github.com/Nitrokey/nitrokey-app/pull/50) ([szszszsz](https://github.com/szszszsz)) - Combine generating AES keys and sd card initialization [\#49](https://github.com/Nitrokey/nitrokey-app/pull/49) ([szszszsz](https://github.com/szszszsz)) - Workaround for issue 43 [\#47](https://github.com/Nitrokey/nitrokey-app/pull/47) ([szszszsz](https://github.com/szszszsz)) ## [v0.3.2](https://github.com/Nitrokey/nitrokey-app/tree/v0.3.2) (2016-04-11) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.2...v0.3.2) **Fixed bugs:** - Not working HOTP with Nitrokey Pro - "BUG: nitrokey HOTP BROKEN" [\#27](https://github.com/Nitrokey/nitrokey-app/issues/27) **Closed issues:** - Hidden volume is volatile [\#28](https://github.com/Nitrokey/nitrokey-app/issues/28) - Please push tag v0.2 [\#8](https://github.com/Nitrokey/nitrokey-app/issues/8) - provide writeToHOTPSlot as shared library [\#5](https://github.com/Nitrokey/nitrokey-app/issues/5) - Conditionally compile libappindicator support. [\#3](https://github.com/Nitrokey/nitrokey-app/issues/3) **Merged pull requests:** - Fix for issue 28 [\#34](https://github.com/Nitrokey/nitrokey-app/pull/34) ([szszszsz](https://github.com/szszszsz)) - Fixing HOTP bug \#27 [\#32](https://github.com/Nitrokey/nitrokey-app/pull/32) ([szszszsz](https://github.com/szszszsz)) - fix typo in icon filename [\#13](https://github.com/Nitrokey/nitrokey-app/pull/13) ([samjuvonen](https://github.com/samjuvonen)) ## [v0.2](https://github.com/Nitrokey/nitrokey-app/tree/v0.2) (2015-09-08) [Full Changelog](https://github.com/Nitrokey/nitrokey-app/compare/v0.1...v0.2) **Merged pull requests:** - Fixed typo in target.path, added note to README regarding non-KDE deskto... [\#1](https://github.com/Nitrokey/nitrokey-app/pull/1) ([dfj](https://github.com/dfj)) ## [v0.1](https://github.com/Nitrokey/nitrokey-app/tree/v0.1) (2014-12-02) \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*nitrokey-app-1.3.2/CMake/Modules/FindGLIB2.cmake0000644000175000017500000001327012774475055020516 0ustar janjan00000000000000# - Try to find GLib2 # Once done this will define # # GLIB2_FOUND - system has GLib2 # GLIB2_INCLUDE_DIRS - the GLib2 include directory # GLIB2_LIBRARIES - Link these to use GLib2 # # HAVE_GLIB_GREGEX_H glib has gregex.h header and # supports g_regex_match_simple # # Copyright (c) 2006 Andreas Schneider # Copyright (c) 2006 Philippe Bernery # Copyright (c) 2007 Daniel Gollub # Copyright (c) 2007 Alban Browaeys # Copyright (c) 2008 Michael Bell # Copyright (c) 2008 Bjoern Ricks # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # IF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) # in cache already SET(GLIB2_FOUND TRUE) ELSE (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS ) INCLUDE(FindPkgConfig) ## Glib IF ( GLIB2_FIND_REQUIRED ) SET( _pkgconfig_REQUIRED "REQUIRED" ) ELSE ( GLIB2_FIND_REQUIRED ) SET( _pkgconfig_REQUIRED "" ) ENDIF ( GLIB2_FIND_REQUIRED ) IF ( GLIB2_MIN_VERSION ) PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0>=${GLIB2_MIN_VERSION} ) ELSE ( GLIB2_MIN_VERSION ) PKG_SEARCH_MODULE( GLIB2 ${_pkgconfig_REQUIRED} glib-2.0 ) ENDIF ( GLIB2_MIN_VERSION ) IF ( PKG_CONFIG_FOUND ) IF ( GLIB2_FOUND ) SET ( GLIB2_CORE_FOUND TRUE ) ELSE ( GLIB2_FOUND ) SET ( GLIB2_CORE_FOUND FALSE ) ENDIF ( GLIB2_FOUND ) ENDIF ( PKG_CONFIG_FOUND ) # Look for glib2 include dir and libraries w/o pkgconfig IF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) FIND_PATH( _glibconfig_include_DIR NAMES glibconfig.h PATHS /opt/gnome/lib64 /opt/gnome/lib /opt/lib/ /opt/local/lib /sw/lib/ /usr/lib64 /usr/lib /usr/local/include ${CMAKE_LIBRARY_PATH} PATH_SUFFIXES glib-2.0/include ) FIND_PATH( _glib2_include_DIR NAMES glib.h PATHS /opt/gnome/include /opt/local/include /sw/include /usr/include /usr/local/include PATH_SUFFIXES glib-2.0 ) #MESSAGE(STATUS "Glib headers: ${_glib2_include_DIR}") FIND_LIBRARY( _glib2_link_DIR NAMES glib-2.0 glib PATHS /opt/gnome/lib /opt/local/lib /sw/lib /usr/lib /usr/local/lib ) IF ( _glib2_include_DIR AND _glib2_link_DIR ) SET ( _glib2_FOUND TRUE ) ENDIF ( _glib2_include_DIR AND _glib2_link_DIR ) IF ( _glib2_FOUND ) SET ( GLIB2_INCLUDE_DIRS ${_glib2_include_DIR} ${_glibconfig_include_DIR} ) SET ( GLIB2_LIBRARIES ${_glib2_link_DIR} ) SET ( GLIB2_CORE_FOUND TRUE ) ELSE ( _glib2_FOUND ) SET ( GLIB2_CORE_FOUND FALSE ) ENDIF ( _glib2_FOUND ) # Handle dependencies # libintl IF ( NOT LIBINTL_FOUND ) FIND_PATH(LIBINTL_INCLUDE_DIR NAMES libintl.h PATHS /opt/gnome/include /opt/local/include /sw/include /usr/include /usr/local/include ) FIND_LIBRARY(LIBINTL_LIBRARY NAMES intl PATHS /opt/gnome/lib /opt/local/lib /sw/lib /usr/local/lib /usr/lib ) IF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) SET (LIBINTL_FOUND TRUE) ENDIF (LIBINTL_LIBRARY AND LIBINTL_INCLUDE_DIR) ENDIF ( NOT LIBINTL_FOUND ) # libiconv IF ( NOT LIBICONV_FOUND ) FIND_PATH(LIBICONV_INCLUDE_DIR NAMES iconv.h PATHS /opt/gnome/include /opt/local/include /opt/local/include /sw/include /sw/include /usr/local/include /usr/include PATH_SUFFIXES glib-2.0 ) FIND_LIBRARY(LIBICONV_LIBRARY NAMES iconv PATHS /opt/gnome/lib /opt/local/lib /sw/lib /usr/lib /usr/local/lib ) IF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) SET (LIBICONV_FOUND TRUE) ENDIF (LIBICONV_LIBRARY AND LIBICONV_INCLUDE_DIR) ENDIF ( NOT LIBICONV_FOUND ) IF (LIBINTL_FOUND) SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBINTL_LIBRARY}) SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBINTL_INCLUDE_DIR}) ENDIF (LIBINTL_FOUND) IF (LIBICONV_FOUND) SET (GLIB2_LIBRARIES ${GLIB2_LIBRARIES} ${LIBICONV_LIBRARY}) SET (GLIB2_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS} ${LIBICONV_INCLUDE_DIR}) ENDIF (LIBICONV_FOUND) ENDIF ( NOT GLIB2_FOUND AND NOT PKG_CONFIG_FOUND ) ## IF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) SET (GLIB2_FOUND TRUE) ENDIF (GLIB2_CORE_FOUND AND GLIB2_INCLUDE_DIRS AND GLIB2_LIBRARIES) IF (GLIB2_FOUND) IF (NOT GLIB2_FIND_QUIETLY) MESSAGE (STATUS "Found GLib2: ${GLIB2_LIBRARIES} ${GLIB2_INCLUDE_DIRS}") ENDIF (NOT GLIB2_FIND_QUIETLY) ELSE (GLIB2_FOUND) IF (GLIB2_FIND_REQUIRED) MESSAGE (SEND_ERROR "Could not find GLib2") ENDIF (GLIB2_FIND_REQUIRED) ENDIF (GLIB2_FOUND) # show the GLIB2_INCLUDE_DIRS and GLIB2_LIBRARIES variables only in the advanced view MARK_AS_ADVANCED(GLIB2_INCLUDE_DIRS GLIB2_LIBRARIES) MARK_AS_ADVANCED(LIBICONV_INCLUDE_DIR LIBICONV_LIBRARY) MARK_AS_ADVANCED(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) ENDIF (GLIB2_LIBRARIES AND GLIB2_INCLUDE_DIRS) IF ( GLIB2_FOUND ) # Check if system has a newer version of glib # which supports g_regex_match_simple INCLUDE( CheckIncludeFiles ) SET( CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS} ) CHECK_INCLUDE_FILES ( glib/gregex.h HAVE_GLIB_GREGEX_H ) # Reset CMAKE_REQUIRED_INCLUDES SET( CMAKE_REQUIRED_INCLUDES "" ) ENDIF( GLIB2_FOUND ) nitrokey-app-1.3.2/CMake/Modules/FindLibnotify.cmake0000644000175000017500000000570212774475055021657 0ustar janjan00000000000000# - Try to find Libnotify # Once done this will define # # LIBNOTIFY_FOUND - system has Libnotify # LIBNOTIFY_INCLUDE_DIR - the Libnotify include directory # LIBNOTIFY_LIBRARIES - Link these to use Libnotify # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # # Copyright (c) 2010, Ni Hui # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. if(LIBNOTIFY_INCLUDE_DIR AND LIBNOTIFY_LIBRARIES) # in cache already set(LIBNOTIFY_FOUND_QUIETLY TRUE) endif(LIBNOTIFY_INCLUDE_DIR AND LIBNOTIFY_LIBRARIES) if(NOT WIN32) find_package(PkgConfig) pkg_check_modules(PKG_LIBNOTIFY libnotify) if(PKG_LIBNOTIFY_FOUND) set(LIBNOTIFY_FOUND) endif(PKG_LIBNOTIFY_FOUND) endif(NOT WIN32) find_path(LIBNOTIFY_INCLUDE_DIR NAMES notify.h PATHS HINTS ${PKG_LIBNOTIFY_INCLUDE_DIRS} PATH_SUFFIXES libnotify ) find_library(LIBNOTIFY_LIBRARIES NAMES notify PATHS HINTS ${PKG_LIBNOTIFY_LIBRARY_DIRS} ) if(LIBNOTIFY_INCLUDE_DIR AND LIBNOTIFY_LIBRARIES) set(LIBNOTIFY_FOUND TRUE) else(LIBNOTIFY_INCLUDE_DIR AND LIBNOTIFY_LIBRARIES) set(LIBNOTIFY_FOUND FALSE) endif(LIBNOTIFY_INCLUDE_DIR AND LIBNOTIFY_LIBRARIES) if(LIBNOTIFY_FOUND) include(CheckCSourceCompiles) find_package(GLIB2 REQUIRED) find_package(GTK2 REQUIRED) # check whether we are using libnotify 0.4 set(CMAKE_REQUIRED_INCLUDES ${LIBNOTIFY_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR} ${GTK2_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${LIBNOTIFY_LIBRARIES} ${GLIB2_LIBRARIES} ${GTK2_LIBRARIES}) set(LIBNOTIFY_INCLUDE_DIR ${LIBNOTIFY_INCLUDE_DIR} ${GLIB2_INCLUDE_DIR} ${GTK2_INCLUDE_DIRS}) set(LIBNOTIFY_LIBRARIES ${LIBNOTIFY_LIBRARIES} ${GLIB2_LIBRARIES} ${GTK2_LIBRARIES}) check_c_source_compiles(" #include int main() { notify_notification_new(NULL,NULL,NULL,NULL); return 0; } " HAVE_LIBNOTIFY_0_4) check_c_source_compiles(" #include int main() { notify_notification_new(NULL,NULL,NULL); return 0; } " HAVE_LIBNOTIFY_0_7) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) if(HAVE_LIBNOTIFY_0_4) message(STATUS "Found Libnotify: ${LIBNOTIFY_LIBRARIES}, (>= 0.4)") endif(HAVE_LIBNOTIFY_0_4) if(HAVE_LIBNOTIFY_0_7) message(STATUS "Found Libnotify: ${LIBNOTIFY_LIBRARIES}, (>= 0.7)") endif(HAVE_LIBNOTIFY_0_7) endif(LIBNOTIFY_FOUND) set(LIBNOTIFY_INCLUDE_DIR ${LIBNOTIFY_INCLUDE_DIR} CACHE INTERNAL "The Libnotify include path") set(LIBNOTIFY_LIBRARIES ${LIBNOTIFY_LIBRARIES} CACHE INTERNAL "The Libnotify library") set(HAVE_LIBNOTIFY_0_4 ${HAVE_LIBNOTIFY_0_4} CACHE INTERNAL "Whether the version of Libnotify is >= 0.4") set(HAVE_LIBNOTIFY_0_7 ${HAVE_LIBNOTIFY_0_7} CACHE INTERNAL "Whether the version of Libnotify is >= 0.7") mark_as_advanced(LIBNOTIFY_INCLUDE_DIR LIBNOTIFY_LIBRARIES) nitrokey-app-1.3.2/CMakeLists.txt0000644000175000017500000002526613404176655016267 0ustar janjan00000000000000CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0 FATAL_ERROR) cmake_policy(SET CMP0043 OLD) # cmake --help-policy CMP0043 PROJECT(NitrokeyApp LANGUAGES CXX) SET(PROJECT_VERSION "1.3.2") set(LIBNK_MIN_VERSION 3.3) include(GNUInstallDirs) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) OPTION(ADD_GIT_INFO "Add information about source code version from Git repository" TRUE) set(BUILD_SHARED_LIBS ON CACHE BOOL "Build all libraries as shared") IF (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo) ENDIF() MESSAGE("${PROJECT_NAME}: Build type: ${CMAKE_BUILD_TYPE}") IF(UNIX) OPTION(ADD_ASAN "Use ASAN to show memory issues" FALSE) OPTION(ADD_TSAN "Use TSAN to show thread issues" FALSE) IF(ADD_ASAN) SET(EXTRA_LIBS ${EXTRA_LIBS} asan ) ADD_DEFINITIONS(-fsanitize=address -fno-omit-frame-pointer) ENDIF() IF(ADD_TSAN) SET(EXTRA_LIBS ${EXTRA_LIBS} tsan ) ADD_DEFINITIONS(-fsanitize=thread -fno-omit-frame-pointer -g) #use with clang ENDIF() ENDIF() #add CMake build info ADD_DEFINITIONS(-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}") ADD_DEFINITIONS(-DCMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER_ID}, ${CMAKE_CXX_COMPILER}, built on: ${CMAKE_SYSTEM} ") ADD_DEFINITIONS(-DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS}") # QT configuration FIND_PACKAGE(Qt5Core REQUIRED) FIND_PACKAGE(Qt5Gui REQUIRED) FIND_PACKAGE(Qt5Widgets REQUIRED) FIND_PACKAGE(Qt5Svg REQUIRED) FIND_PACKAGE(Qt5Concurrent REQUIRED) # add git version info IF(ADD_GIT_INFO) execute_process( COMMAND git describe --always --abbrev=4 HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions(-DGIT_VERSION="${GIT_VERSION}") ELSE() add_definitions(-DGIT_VERSION="") ENDIF() add_definitions(-DGUI_VERSION="${PROJECT_VERSION}") # for out of source build set(CMAKE_INCLUDE_CURRENT_DIR ON) # Directory structure SET(ROOTDIR ${CMAKE_CURRENT_SOURCE_DIR}) SET(UIDIR ${ROOTDIR}/ui) SET(SRCDIR ${ROOTDIR}/src) SET(SRCUIDIR ${SRCDIR}/ui) SET(UTILSDIR ${SRCDIR}/utils) # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) # Resource files SET(qrc_files resources.qrc ) # create translation files to include into resource file # remember to add new translations files there IF (UNIX AND NOT APPLE) ADD_SUBDIRECTORY(i18n) find_package(Qt5LinguistTools) file(GLOB i18n_files "i18n/*.ts") qt5_create_translation(i18n_resources ${SRCUIDIR} ${i18n_files}) qt5_add_translation(TRANSLATION_QM ${i18n_files}) ENDIF() IF (WIN32) ELSEIF(APPLE) ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "BSD") SET( platform_specific_sources ${SRCDIR}/systemutils.cpp) ENDIF () # WIN32 INCLUDE_DIRECTORIES( ${UIDIR} ${SRCDIR} ${UTILSDIR} ${SRCUIDIR} ) # c/cpp sources SET(nitrokey_app_sources ${SRCUIDIR}/aboutdialog.cpp ${SRCUIDIR}/nitrokey-applet.cpp ${SRCDIR}/hotpslot.cpp ${SRCDIR}/main.cpp ${SRCDIR}/core/SecureString.cpp ${SRCUIDIR}/mainwindow.cpp ${SRCUIDIR}/pindialog.cpp # ${SRCUIDIR}/securitydialog.cpp ${SRCUIDIR}/stick20changepassworddialog.cpp ${SRCUIDIR}/stick20debugdialog.cpp ${SRCUIDIR}/stick20hiddenvolumedialog.cpp ${SRCUIDIR}/stick20lockfirmwaredialog.cpp ${SRCUIDIR}/stick20responsedialog.cpp ${SRCUIDIR}/stick20updatedialog.cpp ${platform_specific_sources} src/libada.cpp src/libada.h src/utils/bool_values.h src/GUI/Tray.cpp src/GUI/Tray.h src/GUI/Clipboard.cpp src/GUI/Clipboard.h src/GUI/Authentication.cpp src/GUI/Authentication.h src/core/ScopedGuard.h src/version.h src/GUI/StorageActions.cpp src/GUI/StorageActions.h src/ui/licensedialog.cpp src/GUI/ManageWindow.cpp src/GUI/graphicstools.cpp # src/GUI/PasswordSafe.cpp src/GUI/PasswordSafe.h src/core/ThreadWorker.cpp src/core/ThreadWorker.h) #INSTALL # Freedesktop files IF(NOT WIN32) install(DIRECTORY ${CMAKE_SOURCE_DIR}/data/icons/ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons ) install(FILES ${CMAKE_SOURCE_DIR}/data/nitrokey-app.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications ) install(FILES ${CMAKE_SOURCE_DIR}/data/com.nitrokey.nitrokey-app.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/ ) install(FILES ${CMAKE_SOURCE_DIR}/data/icons/hicolor/128x128/apps/nitrokey-app.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps ) find_package(PkgConfig) # Install Nitrokey udev rules # Removed - should be provided by libnitrokey # Install autocompletion scripts set(PKG_GET_BASH_COMPLETION ${PKG_CONFIG_EXECUTABLE} --variable=completionsdir bash-completion) execute_process(COMMAND ${PKG_GET_BASH_COMPLETION} RESULT_VARIABLE ERR OUTPUT_VARIABLE BASH_COMPLETION_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) IF(${ERR}) set(BASH_COMPLETION_DIR "etc/bash_completion.d") ENDIF() string(REGEX REPLACE "^/" "" BASH_COMPLETION_DIR "${BASH_COMPLETION_DIR}") string(REGEX REPLACE "^usr/" "" BASH_COMPLETION_DIR "${BASH_COMPLETION_DIR}") # usual prefix is usr/local message(STATUS "Setting bash-completion dir to ${BASH_COMPLETION_DIR}") install(FILES ${CMAKE_SOURCE_DIR}/data/bash-autocomplete/nitrokey-app DESTINATION ${BASH_COMPLETION_DIR} ) ENDIF () # NOT WIN32 ADD_EXECUTABLE(nitrokey-app ${GUI_TYPE} ${nitrokey_app_sources} ${i18n_resources} ${qrc_files} ) OPTION(ERROR_ON_WARNING "Stop compilation on warning found (not supported for MSVC)" OFF) if (NOT MSVC) set(COMPILE_FLAGS "-Wall -Wno-unused-function -Wcast-qual -Woverloaded-virtual") # IF(NOT APPLE) if (ERROR_ON_WARNING) set(COMPILE_FLAGS "${COMPILE_FLAGS} -Werror") endif() SET_TARGET_PROPERTIES(nitrokey-app PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS} ) # endif() endif() INSTALL(TARGETS nitrokey-app DESTINATION ${CMAKE_INSTALL_BINDIR}) TARGET_LINK_LIBRARIES(nitrokey-app ${EXTRA_LIBS} # ${platform_specific_libs} Qt5::Widgets Qt5::Core Qt5::Gui Qt5::Svg Qt5::Concurrent ) # first try to find libnitrokey via pkg-config find_package(PkgConfig) pkg_search_module(LIBNITROKEY ${_pkgconfig_REQUIRED} libnitrokey-1 >= ${LIBNK_MIN_VERSION}) MESSAGE(STATUS "Required libnitrokey version: ${LIBNK_MIN_VERSION}") if(LIBNITROKEY_FOUND) MESSAGE(STATUS "Found system libnitrokey (Cflags: '${LIBNITROKEY_CFLAGS}' Libs: '${LIBNITROKEY_LDFLAGS}')") if (BUILD_SHARED_LIBS) target_compile_options(nitrokey-app PRIVATE ${LIBNITROKEY_CFLAGS}) target_link_libraries(nitrokey-app ${LIBNITROKEY_LDFLAGS}) else() target_compile_options(nitrokey-app PRIVATE ${LIBNITROKEY_STATIC_CFLAGS}) target_link_libraries(nitrokey-app ${LIBNITROKEY_STATIC_LDFLAGS}) endif() else() MESSAGE("Using bundled libnitrokey") add_subdirectory (libnitrokey) include_directories(libnitrokey) target_link_libraries(nitrokey-app nitrokey) endif() # ... same for cppcodec pkg_search_module(CPPCODEC cppcodec-1) if(CPPCODEC_FOUND) MESSAGE(STATUS "Found system cppcodec (Cflags: '${CPPCODEC_CFLAGS}' Libs: '${CPPCODEC_LDFLAGS}')") if (BUILD_SHARED_LIBS) target_compile_options(nitrokey-app PRIVATE ${CPPCODEC_CFLAGS}) target_link_libraries(nitrokey-app ${CPPCODEC_LDFLAGS}) else() target_compile_options(nitrokey-app PRIVATE ${CPPCODEC_STATIC_CFLAGS}) target_link_libraries(nitrokey-app ${CPPCODEC_STATIC_LDFLAGS}) endif() else() MESSAGE("Using bundled cppcodec") include_directories(3rdparty/cppcodec) endif() # Packaging SET(CPACK_GENERATOR "DEB;RPM") SET(CPACK_PACKAGE_NAME "nitrokey-app" ) SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION} ) SET(CPACK_PACKAGE_DEPENDS "" ) # Deb #execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE) execute_process(COMMAND uname -m OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE) SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Use and manage your Nitrokey") # We need to alter the architecture names as per distro rules IF("${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" MATCHES "i[3-6]86") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386) ENDIF("${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" MATCHES "i[3-6]86") IF("${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" MATCHES "x86_64") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE amd64) ENDIF("${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" MATCHES "x86_64") SET(PACKAGE_MAINTAINER "Szczepan Zalega " ) SET(CPACK_DEBIAN_PACKAGE_MAINTAINER ${PACKAGE_MAINTAINER} ) SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") SET(CPACK_DEBIAN_PACKAGE_SECTION "utils") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5widgets5, libqt5gui5, libqt5core5a, libqt5svg5, libhidapi-libusb0") SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/debian/postinst") # Rpm #execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE CPACK_RPM_PACKAGE_ARCHITECTURE) SET(CPACK_RPM_PACKAGE_DESCRIPTION "Use and manage your Nitrokey") SET(CPACK_RPM_PACKAGE_LICENSE "GPLv3") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSES/GPLv3") SET(CPACK_RPM_PACKAGE_SUMMARY "Use and manage your Nitrokey") SET(CPACK_RPM_PACKAGE_VENDOR "Nitrokey") SET(CPACK_RPM_PACKAGE_MAINTAINER ${PACKAGE_MAINTAINER} ) SET(CPACK_RPM_PACKAGE_PRIORITY "optional") SET(CPACK_RPM_PACKAGE_SECTION "utils") # Prevent RPM directory collisions by excluding those already provided by # package dependencies. AFAIK this can't be automated. LIST(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/etc/bash_completion.d" "/etc/udev" "/etc/udev/rules.d" "/usr/lib/udev" "/usr/lib/udev/rules.d" "/usr/share/icons" "/usr/share/icons/hicolor" "/usr/share/icons/hicolor/16x16" "/usr/share/icons/hicolor/16x16/apps" "/usr/share/icons/hicolor/22x22" "/usr/share/icons/hicolor/22x22/apps" "/usr/share/icons/hicolor/24x24" "/usr/share/icons/hicolor/24x24/apps" "/usr/share/icons/hicolor/48x48" "/usr/share/icons/hicolor/48x48/apps" "/usr/share/icons/hicolor/32x32" "/usr/share/icons/hicolor/32x32/apps" "/usr/share/icons/hicolor/128x128" "/usr/share/icons/hicolor/128x128/apps" "/usr/share/icons/hicolor/scalable" "/usr/share/icons/hicolor/scalable/apps" "/usr/share/icons/ubuntu-mono-dark" "/usr/share/icons/ubuntu-mono-dark/apps" "/usr/share/icons/ubuntu-mono-dark/apps/22" "/usr/share/icons/ubuntu-mono-dark/apps/24" "/usr/share/icons/ubuntu-mono-dark/apps/48" "/usr/share/icons/ubuntu-mono-dark/apps/16" "/usr/share/icons/ubuntu-mono-light" "/usr/share/icons/ubuntu-mono-light/apps" "/usr/share/icons/ubuntu-mono-light/apps/22" "/usr/share/icons/ubuntu-mono-light/apps/24" "/usr/share/icons/ubuntu-mono-light/apps/48" "/usr/share/icons/ubuntu-mono-light/apps/16" "/usr/share/applications" "/usr/share/pixmaps" ) INCLUDE(CPack) nitrokey-app-1.3.2/CONTRIBUTING.md0000644000175000017500000000775313221173116015743 0ustar janjan00000000000000# How to contribute ## Ideas If you would like to contribute and do not have the idea, you can check our [Ideas](https://github.com/Nitrokey/wiki/wiki/Ideas) wiki page. ## Reporting issues ### What issue description should contain To increase issue's report speed processing please add some information about your environment. At least: - Operating system (name, version, 32 or 64 bits?) - Stick firmware version (could be checked via `About` window) - Application version on which the issue occurs - Any available output or log (could be gathered from `Debug` window, found in tray menu when run with `-d` switch as in `./nitrokey-app -d`) attached as a *text* file In future this might be replaced by submitting one report file produced by application. A detailed proposition for data being gathered is under issue #74 [link](https://github.com/Nitrokey/nitrokey-app/issues/74). ## Pull request / commits content ### General guidelines Whether you have a solution to one of the issues or a quick small fix-up for a typo you are always welcomed to submit a Pull Request (PR). Before submitting please check following guidelines: - Make as small consisting changes as possible within one PR/commit (eg. do not mix translations and functional changes). Mixed PRs/commits might conflict with each other and thus delay or make impossible to merge them. Unclear changes might also be not merged. Please do code reformat with separate commit (last) if not done before each commit. - Before commiting please run `./coding-styles.sh` (requires `clang-format` installed) to reformat all modified files. - Please do not squash changes to one commit. If one of the changes would need to be reverted, it would not be possible without reverting whole commit or editing code by hand. - Do not mix functional changes with not own code reformat. This is a straight road for merge conflicts and problems with reverting commits around, based on this one. - Please sign-off your commit using `-s` switch like in `git commit -s` to confirm that you are the author of the patch or have the right to pass it on as open source (details: http://developercertificate.org/). This rule makes sense only when you are using your real name. You can also sign it with your GPG key if you would like to. - Travis build system will check is code formatted and builds properly. Later on it will check also all warnings emitted during compilation. - Make sure your code is synced with the `master` branch. We could ask you to rebase it in other case. - Prefer extending current solutions over introducing foreign ones where possible. - Please comment solution code in pull request and the impact of planned change on issue page. - Add test scenario to PR under which the solution fixes the issue (with environment description). Please be aware not all PRs will be merged to codebase including yours, however your effort will not go in vain. The PR could shed light on some overlooked problem or be used as an inspiration for rewriting given code later. You can always develop it further in your fork and try again. Don't get discouraged! ### How to make a Pull Request To make a PR please: 1. Make a fork of the repository 2. Create new branch based on master 3. Commit your code there and push to your forked repository 4. On main page of your forked repository a button creating PR will be shown. ### Quickstart with git flow Tutorials for the beginners: - https://guides.github.com/introduction/flow/index.html - https://www.atlassian.com/git/tutorials/ Best practices: - https://sethrobertson.github.io/GitBestPractices/ - http://nvie.com/posts/a-successful-git-branching-model/ ### Travis build checks Currently each PR is checked for proper build. Additionally it might be checked does PR: - Compile without warnings (on at least one recent compiler version) (future) - Pass llvm-format without changes (use a style config file if necessary) (future) - Don't break ability to compile (at least on amd64, QT5) We (would) use Travis service to enforce these and to always have binary builds. nitrokey-app-1.3.2/Info.plist0000644000175000017500000000141413275777051015467 0ustar janjan00000000000000 LSUIElement 0 NSPrincipalClass NSApplication CFBundleIconFile CS_icon.icns CFBundlePackageType APPL CFBundleGetInfoString Nitrokey Device Manager CFBundleSignature ???? CFBundleExecutable nitrokey-app CFBundleIdentifier com.nitrokey.nitrokey-app NOTE Copyright (c) 2012-2018 Nitrokey UG nitrokey-app-1.3.2/LICENSES/GPLv30000644000175000017500000010451313275777051015546 0ustar janjan00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . nitrokey-app-1.3.2/LICENSES/LGPLv30000644000175000017500000001674413275777051015672 0ustar janjan00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. nitrokey-app-1.3.2/LICENSES/MIT0000644000175000017500000000210513275777051015276 0ustar janjan00000000000000The MIT License (MIT) (See individual files for copyright holders.) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. nitrokey-app-1.3.2/Makefile.top0000644000175000017500000000476512774475055015776 0ustar janjan00000000000000mkfile_path := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) ROOT_DIR := ${mkfile_path} SCRIPTS_DIR := ${ROOT_DIR}/scripts BUILD_DIR ?= ${ROOT_DIR}/build BUILD_LINUX ?= ${BUILD_DIR}/linux BUILD_WIN ?= ${BUILD_DIR}/win INSTALL_DIR ?= ${ROOT_DIR}/install RELEASE_DIR ?= ${ROOT_DIR}/release WIN_RELEASE_DIR ?= ${RELEASE_DIR}/windows LINUX_RELEASE_DIR ?= ${RELEASE_DIR}/linux DEPS=cmake qtdeclarative5-dev libusb-1.0-0-dev EXTRA_DEPS: rpm #.PHONY: release prepare build clean windows windows-installer .PHONY: deps prepare linux-clean windows-clean clean prepare: mkdir -p ${BUILD_LINUX} mkdir -p ${BUILD_WIN} mkdir -p ${INSTALL_DIR} mkdir -p ${RELEASE_DIR} $(BUILD_LINUX): mkdir -p ${BUILD_LINUX} $(BUILD_WIN): mkdir -p ${BUILD_WIN} $(INSTALL_DIR): mkdir -p ${INSTALL_DIR} $(LINUX_RELEASE_DIR): mkdir -p ${LINUX_RELEASE_DIR} $(WIN_RELEASE_DIR): mkdir -p ${WIN_RELEASE_DIR} deps: sudo apt-get install ${DEPS} ### Linux $(BUILD_LINUX)/nitrokey-app: | ${BUILD_LINUX} cd ${BUILD_LINUX} && \ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} ${ROOT_DIR} && \ make build: $(BUILD_LINUX)/nitrokey-app install: build | ${INSTALL_DIR} cd ${BUILD_LINUX} && make install ### Windows $(BUILD_WIN)/release/nitrokey-app.exe: | ${BUILD_WIN} export PATH=${MXE_ROOT}/usr/bin/:${PATH} && \ cd ${BUILD_WIN} && \ ${MXE_ROOT}/usr/i686-w64-mingw32.static/qt5/bin/qmake -spec ${MXE_ROOT}/usr/i686-w64-mingw32.static/qt5/mkspecs/win32-g++ -o Makefile ${ROOT_DIR}/nitrokey-app-qt5.pro && \ make windows: $(BUILD_WIN)/release/nitrokey-app.exe ### Releasing linux-release: build | $(LINUX_RELEASE_DIR) cd ${BUILD_LINUX} && \ make package && \ mv *.deb *.rpm ${LINUX_RELEASE_DIR} && cd ${LINUX_RELEASE_DIR} && \ find . -name *.deb -type f -printf '%f' | xargs -0 -n1 -I{} sh -c '${SCRIPTS_DIR}/fix-deb.sh {}' && \ find . -name *.deb -type f -printf "%f" | xargs -0 -n1 -I{} sh -c 'sha256sum -b {} > {}.sha256; md5sum -b {} > {}.md5' && \ find . -name *.rpm -type f -printf "%f" | xargs -0 -n1 -I{} sh -c 'sha256sum -b {} > {}.sha256; md5sum -b {} > {}.md5' windows-release: windows | $(WIN_RELEASE_DIR) cd ${ROOT_DIR}/nsis && \ cp ${BUILD_WIN}/release/nitrokey-app.exe . && \ makensis nitrokey-app.nsis && \ cp Nitrokey-App-Installer.exe ${BUILD_WIN}/release/ release-all: linux-release windows-release ### Cleaning linux-clean: cd ${BUILD_LINUX} && make clean windows-clean: cd ${BUILD_WIN} && make clean clean: linux-clean windows-clean purge: rm -rf ${BUILD_DIR} rm -rf ${RELEASE_DIR} nitrokey-app-1.3.2/OTP_full_specification.txt0000644000175000017500000001407512774475055020655 0ustar janjan00000000000000 Flash storage description OTP OTP parameter block The OTP parameter block save the configuration data of each slot. The size of each slot is 64 byte Slot Start End GLOBAL_CONFIG 0 2 free 3 63 HOTP_SLOT1 64 127 HOTP_SLOT2 128 191 HOTP_SLOT3 192 255 TOTP_SLOT1 256 319 TOTP_SLOT2 320 383 TOTP_SLOT3 384 447 TOTP_SLOT4 448 511 TOTP_SLOT5 512 575 TOTP_SLOT6 576 639 TOTP_SLOT7 640 703 TOTP_SLOT8 704 767 TOTP_SLOT9 768 831 TOTP_SLOT10 832 896 TOTP_SLOT11 896 939 TOTP_SLOT12 1088 1151 //Start of second OTP slot page TOTP_SLOT13 1152 1215 //The first slot has been left empty TOTP_SLOT14 1216 1280 //in case of future need TOTP_SLOT15 1280 1343 OTP configuration slot Slot size 64 byte Contain the parameter data - 50 data byte Start Description SLOT_TYPE_OFFSET 0 1 byte slot type TOTP, HOTP SLOT_NAME_OFFSET 1 15 byte slot name SECRET_OFFSET 16 20 byte secret key CONFIG_OFFSET 36 1 byte config byte TOKEN_ID_OFFSET 37 12 byte token ID OTP counter storage slot This field is used for storing the actual counter value. Because of the limitation of flash erase accesses (10,000 for a Stick 1.4 flash page (1024 byte), 100,000 for a Stick 2.0 flash page (512 byte)). it is necessary to reduce the erase access of the flash. This is done by using a greater area of the flash. The limitation of flash accesses is only in the change of the bits to 1 in a flash page. Only all bit in a hole flash page can set to 1 in a single process (this is the erase access). The setting to 0 of a bit in the flash page is independent to other bits. The implementation: The first 8 byte of the slot contains the base counter of stored value as an unsigned 64 bit value. The remaining page stored a token per flash byte for a used number. When all tokens in a slot are used, the base counter is raised and the tokens are reseted to 0xff Flash page layout Entry Position Counter base 0 - 7 8 byte, unsigned 64 bit Use flags 8 - 1023 1016 byte marked a used value (for Stick 1.4) Use flags 8 - 511 504 byte marked a used value (for Stick 2.0) Flash page byte order 0 1 2 3 4 End of flash page 01234567890123456789012345678901234567890123456789.... X VVVVVVVVFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.... . V = 64 bit counter base value F = token for a used value, 0xFF = unused, 0x00 = used The actual counter is the sum of the counter base value and the number of tokens with a 0 in the slot. Example: Flash page byte order 0 1 2 3 4 End of flash page 01234567890123456789012345678901234567890123456789.... X xHi 0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.... . xLo 0000001000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.... . V = 0x0100 = 256 Token 0-7 are marked as used = 8 tokens are marked Counter value = 256 + 8 = 264 Slot size 1024 byte Stick 1.4 Slot size 512 byte Stick 2.0 OTP time storage slot The time storage has the same limitation as the OTP counter storage. For reference read above. Store time command data: The data that is send from the Utility for the storing of the time has the following format: The first byte of the *report is the command type ( similar to all other command data). The second byte is used for the overriding of the time. If that byte is set to 1 it means that the user has requested an overriding of the time in firmware and provided correct Admin PIN to authorize that. If this has any other value the time shouldn't be overwritten. The next 64 bits represent the seconds since epoch (1 January 1970). That value is stored in a RAM variable which is used to calculate the TOTP token and is also used to calculate the value to be stored in the flash ( (Epoch value - 1388534400)/60 , the value 1388534400 is the number of seconds from 1 January 1970 to 1 January 2014 ). The time is only written in three cases: the second byte of the command data is 1, the old time (return by the function get_time_value) has a value smaller than the new time (in minutes) and if the old time is 0xFFFFFFFF (bellow is an explanation when this happens). Implementation: The time is stored as a 24 bit value representing the minutes that have passed since 1 January 2014 plus a 8 bit CRC code of the value (The polynomial used for the crc calculation is 100110001). On request for the reset of time (when the device and utility connect to each other and every time a new TOTP token is requested) the time is stored on a new position in the time slot that is 32 bit offset from the begging. If the slot is empty ( the first position has value 0xFFFFFFFF ) that is returned by the get_time_value() function. When there are no empty positions in the slot it is reset and the time is stored on the position with offset 0. To find the last position on which the time has been set we iterate trough all the possible positions and check if position has value of 0xFFFFFFFF if it has the previous position holds the last time. If the value is different then we continue the iteration. To find the next free position in which the time can be written we do the same as when looking for the last written time and when we find a position with the value 0xFFFFFFFF that is the next free position. OTP backup slot Backup of the OTP parameter block nitrokey-app-1.3.2/README.md0000644000175000017500000002436013314460010014755 0ustar janjan00000000000000Nitrokey App [![Build Status](https://travis-ci.org/Nitrokey/nitrokey-app.png?branch=master)](https://travis-ci.org/Nitrokey/nitrokey-app) [![Coverity Scan Build](https://scan.coverity.com/projects/4744/badge.svg)](https://scan.coverity.com/projects/4744) ============ Nitrokey App is a cross-platform (runs under Windows, Linux and Mac OS) application created to manage [Nitrokey devices](https://www.nitrokey.com/). Lately developed under Ubuntu 17.10/18.04 with Qt5.9. Underneath it uses [libnitrokey](https://github.com/Nitrokey/libnitrokey) to communicate with the supported devices. Both Nitrokey App and libnitrokey are available under GPLv3 license. ##### Supported devices Currently Nitrokey App supports: - Nitrokey Pro v0.7/v0.8, - Nitrokey Storage. For Nitrokey HSM please see [Nitrokey Encryption Tool](https://github.com/Nitrokey/nitrokey-encryption-tool). Nitrokey Start has its own tools in its [firmware repository](https://github.com/Nitrokey/nitrokey-start-firmware/tree/gnuk1.2-regnual-fix). ##### Compatibility The implementation is compatible to the Google Authenticator application which can be used for testing purposes. Test vectors from proper specifications also works: - HOTP: An HMAC-Based One-Time Password Algorithm - [RFC4226](https://tools.ietf.org/html/rfc4226), - TOTP: Time-Based One-Time Password Algorithm - [RFC6238](https://tools.ietf.org/html/rfc6238). Each libnitrokey's and supported devices' firmware release OTPs are tested automatically, according to the RFCs test vectors. ##### Builds Ready to use binaries are available at [releases page](https://github.com/Nitrokey/nitrokey-app/releases). More details could be found at [main download site](https://www.nitrokey.com/download). ##### Using under Linux Using the application under Linux requires configuration of device privileges in udev (due to USB communication). The configuration is installed automatically with the libnitrokey library (either with a package or after `make install`). Without it application cannot communicate unless run with root privileges. ## Known issues #### Tray icon under Gnome 3.26 Gnome 3.26 (and later) removed support for the tray dock and tray icon (Ubuntu 18.04 is not affected - it contains own plugin to support it). For more details please see: [NitrokeyApp#274](https://github.com/Nitrokey/nitrokey-app/issues/274). Nitrokey App v1.3 should solve this by introducing main window, which is shown right on application's start. #### Tray icon under Debian Jessie Under Debian Jessie application's tray icon might be unavailable. There were reports it can be fixed with updating Qt libraries to 5.4.2 version and up. The packages are available in experimental OS branch. For more details please refer to: [NitrokeyApp#86](https://github.com/Nitrokey/nitrokey-app/issues/86). Another way to workaround this is using an AppImage binary release, introduced in [Nitrokey App v1.3](https://github.com/Nitrokey/nitrokey-app/releases/tag/v1.3). ## Installation and downloads Ready to use packages and install instructions are available on main site in download section: https://www.nitrokey.com/download ## Compilation Ready to use Docker containers for building AppImage, Windows and Snapcraft binaries are available at [nitrokey-app.build](https://github.com/Nitrokey/nitrokey-app.build/tree/master/docker) project. There are set [automatic builds using Travis CI](https://travis-ci.org/Nitrokey/nitrokey-app) as well. Below are detailed instructions how to make a build manually. ### Compiling on Ubuntu Linux Prerequisites for building on Ubuntu 17.10: - `build-essential` - for building applications - `cmake` - for compiling libnitrokey - `qt5-default` - QT5 library - `qttools5-dev-tools` - QT5 library tools - generating translations - `libqt5svg5-dev` - QT5 library for rendering SVG - `libqt5concurrent5` - QT5 library for concurrent calls - `pkg-config` - system libraries detection - `libnitrokey` v3.3 - compiled only, if not already installed in the OS - `libusb-1.0-0-dev` - library to communicate with USB devices - `libhidapi-dev` - to communicate using HID layer Whole command for Ubuntu: ``` sudo apt-get install libusb-1.0.0-dev cmake qt5-default qttools5-dev-tools pkg-config libhidapi-dev build-essential libqt5svg5-dev libqt5concurrent5 ``` #### Getting the Nitrokey Sources Clone the Nitrokey-App repository using `git` and `--recursive` switch: ``` git clone https://github.com/Nitrokey/nitrokey-app.git --recursive ``` #### Qt Creator Prerequisites: Install Qt manually using [download page](http://www.qt.io/download-open-source/#section-2) or through package manager: ``` sudo apt-get install qt5-default sudo apt-get install qtcreator #for compilation using IDE ``` Please open `nitrokey-app-qt5.pro` file and select `Build All` from `Build` menu. #### Using CMake: General use: ``` # in nitrokey-app directory: mkdir build cd build mkdir install cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./install .. make -j4 make install ``` This will build and install binary to `./build/install` directory. Please omit `-DCMAKE_INSTALL_PREFIX=./install` in case you would like to install it to the system. Note: In case you have downloaded Qt manually from web download page you have to set `CMAKE_PREFIX_PATH` to your corresponding Qt path. Example: (If QT5.5 (64bit) was installed in your `$HOME` DIR): ``` export CMAKE_PREFIX_PATH=$HOME/Qt/5.5/gcc_64/ ``` #### Using QMake: Please run following commands for out-of-the-source build: ``` mkdir build && cd build qmake .. make -j4 # make install ``` ### Debian Packages #### Building Debian Packages Execute the following in directory "nitrokey-app": ``` fakeroot make -f debian/rules binary ``` Cleanup with: ``` fakeroot make -f debian/rules clean ``` Requirements: fakeroot, debhelper, hardening-wrapper, qt5-default, libusb-1.0-0-dev, cmake. #### Building RPM and Debian Packages (alternative) CMake can generate RPM packages using CPack. It can also generate `.deb` package using other method than presented in previous section. To create both packages please execute the following in directory "nitrokey-app": ``` mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. make -j4 package ``` This will result in two packages: `.deb` and `.rpm`. #### Cross Compiling with QT5 for Windows on Ubuntu Linux (using MXE) Please run following commands: ``` # install dependencies for compilation sudo apt-get install bison cmake flex intltool libtool scons # MXE GCC6, x32 #remove MXE_PLUGIN_DIRS switch to use GCC 5.4.0 instead of GCC 6 git clone https://github.com/mxe/mxe.git && pushd mxe make MXE_TARGETS=i686-w64-mingw32.static.posix MXE_PLUGIN_DIRS=plugins/gcc6 qtbase # takes about 1 hour first time popd #following should download nitrokey-app and libnitrokey with hidapi (own clone with applied OS-specific patches) git clone https://github.com/Nitrokey/nitrokey-app.git --recursive pushd nitrokey-app/libnitrokey/build ln -s ../../../mxe/usr/bin/ ./bin/i686-w64-mingw32.static.posix-cmake .. make -j popd mkdir nitrokey-app/build/ pushd nitrokey-app/build/ ln -s ../mxe/usr/bin/ ./bin/i686-w64-mingw32.static.posix-qmake .. PATH=$PATH:./bin make -j popd ``` #### Compiling and creating a package for MAC OS 1. Use Qt (qmake) to compile the Nitrokey App 2. Navigate to `//Contents` 3. Create a .dmg file: go to the build directory and run: `macdeployqt / -dmg`. `.dmg` file will be created at the same folder. This is the final file for distributing the App on Mac OS 4. Compress the `.dmg` package: * Open Disk Utility * Select the dmg package from left column (or drag'n'drop) * Select Convert, check "compressed" option and then "Save" ## Tray Note that the Nitrokey App's graphical interface is based on a QT system tray widget. If you are using a Linux desktop environment that does not support system tray widgets, then you may be unable to access the graphical interface. Nitrokey App v1.3 shows main window right on start, offering tray's menu, and it is possible to configure it to quit once the main window is closed. ## Internals All configuration data including OTP secrets are stored in clear text in the flash of Nitrokey's microcontroller. This is not tamper resistant and may only be used for low to medium security requirements. Password Safe is encrypted using 256 bit AES key to which access is protected with SIM card. By default the OTP serial number (OTP Token) is OpenPGP Card's serial number. It can be changed within the GUI for each entry. The USB device serial number is set to the card's serial number when the device powers up. (disabled feature) Keyboard Layout: The user will input the token ID values as he wants them displayed, then the gui will translate them to keycodes of the selected layout. The keycodes will be stored on the device, along with a number saying which layout was used, this number is important when the GUI application reads the conifg back from the device (to translate the keycodes back into characters). The report protocol is described [here](https://github.com/Nitrokey/nitrokey-pro-firmware/blob/master/src/inc/report_protocol.h) for Pro and [here](https://github.com/Nitrokey/nitrokey-storage-firmware/blob/master/src/OTP/report_protocol.h) for Storage. The HID reports are set to 64 bytes. The "output report" is what you get from the device. When you send a report (command), the first byte sets the command type, then you have 59 bytes for your data, and the last 4 bytes are the CRC32 of the whole report. On the client side, please check documentation of [libnitrokey](https://github.com/Nitrokey/libnitrokey) project. ## Advantages of App 1.x branch over 0.x Nitrokey App v1.x uses `libnitrokey` for communication with device, making the code both testable and reusable. Furthermore communication speed is vastly improved. Most of the code now makes requests to device in the background improving GUI responsiveness. Also the delay between sending and receiving is decreased. Additionally device-related information is now lazy-loaded, which means App requests the data only when it needs them (it was earlier loading all OTP slot data to memory). Migration to `libnitrokey` comes with a cost of increasing compiler's requirements to be compliant with C++14 standard. Fortunately most compatible compilers have been released in 2015 and all current ones should work.nitrokey-app-1.3.2/coding-styles.sh0000755000175000017500000000043012774475055016641 0ustar janjan00000000000000#!/bin/bash #style is defined in .clang-format # run for all files #cat <(find . -name '*.cpp') <(find . -name '*.h') | xargs -n1 clang-format-3.8 -i #run only on changed files vs master git diff master --name-only | grep -e '\.cpp$' -e '\.h$' | xargs -n1 clang-format-3.8 -i nitrokey-app-1.3.2/data/bash-autocomplete/nitrokey-app0000644000175000017500000000073513221173116022375 0ustar janjan00000000000000_nitrokey_app() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--help --version --debug --debug-file --debug-window --delay --version-more --admin --language-list --language" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 else COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) fi } complete -F _nitrokey_app nitrokey-app nitrokey-app-1.3.2/data/com.nitrokey.nitrokey-app.appdata.xml0000644000175000017500000000277413275777051023637 0ustar janjan00000000000000 com.nitrokey.nitrokey-app CC0-1.0 GPL-3.0+ Nitrokey App Manage your Nitrokey devices

Nitrokey is an open source/open hardware USB key supporting secure encryption and signing. This package installs the official application to manage the features of the different USB keys.

Office Security Qt nitrokey-app nitrokey-app.desktop https://www.nitrokey.com/ https://github.com/Nitrokey/nitrokey-app/issues https://www.nitrokey.com/documentation/frequently-asked-questions https://www.nitrokey.com/start https://github.com/Nitrokey/nitrokey-app/blob/master/images/icon/nitrokey-app-icon-128-black.png Nitrokey UG info_AT_nitrokey.com
nitrokey-app-1.3.2/data/icons/hicolor/128x128/apps/nitrokey-app.png0000644000175000017500000001175612774475055024246 0ustar janjan00000000000000‰PNG  IHDR€€Ã>aËtEXtSoftwareAdobe ImageReadyqÉe<‚iTXtXML:com.adobe.xmp qï3ýIDATxÚì] ´VUÞ<!SsÀ|=RÈ53$@Hs@RbPKE4E—J`j’š8a¢™‰‰–CЉ€SB ¢`€š"& Áý­ûý‰ÿÿ?Þ=çÞsï¹ÿ»{­½XüïÞ3ìýÝ3ì³÷>6mÚ$QhÉ’%’!ªR>B¹òaÊm”›(¯W^¨ü‚òÊO)oÌB‡jjj"½ßDm¯|ºò9Ê»×!‡½È?Q~Ky¬òxå••,˜ª WüÊã”—)®Cùåè|~ß? @v¨©r?åç”g+Ÿ©Ü²¬|6ËëÇò+†*i ØEù,r+åw"¿­|ù|HŸ:*ß§¼Ty˜#åoN­XÏRÖÛ1@òÔ‚‹ºW¸r?1…¡¹)ë}í8#ÂT“ $µV¾š‹³;•ô¤]hÇïØ®«ÙÎ1Q#å#•V^¬<„Û:_·›CØÎ‡ÙîF9쨥òùÊó”ŸTîé»0‹@Û“ížÇ~´ÌŽö–À³\ùå=ÕæÅÊû*ÿœÿwA{²ËÙ¯}¼Bª'¦àÆüb)wsÜçÉÊc”•/š{ñ1Ç6|Ïq¦° (oˆRPTSpÚØQÓëO•¿îPà)ßÍ/p~ˆça>Wù4åm¶ [É[¸€|¯!à`~iØFmåPÀóù¥ýž 0%(ÿT¶u/‡í\«¿­C,çx»ò<´aì¬<ÓÝ×Öó¡Î*c S€* ¡£8~_ÜZéž%ò1®ÿ© §>Œ Öå=É)p’‚ac"PåÃ`r¥¸µj­áP‡½ûk’]jG `jü’Ãz`r¾TAðgPÅ£7Ó@âŠQéw) •CÛ)÷çT¹‡ÃzîÅ4¤@X+¨üÇ”w4”Mâ0?I2â‘kI…©sÿu1uNUî&Û(•òõÊm•Q~¼Â•/ìßãìo[öUÌu@OwÆ6è×íÍý16p¿ö{ Û™NØ>ÿˆ£B»Ë=YGû"@•#Λ¸J;3häôêÂuB/‰n@ý‚`}”)àèˆÊWy¤&Ô>¹òë%ȧ/å5’ò³¥ê/Ò —eå3¸õ©V¾œFœœÂÓrÊ­šrœaYN¯¨è`PÙZnßpÜÛžsüº\—‘håØžr½‹rK£ ¬±gî8ùƒ9xf®7'4“ò…œïùNuT„õuÇ|õ~®£DròÙqÙê£Ú\/‰Ò†8 ©Ê娰)€[‚çq{”ÀC‚}–½Ê£$ˆ?ÈÐ@è Fq”]p *nÝÞsx@­¸G‡‹Z±íþƒ×ä¨LÚŠóüøIÔu¼ óîwsTÁíkçù/‡xþßdžÀŽpdû´òCbvPö- Bárd”—8d± b…ÅtÛÙ"xù"Æ.؈ ŠrN¿“§|92Bpyó÷Wb*`úf¿ B8©î]ô·¿Iùt„eÙˆº.€Ÿ´-÷ìÃêQô7xçÏQáu ’MÜgYϱ,'€GÓáîç&åcütñpÑoH µÆ²Îë%ådU D±õ·˜áv.Òê"Ø÷w-ú ®[WX¶ I'åpCp„¸Lù%©;bÞNpw†{ôú§{WÕñ%ÛÆ,þJù«9â¥ÞÊÿäž±ûç–yÎ’H!Ó×°l8hv(Z3ŒŽ0”cg1"@<„´îÓ$¸ô¡õf¿“Òì$ð²µBKÅ!KÈ›´ D!„”ïŸÀž \ä @¶.u¬ìG–™»cY¦ ®Ž“xÒÞTÑÎÀb?}!¿ÂõôçL)½øáZq›OÈ„ºŠ} FƒÀÑÜ«_'álëå¾²O¸ó…Èæ9¶LH½ú„¶¦æÔ.\ nNˆ?ájX·\” îÕòoùÕ¡œk¤ÔWþñ',ýÒ2¶† œ¼Åyþ‰n9+÷•áN ;bjoáìÀÖÌ [Õ9>_aekÌÆ|eÅY¼~!Aö-[ÂýAÇqmûŒ&X–Õ.©µ€¯€—ÍD R¸ØÃO¿Ø¢‡ÌœÃ#”‰ÜýfzN€6œ­ümI(é¥o€_ìêð³û¡ãº`×o_ô’W¼aYÞ)RzaÕ²¶†õ\ß´¥=#±õˆ/€'-²r/àð¼UBõÞ(_ôâ­å:üåænlS·”†;šý¸.ù0iÁûdQ‚pç]®û;Ršòî ² Z4ªlÇ/»œ«8À~ yAZÂOP6r L·éãë#¸t_ q¡ØŸî¥âÏât2°èï²üv€–yô%êOñ`jÅi§øë¼É²<œ>®,³sÙÈù½΋pú4€ô²÷J¸@Ф_dñÅÒÃÅò—2Tð78;Æ23 €þâßÅXt^[f¨Žê¾ý/ Lϰgx™ï8 ìä©íΞÅÁ8î}Õ¢,$¿„7,‚ŠÇ”ÞôX7N˜·Ï7,ã ©°¸üT<§4›ûGžÊc¿2«vÜUð@ˆwáaÔ[Á’J¸éã e2‚Û¸Íiè¾æ´%t?®¯ÉÄ6Æ‘EžÊd{)=ÀbntÑok9ÌïI{Æ&É Å €Ï"ûå`årŽ”Þ†3o!Ýíƒ\àa¡÷¿”ÚØ")„MõÚÛ°nDØLö9J¯ìáWx8ûúVÊmìmð±E@ØÓ1¸F73ì^6x ‚#%¸%ts‚³Ç4ÚÖL»¢¿χ¬&Õ>†A€å-O×Z€: ê#¥GÏuÑsQ0Ñ aª4½¡Q¾^ÕFì‡]Q#Ê9,MŒ \Àö¸ò@ Ž7M'—{< ÀUlgÚs4冠·©‘PSSƒíÍ ´Q&NÉæz €m¸Ýó…~iðìÔ_äm œ5ÂÞl…³ýã ;…³÷ =Nç~?m:^ÂûN¬’w „€¢èc~¥aé×6†ÉRš|ÁZDÁ/H¹U”kèQ•z“8F€ÂŠ8ìá¼]ln½Hü¹bçHò ƒÐ#´çT ¥Ü§Rz¼ Ц÷ GØûM>K©&iœ‰Ká¹sµ'€ÜÚprõ%qŽ øÒ‡õso%viÒœwR4²|ãb&dóôézú‹ öýKù,&Ñ ¨z[Ì|å†p/m:ô^’°€ÿ­|’Éœgyh‹jðüêI\Œ…Q ¬ÿ:\­n¶¨§k/% \„‡ç ‚øy¢w³„“ÀÊß(®ÐŠ® W£H¦ØÏ°x⸶ÀM â‡>R?1KF9Bõ³Ê) ÃŒysÃ\­v0¬ãïÊt ÔYêOâÐï+í ficR/âвub–Y¦Ô[-ª*öI‹é].î ô¼øO·ˆ™ zõ"IŒ²fN2xçצ§…Ë%z¬|-·sm¹½Û˜å÷1”Õ$êØê½>~K´dÉ’=$°á‡eÇ—HÔdâ4 ÏD ×X4œÁ†ÓUÚ„9¸¢‡Í‡£Ï¾ €Å6•Er ÓJ‰™ƒ':…Û´LòíÛ$rB’H8tü cÊoLù˜$Ãi«üÈ ax}Ýày¸T]fXܲŸ ñv(çq”yJ²G—Q>a rtY¤)€ÓþõlºÁ—yQ8&Ù¹¤m \XÙ.2qTºR²IÈ`6Åà£DŸÛë×ÿr”Jãò F#®2¬Iš« ÞA"'m¬-ú}2¿øAV~5åa¢«(wñaÁwîRš3ÌžÜd«·›94ç¨3]²MÈW¿½ƒ Þy•ÛÙZ¼h‚À$Å ,r'KF+¢~€„ÊŸdðÎZ*â‘wdB MM¸'Z, +….5T¾P¾sâj€‹Ð0,Æ&¾ƒx¼3˜òÑß‘»¡[ãl„«Ø@DИîM‹ß³(¿'ûkB瀸â 8.†)óö`=Щ•߉ý4‘=äØ[¤‘s<ËbX‡Ù÷¯’nÖ0—t(ûgØ 9¾â¢A®ÃÃtSŸú–äÙ=¤Â”0ûÕÒð½QbŸs8u€(ò¨žª ‘ýxÚBùŠã¨©$³/òòζ¬|Ý2®ün쇩ògSn³=qUêRÃ÷àVŸƒ¾U~¶ßÔ=~)åå<—R’)bà€›>Þ7|¯)çÀÁS>Ú{¿Ô}ie]ô>å”H¢©¤sÁ±Ñ­« ߃É9zpµk3Ïß”í-æ¡ò«©üyI56$Q/Óbã‰;€‹Ã]û;'mÁûtkŒ‡EqY#âàh÷½{ÍYî\±¿RØ¿ÃÄÜ(Vñ­ä>x\„2pÒ÷Õs½XÞ-Eë8öÏçU/ŽD|¼áßå^Öx&Ái´«e]ùþƒ,Ï–jÙŸâO oP Dºv‘è&ÑC9ìN6BW>?U¢ŸH®`?Æø(dßïÆ}‚‰ãzµîT(¾è¤4ˆ¥1ŸÎçºÇPçlÿ‹¾ 8 ·‡¿GCÉà˜†O|ÑIþ­ìbþÿ!‰Ç¡ÿXñì–°bŠ;.À5áJ$?<Èc™Âî4I(ó©oq® BÅÕ¬Ã|[L±=ÃØ¾¹YhÖPXQ#±¢¦yÒ¦ilÏpñäFÐJ@ºîViÞÒµ‚õw“ôSÉ68€°€)ÜÓ#MR÷ô¡ž‘¬÷Ép\cÖP dÇD^¤¬¹Íá0\ËòQÏå¬7ÓT)Ø|H>›[»ñ1¡–åíÃòWTŠÀ* B^ DÓ Í*ríÙ¦š[Ã÷Û°¼…•&¨J@pâ†pj$•@*ú°«‹ùün|i¥ (k† 8Ô«ð×ïĹž<¸±–@$D6O³O0²!è3D†}*´.VIEND®B`‚nitrokey-app-1.3.2/data/icons/hicolor/16x16/apps/nitrokey-app.png0000644000175000017500000000244512774475055024071 0ustar janjan00000000000000‰PNG  IHDRóÿatEXtSoftwareAdobe ImageReadyqÉe<(iTXtXML:com.adobe.xmp ¾åõ “IDATxÚ|“;HA†/!Š_¥I%Ágá+Á€…EÄJ°ð‰………b£BH¡ˆhaa㣰°°´PˆVF-,Ä;±±Èù Ì…½ÕdácŽ™ùgowgBžç9ör]·3êÚƒíX,öjç†Ìû0ó0 ï°£¡)¨ƒSؤÐE Â!¾Ó€,lÁ1‰?Z¸“‚9è€;X"~æøÄqk8³N‰E®Xr£aõWB¦˜Q l@¯ædTãDJì$¿‡1ÔCþ63/\DœÄ<À$T«XV+Œ›¹K؈مAu­B3L«•ßÏAô¿?(ƒ~C,«–aVwîân47PàIŸéî­Éî9„ûà7MJ5…iÝ¡ ñt#|3Ž™ÐÜ´ÙHRèªD M¢—xhì*yrökøyÒ|¡• 6aä|·0Bð˺`y÷gl'þ¸DuÈóuJW"ˆâ¸vªÄ’¾øÏ0i²ÜÃÄu&gEüXt":‹êZ—ÉDümçþ 0&ž' ÀyIEND®B`‚nitrokey-app-1.3.2/data/icons/hicolor/22x22/apps/nitrokey-app.png0000644000175000017500000000311412774475055024055 0ustar janjan00000000000000‰PNG  IHDRÄ´l;tEXtSoftwareAdobe ImageReadyqÉe<‚iTXtXML:com.adobe.xmp ,‚`IDATxÚ”•MHQÇGK%ÁQI š¢hY”A¸uá²"." ¦*Z‹Ô åG¡ÑJqaË·¢$bIb$øÑ{›,(]äGúü8O¦qfÞxáǹsî=ÿ¹sï¹g¢B¡áÔ‚Á` æ&ÔÂU˜^xãóùv —e'Œ`*æ܇ u…Líƒ>äë…,Ä<€ ˆƒ…§Ì1~‰þC(‡X؆èaüÓa è?‡õ¯A?¼$à»Í¥aª¡Ψ{ê˜?o^¡Ÿ¥{ØcLØ1"4âdÕ· ®Á*qçÿ Šp Á”ô½ÂütËó”脟£M Ø5<4Vydß—°Nñ' 9ÌFh…xuwÀ»ùÑÄ’adct/ãMSnk¦xfò ðËç‚Ø6M¿VkºB‹'aÍåY€du'Âx á|ý ]Pe'l·Ç’>mü~½m Ð,‰ÔZt½Ò¬r“þo½²§a’læ¿C¬Ì¡¦È•Od<Á¼Ãp*ø‰mwXH" 6þJ¶®XnËøy°Ÿ![ç­ëÁ½âÅû–ÕÊÊ–¤ÀÆWW¬Ý.eQ¯sìi™ÌÅ7hÕÖ«qÝaÑÿª›^Ɇ|=˜gøNaÿ¸äy½Ö–¸ÂÜm§²™ƒ™ÖƒóË*]D¥^¿€_PÌÜ%×BO@1f\³£›ÿšíšrPÊø´×?Hæ­ÖÚRÜ žÄCŠ>\Öš]†ÿ£ç_“Š‹è‡]rÎÚ——ÞEtíXÿ<Ë J1à:¼—Іàx¤jx ÀWÞ<¥DwÈÇIEND®B`‚nitrokey-app-1.3.2/data/icons/hicolor/24x24/apps/nitrokey-app.png0000644000175000017500000000321612774475055024064 0ustar janjan00000000000000‰PNG  IHDRÄé…ctEXtSoftwareAdobe ImageReadyqÉe<‚iTXtXML:com.adobe.xmp !fî¶¢IDATxÚœ–KHQÇï½Z¤"7‚p!E.Š¢pRö€¨EEÐLZ=Ñ‹¬M)Aô€„eТ…Ô"zA Qaµ™$2¡dÏÛï‹?1žæŒsïÀoî7ßùÿÏ=óÍ™IçóùÔhG5„í°Z©kОÍf_¦iŸ Â¥„e_âÏÌ ߉M/'l†­P¥ôw¸§ô{¬…±úÝ gàfŸ¼&ˆÏ%ì€50N×?Ài þèL¦B“ÉA¥Òßà*œ¤þÙ´pÞÒ¸¯e¸· ¡e]®e]º´‹±ÇÂ&ƒœO°C_¤Š8ЩÕjl‚!t&†Mþ®Ét¢ ¸ÉØß¡ü½LªÈ¡„Çp6ÄÕfН„Ëœ>€yJ%7É7¦4¡p#a‘ÝL°®©pJ¦ÁØ]ð?A|6ØwšÀ–¨ÍS¾“Ú™‰ÿ ÅS a‹3‘0_ÏÇŒPþ—ÆD&”^AyD}­nr‹ö/;îB3ô:Ñ=±–¤x˜øÎcbǘ硃úÛmyOÅUŠÍàÛžm)÷#¾Ñ5p4פ]q/3)aðÎ/xL†´§EÝËÓp4ÿ™œ…>­yN9kÉAGçT3‰ãž ä¤Ñ'ÍÿváõšýW˜ƒP9ëû#ðÔZ˜Ü£˜v¯&<‡ñÖÔ^Œ|ŸPØ¡½¨G­úêlû`P>Æ` á¡ýK5Ãʸ¶þ¯Qq'4ÄÍ^“UkcÞJÃÿÄ#øÙ„¡B"Óc ìZ—jû5©Q·ŠÞêuóìmÙXC„åºUcµõ[ЇDV{VRwàÎ÷ÁR[S4bð¾à¯QßÛî[æ\Ö+û0?Šú$r̪d´N){Ÿ´"Þ›äUñG€‘±…~XJIEND®B`‚nitrokey-app-1.3.2/data/icons/hicolor/32x32/apps/nitrokey-app.png0000644000175000017500000000362412774475055024065 0ustar janjan00000000000000‰PNG  IHDR szzôtEXtSoftwareAdobe ImageReadyqÉe<‚iTXtXML:com.adobe.xmp oQ¨IDATxÚ¬—khŽaÇßw£!ÊFâóÅd_ÖÆ¤JÍZrH’XÉ–S %+û2Æä0Z>ä,Iâ”1‡lmR(¦˜CÎl^¿Kÿ·n=ïiï]ÿ®ç¹žët®ëºŸ`8$:::: !«À<±Î€}¡P¨9Q[ÁxÀi_ȰøˆÝ{ÁI‚ù‘’p<R –ƒ,Ïçë¢S<ü7 $I€ãbÍv.Hw>uƒã`Æ[%;²,ýٟଭ ²7b€¡ 1cùÞ˜@8„±÷>A…,+@Èó¹Å‚¶àÑÿþ_(ƒ\£=Š×ì€ (þŠó¼ô”é Nó|~fa«ÝÀ-H¡„ºÀQ-݃@/†&f[¹ »»EÞlvià‚?Èn2à"ï_⬞cU-­rZ?(D·%æ¥T¨N¯A1ŠoìÃtvrÅZñ¢]ºùFÊ5 f'à<[¥;âü¸l&t-ï«Kêt±¬N”1‹¶ÎÇÛÖiÉWA‰_KŽúc‚1»DžS—‹ül°”Uv¸²A]Çw8ÿWÀd»’êR´žÐé€Ö|šp8ÙqnÏMúqn:¥Ñœ'úo¸H)4Øa7‰NrxVÌVâøXJN„Ýv¶ &ØCU4§U8ïLùß±'<…ùb¶½üí$2þ0&Ûz>ë'‡IEND®B`‚nitrokey-app-1.3.2/data/icons/hicolor/48x48/apps/nitrokey-app.png0000644000175000017500000000462412774475055024104 0ustar janjan00000000000000‰PNG  IHDR00Wù‡tEXtSoftwareAdobe ImageReadyqÉe<‚iTXtXML:com.adobe.xmp (j8K¨IDATxÚÔZilUE¾MDYš MlŒ¢lLZHD±þ¬Ñ-`€°•M”TÙCÅJ!Pˆ$¦DA£ÑH¡a 6P”EÅÅ4RYÛTd-Ôï„ï%“éÜûîÜ{_Á“|™¾¹³œ3sæœ3gklltÂPuuµ^Õ x˜ bÀ Ø4¨ÓÓÓCÍßʉŽR€)À MûöQ¬Ö磘´EcdÓÀBó*¥±Íì“vòX‚Ú´Añ"ð íÑôËöm¾ŠÏ Nד*OE1xУé¯djO¢°zô9 ¬@s‘ ƳPÌæª·vi&} |”· êú Çy–‡ÛD7d7dRX0}Š1ÀL` Çõ\éUÀIŸ ׃ãÊÎtðhwˆã–B˜k¾㢯¯s‚ÁV›]·%™+˜ôôh÷)„ —\óQì2<Ôä+2^ŽÁ ~ÀŠÄ`Œͬòœ‡zß‚>un~à=ækdÐùw'b’…@±Saæî¿ tÒš oïòwàŠ.J‡¹Ú›1ÉeŸžØz\Æm‡baàÑÓ×7ó`n(– Y}2C‰ $Lì–ÝÉXÈ–ÚoUÀXÖÃ.dÿÈN0 k§}+¢9½+èC3)÷t^:‰·Ï»0!næÄŽG鍯K_ú.Æ.Üw§èÀÃø¢ÃßâtZ*í–°n¨aŒîÀ¼æ@ôv"å\F«Sè5 €+&‹<⬹؅‡šEL4E£ÑT哬øû¼¥y™H Kþ6X©¥IŒw6’ùA.ÍžFQ€Ã÷߀^j\CºÌ&zä* Ì£ºäû貜Y“^?Âëh¥’©(G°0ò¬Ýý.Z‹$WÉ Êkß·ñN +>ŒïK¦͵d>NïЬ¾jøÖ@3ƒ0o+@™ž”òIÃW0öºIKô/n%#JÑÂÛ*^ë‚déúñ,|É¿eGê,’f¾Po[½¡÷C´ï³çw¡> Y ülqö„‡Þ.<6 Ô ¿ê.Ôêu4x>àråQ`ó2qÊ1„¹kmì´f÷ÿ à(s”ª«¼âšÀ ×ðò®Ò 5ÌE9ȯYð!i7‘–[0£Ú©´óŸItˆÐÆIVa‚&è¦WÑfqL à®Yî˜Ì™¥yèe ­˜“ƒ¶H«.4Ü[ßÐÔMϨe3¾ÿ3@¨"sjÕ‹È›/3*O)¿;KÀ¦©’˜Õb­ßyæs²h÷ƒÄY1‡•êSÜsrX¦kÕ#9³*WÄ뜠'ì˜8ÇHݧ¦±¼Wv«±’®>NÂXÛ©´‘EhC *±…±$‚Ý®-l1ÚÌ JÈå˜Ö~+&ê¯ uÕ Is«ÆÓ1ò,â¶IW«]Ë0aF„É­ ®¼šj—9sÝTÇ— )ŒàêãÆêê‘üv(‰‡ÖMTuW$Ñ(ÊÓ§L¸×¹ýÚ”r8FWM%óü0oNcÀ-¼…©BÜ| ¼mš·`Ÿo8†Ê|>çò—Q°}¥„:ɳÓ&§é[™¬äd'ñ3“˜Zy'¦Õß ó¥V)‘€Ï¬ÃQ|< }ºB°ÔiúìÔž÷y¾ºWûVÇ»Û:§ô_ ø’ò©c~¬>Ç@l Oã&ÕÐö0ðRЗŸX˜ÿ•àKf㢖†&ÿ²4¥ o2k1ßí2éP)žä]bÏnÛï`•aÿÙ#ªÜh%¸1̹QÛd±OhŠ2¹+[¹…ٶѼ¼4å¬ëÅ6‘=]ý'Àþ&ÙÐ.³û¨IEND®B`‚nitrokey-app-1.3.2/data/icons/hicolor/scalable/apps/nitrokey-app.svg0000644000175000017500000000262612774475055025066 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-dark/apps/16/nitrokey-app.svg0000644000175000017500000000514312774475055025313 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-dark/apps/22/nitrokey-app.svg0000644000175000017500000000527012774475055025311 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-dark/apps/24/nitrokey-app.svg0000644000175000017500000000531412774475055025312 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-dark/apps/48/nitrokey-app.svg0000644000175000017500000000540212774475055025316 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-light/apps/16/nitrokey-app.svg0000644000175000017500000000207612774475055025503 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-light/apps/22/nitrokey-app.svg0000644000175000017500000000207412774475055025476 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-light/apps/24/nitrokey-app.svg0000644000175000017500000000217112774475055025476 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/icons/ubuntu-mono-light/apps/48/nitrokey-app.svg0000644000175000017500000000370712774475055025512 0ustar janjan00000000000000 nitrokey-app-1.3.2/data/nitrokey-app-small.xpm0000644000175000017500000000123212774475055020706 0ustar janjan00000000000000/* XPM */ static char * nitrokey_app_small_xpm[] = { "22 22 2 1", " c None", ". c #E0E0E0", " ... ", " ....... ", " ..... ..... ", " .... .... ", " ... ... ", " .. .. ", " .. .. .. ", " .. .... .. ", " .. . ..... .. ", " .. ... ..... .. ", " .. ...... .... .. ", " .. ....... . .. ", " .. ....... .. ", " .. ...... .. ", " .. .... .. ", " ... .. ... ", " .. .. ", " .. .. ", " ... ... ", " ... ... ", " ....... ", " ... "}; nitrokey-app-1.3.2/data/nitrokey-app.desktop0000644000175000017500000000040312774475055020444 0ustar janjan00000000000000[Desktop Entry] Name=Nitrokey App GenericName=Nitrokey Management Application Comment=Manage your Nitrokey devices TryExec=nitrokey-app Exec=nitrokey-app Icon=nitrokey-app Type=Application Categories=Utility;Security;Qt; Keywords=Nitrokey;OpenPGP;smart card; nitrokey-app-1.3.2/debian/changelog0000644000175000017500000000217513232102135016572 0ustar janjan00000000000000nitrokey-app (1.0beta1) xenial; urgency=medium * Beta test -- Szczepan Zalega Sat, 11 Mar 2017 20:35:20 +0100 nitrokey-app (0.6.2) xenial; urgency=low * Update to version 0.6.2 -- Szczepan Zalega Tue, 03 Jan 2017 15:49:07 +0100 nitrokey-app (0.6.1) xenial; urgency=low * Update to version 0.6.1 -- Szczepan Zalega Tue, 29 Nov 2016 12:05:36 +0100 nitrokey-app (0.6) xenial; urgency=low * Update to version 0.6 -- Szczepan Zalega Mon, 28 Nov 2016 12:01:00 +0100 nitrokey-app (0.5.1) xenial; urgency=low * Update to version 0.5.1 -- Szczepan Zalega Fri, 07 Oct 2016 18:15:12 +0200 nitrokey-app (0.5) xenial; urgency=low * Update to version 0.5 -- Szczepan Zalega Tue, 27 Sep 2016 14:41:41 +0200 nitrokey-app (0.4) xenial; urgency=low * Update to version 0.4 -- Jan Suhr Fri, 15 Jul 2016 15:22:59 +0200 nitrokey-app (0.3.2) xenial; urgency=low * Initial release package -- Jan Suhr Tue, 21 Jun 2016 15:22:59 +0200 nitrokey-app-1.3.2/debian/compat0000644000175000017500000000000213232102135016111 0ustar janjan000000000000009 nitrokey-app-1.3.2/debian/control0000644000175000017500000000137513275777051016352 0ustar janjan00000000000000Source: nitrokey-app Section: universe/utils Priority: optional Maintainer: Jan Suhr Build-Depends: debhelper (>= 9), qtchooser, libqt5core5a, libqt5dbus5, libqt5gui5, libqt5widgets5, libqt5xml5, qt5-qmake, qtbase5-dev-tools, qtbase5-dev, libhidapi-dev, cmake, libqt5svg5-dev Standards-Version: 3.9.7 Homepage: https://www.nitrokey.com Package: nitrokey-app Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libqt5core5a, libqt5dbus5, libqt5gui5, libqt5widgets5, libqt5xml5, libhidapi-libusb0, libqt5svg5 Description: Nitrokey App for usage with Nitro Key Pro The Nitrokey App is required for Nitrokey Pro and Nitrokey Storage. It offers Google Authenticator compatible One-Time-Passwords and and tamper-proof password storage. nitrokey-app-1.3.2/debian/copyright0000644000175000017500000000175513232102135016656 0ustar janjan00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: nitrokey-app Source: https://github.com/Nitrokey/nitrokey-app Files: * Copyright: 2016 Jan Suhr License: GPL-3.0+ License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". nitrokey-app-1.3.2/debian/docs0000644000175000017500000000004513232102135015565 0ustar janjan00000000000000OTP_full_specification.txt README.md nitrokey-app-1.3.2/debian/nitrokey-app.dirs0000644000175000017500000000052313232102135020220 0ustar janjan00000000000000/usr/bin /usr/share/applications /usr/share/pixmaps /usr/share/icons/ubuntu-mono-dark /usr/share/icons/ubuntu-mono-light /usr/share/icons/hicolor /usr/share/icons/breeze /usr/share/icons/breeze-dark /usr/share/icons/Humanity /usr/share/icons/Humanity-Dark /usr/share/icons/Adwaita /lib/udev/rules.d /usr/share/bash-completion/completions nitrokey-app-1.3.2/debian/nitrokey-app.menu0000644000175000017500000000040013232102135020215 0ustar janjan00000000000000?package(nitrokey-app): needs="X11" \ section="Applications/System/Security" \ title="Nitrokey App" \ command="nitrokey-app" \ icon="/usr/share/pixmaps/nitrokey-app-small.xpm" nitrokey-app-1.3.2/debian/nitrokey-app.postinst0000755000175000017500000000004313232102135021142 0ustar janjan00000000000000#!/bin/sh -e #DEBHELPER# exit 0 nitrokey-app-1.3.2/debian/nitrokey-app.postrm0000755000175000017500000000004213232102135020602 0ustar janjan00000000000000#!/bin/sh -e #DEBHELPER# exit 0 nitrokey-app-1.3.2/debian/postinst0000755000175000017500000000003513232102135016522 0ustar janjan00000000000000#!/bin/bash -e #DEBHELPER# nitrokey-app-1.3.2/debian/rules0000755000175000017500000000341713275777051016026 0ustar janjan00000000000000#!/usr/bin/make -f export DEB_BUILD_HARDENING=1 export QT_SELECT=qt5 clean: -rm build -rm nitrokey-app dh_testdir qmake -qt=qt5 make clean dh_clean -A build: cd libnitrokey/build && cmake .. && ${MAKE} qmake -qt=qt5 ${MAKE} touch build nitrokey-app: build binary: nitrokey-app dh_testdir dh_testroot dh_prep dh_installdirs install -m755 nitrokey-app debian/nitrokey-app/usr/bin/nitrokey-app cp -r data/icons/ubuntu-mono-dark/* debian/nitrokey-app/usr/share/icons/ubuntu-mono-dark/ cp -r data/icons/ubuntu-mono-dark/* debian/nitrokey-app/usr/share/icons/breeze-dark/ cp -r data/icons/ubuntu-mono-dark/* debian/nitrokey-app/usr/share/icons/Humanity-Dark/ cp -r data/icons/ubuntu-mono-light/* debian/nitrokey-app/usr/share/icons/ubuntu-mono-light/ cp -r data/icons/ubuntu-mono-light/* debian/nitrokey-app/usr/share/icons/breeze/ cp -r data/icons/ubuntu-mono-light/* debian/nitrokey-app/usr/share/icons/Humanity/ cp -r data/icons/hicolor/* debian/nitrokey-app/usr/share/icons/hicolor/ cp -r data/icons/hicolor/* debian/nitrokey-app/usr/share/icons/Adwaita/ install -m644 data/nitrokey-app.desktop debian/nitrokey-app/usr/share/applications/nitrokey-app.desktop install -m644 data/icons/hicolor/48x48/apps/nitrokey-app.png debian/nitrokey-app/usr/share/pixmaps/nitrokey-app.png install -m644 data/nitrokey-app-small.xpm debian/nitrokey-app/usr/share/pixmaps/nitrokey-app-small.xpm install -m644 data/bash-autocomplete/nitrokey-app debian/nitrokey-app/usr/share/bash-completion/completions/nitrokey-app dh_installdocs dh_installchangelogs dh_strip dh_shlibdeps dh_installmenu dh_icons dh_compress dh_fixperms dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary-arch: binary binary-indep: binary build-arch: build build-indep: build .PHONY: clean binary nitrokey-app-1.3.2/debian/source/format0000644000175000017500000000001413232102135017421 0ustar janjan000000000000003.0 (quilt) nitrokey-app-1.3.2/i18n/CMakeLists.txt0000644000175000017500000000006713221173116017020 0ustar janjan00000000000000SET_DIRECTORY_PROPERTIES(PROPERTIES CLEAN_NO_CUSTOM 1) nitrokey-app-1.3.2/i18n/nitrokey_arabic.qm0000644000175000017500000006456713314460010017776 0ustar janjan00000000000000<¸dÊÍ!¿`¡½ÝB0%Uã²VÍY;,;U¸+;>eNÈ"SYz3u7Z>Ž´OÛÔ!@)Ê#SB:(Œ”2%˜Å-@Û{_(4²þ+ŒPD$ä (G=Š#G–ÄZME^CïTƒŠ$/YÙ «Z6`0Z6z1«\Pz^J\œZíqqO6¾ñUQÄ•š;íÿþ+ÉRZXåQ‹$d?’+ÛuOŒ\Q´<\Q´B5\Q´Zþ\œš(_;”¿u_*š‰jþ Y‹ˆþKÍÐ{ô&Ö€éÞõôÊOÐÑ{@j?ùBqc#|Y³eQu@¹iè“ ¡}Âð38ð"„)ÓY—„PÞ)O“F 媹·L ¬áÑWy¬áÒWá¬áÓXI¬áÔX±ÊÔùtÑZ+–B|30»P®_¾TÁÊVk“1 …VŽEÇN:æí %aÀúL,* D-§/u*TBN` …pµ!LGz°Å…z°ÅR{@±ˆ˜b€˜I¼Õ¯ƒWU¹h¥QÚÈrŽ=¬ϦåRô ‡:y;9®0H;°½YY=FsW QNÀXžP(X4žSeu‰Èn_7ÑvMzG†‰¥MR¡ê¿:Tª‹Ãƒ«–G\z«Ç Õ¸°j~Âíu.CÃŒã`üëF01×÷]÷^…¥M¬d5|–ENü'ˆ¥O9JÕq.ÒJÕr/TÉJUªA)`ëN$¬pxÊ!£qàê1 €¥ô¯ãK¯ã3ÓÚ#ÉÞ¼N/ñ>t Ü}ôNîK%£¾¼,N¨`z0xÊ2ýGç~)ÂIÕˆ\ª@cÐ=žD­ÕR´"•ן3óñNÀŽãÚõ9Ä*Z`šN u*9ƒN‡ŒÚ w¯)S©Ä i.ñ>TKmúþF$ 5Ñ&¾ 5ÑS Oþz [0ªu ^‰ÓEb `gt á qkä> ä%À µ‡»^Ì Õ.‰Jß ´‡ {D&l ŒÎ=_ Ì\´ Ckê 0 FÞ( FøçL§ ˜Iœ>8 ®>3Ss ®>ú+8 ®>úZT Â$î× –Ca; $Ð -Òn' 7‡2;ô OÊÿ/Ü c]/ j:êYø ¯ENF Y ¾Yt$Y ÍIN " ÍIN<ä Ø¡5· Ø¡T` âË.1F ëÏUT" ù Nµ 33› ]·Aê &•R/ 3ïùR¦ >¦J-k A_õax A®E`´ EŠBÒ OG0± X1† hÞAœ „]3(ñ ‰á‰± §0þE  Ê_—U8 ÌÎ < Õü¾+n ÝØò\ å@~J *'^ ¾ *'^>ä ,j @þJ"Ï `º¶ l>Nc u_Zß àlÔ/L îûô| ðZ<(µ ®GB2/–[¬:2ˆ‹mÕT·©D^Gœï9õ*‘ c)P„Á/4I½_I*êc”iQNëèõ_M› ý*ݤ›ê[Uͯê Áý ÞCibB C1* 'D%3 /J D' JECF 'D/.HD %DJG  SD card is not accessible  AboutDialogB 'DC1* 'D0CJ D' JECF 'D/.HD %DJG  Smartcard is not accessible  AboutDialog%1 ,J,'('J*%1 GB AboutDialogF(DE *E3- E3-' "EF' ((J'F'* 94H'&J))(Not erased with random data) AboutDialogT<span style="color:#c80636"> *-0J1 </span>*Warning AboutDialog-HDAbout AboutDialogF47Active AboutDialog'DE3*./E 'DE/J1Admin: AboutDialog%5/'1 'D*7(JB App version: AboutDialog&'D1BE 'D*D3DJ DDC1*Card serial number: AboutDialog'D-'D) 'DEA5D)Detailed Status AboutDialog'D,2! 'DE4A1Encrypted volume: AboutDialog %5/'1 'DAJ1E HJ1Firmware version: AboutDialog'D,2! 'DE.AJHidden Volume: AboutDialog*H,/ 0'C1) %3 /J ,/J/)New SD card found AboutDialog&D' JH,/ F*1HCJ F47 No active Nitrokey  AboutDialogFD' JH,/ %*5'D 'D1,'! %9'/) 'DE-'HD)No connection Please retry AboutDialog:J1 F47 Not active AboutDialogF9EOK AboutDialog<9/'/ E-'HD'* %/.'D 'D1E2 'D31JPassword retry counters: AboutDialogDDB1'!) AB7 READ ONLY AboutDialogB1'!)/C*'() READ/WRITE AboutDialog1BE 'D%3 /JSD ID: AboutDialog 'D-'D)Status AboutDialogT0'C1) 'DAD'4 :J1 "EF)! '.*1 EA'*J- 'D*#3J3&Stick is not secure! Select Init keys. AboutDialogE3'-) 'D*.2JFStorage Capacity: AboutDialog 'D,2! :J1 'DE4A1Unencrypted volume: AboutDialog'DE3*./EUser: AboutDialog@CDE) 31 .7#. J1,I %9'/) 'DE-'HD)Wrong PIN. Please try again.Authentication .'F'* charsDialogChangePassword<BE (*:JJ1 CDE) 'D31 DDAJ1E HJ1Change Firmware PasswordDialogChangePassword0:J1 'D1BE 'D31J DDE3*./EChange user PINDialogChangePassword4'D1BE 'D31J 'D-'DJ DDE/J1:Current Admin PIN:DialogChangePassword8CDE) 'D31 'D-'DJ) DDAJ1E HJ1Current Firmware Password:DialogChangePassword"CDE) 'D31 'D-'DJ)Current User PIN:DialogChangePassword`'D1BE 'D31J 'D-'DJ :J1 5-J-. J1,I %9'/) 'DE-'HD).Current password is not correct. Please retry.DialogChangePasswordZ'D,G'2 DE J*E *#3J3G (9/. J1,I %9'/) 'DE-'HD)6Device is not yet initialized. Please try again later.DialogChangePassword4CDE) 'D31 'D,/J/) DDE3*./E New User PIN:DialogChangePassword6*E *GJ&) 'D1BE 'D31J 'D,/J/New password is setDialogChangePassword,GJ& CDE) 'D31 DDE3*./EReset User PINDialogChangePassword89// E-'HD'* 'D%9'/) 'DE*(BJ)Retry count left:DialogChangePassword(GJ& CDE) 'D31 DDE/J1 Set Admin PINDialogChangePassword0GJ& 'D1BE 'D31J 'DE3*./E Set User PINDialogChangePassword #8G1 'D1BE 'D31JShow PINDialogChangePassword#8G1 CDE) 'D31 Show passwordDialogChangePassword4'D-/ 'D#B5I DCED) 'D31 GH $The maximum length of a password is DialogChangePassword4'D-/ 'D#/FI DCDE) 'D31 GH $The minimum length of a password is DialogChangePasswordL'D-/ 'D#/FI D7HD CDE) 'D31 'DB/JE) GH *The minimum length of the old password is DialogChangePasswordÎD3H! 'D-8 '3*FA0* CD E-'HD'* 'D%9'/). J1,I E7'D9) 'D*9DJE'* DE91A) CJAJ) %9'/) *GJ&) CDE) 'D31 DDE/J1.aUnfortunately you have no more trials left. Please check instruction how to reset Admin password.DialogChangePasswordüD3H! 'D-8 '3*FA0* CD E-'HD'* 'D%9'/). J1,I '3*./'E .J'1 "%9'/) *GJ&) 'D1BE 'D31J DDE3*./E" EF 'DB'&E) D%9'/) *GJ&) CDE) 'D31.jUnfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset passwordDialogChangePassword¸(*H5J): '3*./E CDE) 31 DE1) H'-/) B5J1) 'D#E/ D*7(JB'* 'DH( H7HJD) 'D#E/ DD*7(JB'* 'DE-DJ))O(Recommendation: Use TOTP for web applications and HOTP for local applications) MainWindow@******************************** ******************************** MainWindow(0000000000000000000000000000000000000000 MainWindow6 #1B'E6 digits MainWindow8 #1B'E8 digits MainWindow#3'3 32Base32 MainWindow(DE JECF *-1J1 'DEH69Can't clear slot. MainWindow&DE JECF -A8 EH69 %1Can't save slot. %1 MainWindow8DE JECF A*- .2'F) CDE'* 'D31Can't unlock password safe. MainWindow#D:Cancel MainWindow#-1A E*(BJ)Characters left: MainWindowHA4D *FAJ0 'D#E1. J1,I %9'/) 'DE-'HD)+Command execution failed. Please try again. MainWindow.*E* C*'() 'D*GJ&) (F,'-#Configuration successfully written. MainWindow°BJE) 'D9/'/ DE J*E F3.G'. GF'C .7# AJ 'D*-HJD. 6(7 BJE) 'D9/'/ D5A1. J1,I %9'/) 'DE-'HD)fCounter value not copied - there was an error in conversion. Setting counter value to 0. Please retry. MainWindow 'D,G'2 *E %:D'BGDevice has been locked MainWindowD' *A9D 4J&' Do nothing MainWindow.'6:7 E1*JF 9DI CapsLockDouble press CapsLock: MainWindow,'6:7 E1*JF 9DI NumLockDouble press NumLock: MainWindow2'6:7 E1*JF 9DI ScrollLockDouble press ScrollLock: MainWindow%D:'! EH69 Erase Slot MainWindow(.7# AJ C*'() 'D*GJ&)Error writing configuration! MainWindowrDF*1HCJ 3*H1J, J,( #F J*CHF BJE) 'D9/'/ (JF 5A1 H 9999999BFor Nitrokey Storage counter must be a value between 0 and 9999999 MainWindowò'E- CDE) 'D31 DDE3*./E (9/ 10 /B'&B (%0' DE J*E '.*J'1G A%F CDE) 31 'DE3*./E 3*(BI AJ 'D0'C1) %DI -JF 'D.1H, EF 'D(1F'E,)fForget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) MainWindow&HD/ CDE) 31 94H'&J)Generate random password MainWindow(HD/ CDE) 31 94H'&J' Generate random password  MainWindow&HDQP/ 'D31 'D94H'&JGenerate random secret MainWindow@CDE) 'D31 DE1) H'-/) 7HJD) 'D'E/HOTP MainWindowH7HD CDE) 'D31 DE1) H'-/) 7HJD) 'D#E/ HOTP length: MainWindowEH69 HOTP  HOTP slot  MainWindow 'D'3'3 'D3* 941JHex MainWindow#.A 'D31 Hide secret MainWindow5J:) 'DE/.D'* Input format: MainWindow'3E 'D/.HD Login name: MainWindowMUIMUI: MainWindow"'D*-CE AJ 'DEH'69 Manage slots MainWindow4*-1JC E9'ED 'D(01 'D94H'&JMoving factor seed: MainWindow%3EName: MainWindowF*1HCJ (1H E*5DNitrokey Pro connected MainWindow˜F*1HCJ (1H %5/'1 0.7 D' J/9E 'D#31'1 'D*J *(/# EF ('J* A'1:. J1,I *:JJ1 'D31]Nitrokey Pro v0.7 does not support secrets starting from null byte. Please change the secret. MainWindow$F*1HCJ 3*H1J, E*5DNitrokey Storage connected MainWindow*E *H5JD F*1HCJNitrokey connected MainWindowF*1HCJ :J1 E*5DNitrokey disconnected MainWindow F*1HCJ DJ3 E*5D'Nitrokey is not connected! MainWindowØED'-8): 2<sup>'D+'FJ</sup> 'DE9'ED'* :J1 E-EJ) 6/ 'DG,E'* 'D-3J). BE (*:JJ1 CD CDE'* 'D31 9F/ AB/'FC DF*1HCJ~Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. MainWindowOMPOMP: MainWindowOTP 'D9'E OTP General MainWindow*%9/'/'* CDE) 'D31 OTPOTP Password settings MainWindow>*GJ&) EH69 CDE) 'D31 DE1) H'-/)OTP Slot Configuration MainWindowJCDE) 'D31 DE1) H'-/) *E F3.G' DD-'A8)/One-time password has been copied to clipboard. MainWindowE9'ED'* Parameters MainWindow .2'F) CDE'* 'D31 Password Safe MainWindow*.2'F) CDE'* 'D31 [%1]Password safe [%1] MainWindowCDE) 31 Password: MainWindow$J1,I %/.'D CDE) 31Please enter a password. MainWindow*J1,I %/.'D '3E 'DEH69Please enter a slotname. MainWindow²BE (-E'J) CDE) 'D31 DE1) H'-/) (1BE 31J DDE3*./E (3HA J7D( EFC %/.'DG AJ CD '3*./'E ,/J/)EProtect OTP by user PIN (will be requested on first use each session) MainWindow'-A8Save MainWindowEA*'- 31J Secret Key: MainWindow('D31 F3. %DI 'D-'A8)Secret copied to clipboard MainWindowEA*'- 31J Secret key MainWindowN#13D 'enter' C".1 E/.D EF DH-) 'DEA'*J-"Send 'enter' as the last keystroke MainWindow#13D HOTP1 Send HOTP1 MainWindow#13D HTOP2 Send HOTP2 MainWindow#13D 1BE 'D*HCF Send token ID MainWindow'6(7G 94H'&J' Set to random MainWindow'6(7G 5A1' Set to zero MainWindow EH69 Slot  MainWindow('DEH69 *E E3-G (F,'-"Slot has been erased successfully. MainWindow"'DEH69 EE3- E3(B'Slot is erased already. MainWindow'3E 'DEH69 Slot name: MainWindow,*E* C*'() 'DEH69 (F,'-Slot successfully written. MainWindowEH69Slot: MainWindowCDE) 31 +'(*) 0Static password 0 MainWindow@CDE) 'D31 DE1) H'-/) B5J1) 'D'E/TOTP MainWindowHE/I CDE) 'D31 DE1) H'-/) B5J1) 'D#E/TOTP interval: MainWindow7HD TOTP TOTP length: MainWindowEH59 TOTP  TOTP slot  MainWindowTTTT: MainWindow&'DHB* .'1, 'DE2'EF)Time is out-of-sync MainWindow,*E* %9'/) *GJ&) 'DHB*! Time reset! MainWindow°DD*9'ED E9 G0G 'D.'5J) 'D*7(JB 3HA J-A8 CDE) 31 'DE3*./E AJ 'D0'C1). GD *1J/ 'D'3*E1'1dTo handle this functionality application will keep your user PIN in memory. Do you want to continue? MainWindow1BE 'D*HCFToken ID MainWindow*'A*- .2'F) CDE'* 'D31Unlock password safe MainWindowŒ*-0J1! 'DHB* AJ ,G'2 'DCE(JH*1 :J1 E*2'EF E9 F*1HCJ. JECF #F JCHF 'DCE(JH*1 GJ& (2EF .7# #H #FG *E '.*1'B 'D,G'2. %0' *E '.*1'B F*1HCJ #H #5J( ((1E,J) .(J+) AJF(:J %9'/) *GJ&) 'D31 DCDE) 'D31 'DE$B*) DE1) H'-/). %0' C'F 'DHB* .7# (,G'2C AJF(:J *5-J-G +E %9'/) *GJ&) 'DHB* 9DI F*1HCJ. GD *1:( AJ %9'/) *GJ&) 'DHB* AJ F*1HCJ•WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? MainWindowBGD #F* E*#C/ EF 1:(*C E3- 'DEH591WARNING: Are you sure you want to erase the slot? MainWindow’*-0J1: 'D,2! 'DE3A1 :J1 "EF. '.*1 .'5J) "#33 'D,G'2" EF 'DB'&E) 'D.'5) (G]Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. MainWindow|*-0J1: 'D,2! 'DE4A1 :J1 "EF. '.*1 "#33 F*1HCJ ((J'F'* 94H'&J)"UWarning: Encrypted volume is not secure, Select "Initialize storage with random data" MainWindow@CDE) 31 .7#. J1,I %9'/) 'DE-'HD)Wrong PIN. Please try again. MainWindowCDE) 31 .'7&)Wrong user password. MainWindow<'D31 :J1 5-J-. J1,I *:JJ1 'D311Your secret is invalid. Please change the secret. MainWindow&#D:&Cancel PinDialog&F9E&OK PinDialog.CDE) 31 'DE3*./E 'DE/J1 Admin PIN: PinDialogZ'D,G'2 DE J*E *#3J3G (9/. J1,I %9'/) 'DE-'HD)6Device is not yet initialized. Please try again later. PinDialog2#/.D CDE) 'D31 DDAJ1E HJ1Enter Firmware Password PinDialog4#/.D CDE) 'D31 DDAJ1E HJ1:Enter Firmware Password: PinDialog$#/.D CDE) 31 'DC1*Enter card password: PinDialog2#/.D CDE) 31 'D,2! 'DE.AJ Enter password for hidden volume PinDialog4#/.D CDE) 31 'D,2! 'DE.AJ:!Enter password for hidden volume: PinDialog"CDE) 31 'DE3*./E:Enter user PIN PinDialogF'A0) CDE) 'D31Password dialog PinDialog#8G1 CDE) 'D31 Show password PinDialog*'DE-'HD'* 'DE*(BJ):%1Tries left: %1 PinDialog"CDE) 31 'DE3*./E: User PIN: PinDialog‚*-0J1: DB/ '3*./E* 'D1BE 'D31J 'D'A*1'6J. J1,I *:JJ1 'D1BE 'D31J4Warning: Default PIN is used. Please change the PIN. PinDialogjCDE) 'D31 7HJD) C+J1'! '3*./E CDE) D' *2J/ 9F 30 -1A'6Your PIN is too long! Use not more than 30 characters. PinDialogfCDE) 'D31 B5J1) C+J1'. '3*./E CDE) D' *BD 9F 8 #-1A1Your PIN is too short. Use at least 6 characters. PinDialog 'D*B/EProgressStick20ResponseDialog8J1,I *A9JD 'D,2! 'DE4A1 #HD')Please enable the encrypted volume first.StorageActionsÎG0' 'D%,1'! J:DB 'D,2! 'DE4A1. GD *1J/ 'D'3*E1'1 D*,F( AB/'F 'D(J'F'* J1,I *F2JD 'D,G'2 B(D 'D'3*E1'1‡This activity locks your encrypted volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding.StorageActionsÜG0' 'D9ED J:DB 'D,2! 'DE.AJ. GD *1J/ 'D'3*E1'1 D*,F( AB/'F 'D(J'F'* J1,I *F2JD 'D#,2'! 'DE-ED) B(D 'D'3*E1'1„This activity locks your hidden volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding.StorageActionsÚ*-0J1: *HDJ/ EA'*J- AES 'D,/J/) 3HA J/E1 'D,2! 'DE4A1 'D,2! 'DE.AJ H.2'F) CDE'* 'D31. GD *1:( AJ 'D'3*E1'1qWARNING: Generating new AES keys will destroy the encrypted volumes, hidden volumes, and password safe! Continue?StorageActions 'D1BE 'D31J .'7&Wrong password.StorageActions&-HD F*1HCJ&About NitrokeyTray&&:J1 CDE) 31 'DE/J1&Change Admin PINTray.&:J1 CDE) 31 'DAJ1E HJ1&Change Firmware PasswordTray*&:J1 CDE) 31 'DE3*./E&Change User PINTray&5--&DebugTray0&/E1 (J'F'* 'D,2! 'DE4A1&Destroy encrypted dataTray\&97D 13'D) *-0J1 "#33 'D0'C1) ((J'F'* 94H'&J)"6&Disable 'initialize storage with random data' warningTray*&A9D *-/J+ 'DAJ1E HJ1&Enable firmware updateTray(&5/1 'DAJ1E HJ1 DEDA&Export firmware to fileTray&*GJ&) 'DE5F9&Factory resetTray&#33 'D,G'2&Initialize deviceTray8&#33 'D0'C1) ((J'F'* 94H'&J)$&Initialize storage with random dataTray&#:DB 'D,G'2 &Lock DeviceTray$&#:DB 'D,2! 'DE4A1&Lock encrypted volumeTray"&#BAD 9*'/ 'DAD'4&Lock stick hardwareTray&OTP&OTPTray &#.1,&QuitTray4&#9/ *GJ&) CDE) 31 'DE3./E&Reset User PINTrayD&',9D 'D,2! :J1 'DE4A1 DDB1'!) AB7!&Set unencrypted volume read-onlyTrayN&',9D 'D,2! :J1 'DE4A1 DDB1'!) H'DC*'()"&Set unencrypted volume read-writeTray"&GJ! 'D,2! 'DE.AJ&Setup hidden volumeTray$&'A*- 'D,2! 'DE4A1&Unlock encrypted volumeTray$&'A*- 'D,2! 'DE.AJ&Unlock hidden volumeTrayF47ActiveTray"F47 (H69 'D*5-J-)Active (debug mode)Tray *GJ&) ConfigureTray F*1HCJ DJ3 E*5D'Nitrokey is not connected!TrayCDE'* 'D31 PasswordsTray>'D%3 /J #H 'DC1* 'D0CJ :J1 ,'G2"Smartcard or SD card are not readyTray*GJ&) .'5)Special ConfigureTray*'A*- .2'F) CDE'* 'D31Unlock password safeTray *-/J+ 'DAJ1E HJ1Firmware update UpdateDialog4'4)Dialogsecuritydialog2B1#* HAGE* 'D*-0J1 'D#EFJ+I read and understood this security warningsecuritydialogF9EOKsecuritydialog%%stick20HiddenVolumeDialogZ-// FG'J) 'D,2! 'DE.AJ 9F/ %1 EF 'D,2! 'DE4A11End hidden volume at %1 of the encrypted storage:stick20HiddenVolumeDialog,J,'('J*GBstick20HiddenVolumeDialog(%9/'/'* 'D,2! 'DE.AJHidden Volume settingsstick20HiddenVolumeDialog&'D,2! 'DE.AJ EH69 1Hidden volume slot 1stick20HiddenVolumeDialog&'D,2! 'DE.AJ EH69 2Hidden volume slot 2stick20HiddenVolumeDialog&'D,2! 'DE.AJ EH69 3Hidden volume slot 3stick20HiddenVolumeDialog&'D,2! 'DE.AJ EH69 4Hidden volume slot 4stick20HiddenVolumeDialogEJ,'('J*MBstick20HiddenVolumeDialog E*H37Mediumstick20HiddenVolumeDialog"%9/'/'* CDE) 'D31Password settingsstick20HiddenVolumeDialog7HD CDE) 'D31:Password strength:stick20HiddenVolumeDialogCDE) 'D31 Password:stick20HiddenVolumeDialog GJ! 'D,2! 'DE.AJSetup hidden volumestick20HiddenVolumeDialog#8G1 CDE) 'D31 Show passwordstick20HiddenVolumeDialogP%(/# 'D,2! 'DE.AJ 9F/ %1 EF 'D,2! 'DE4A13Start hidden volume at %1 of the encrypted storage:stick20HiddenVolumeDialog0-,E 'D*.2JF: %1 ,J,'('J*Storage capacity: %1GBstick20HiddenVolumeDialogBHJStrongstick20HiddenVolumeDialog.CDE* 'D31 :J1 E*7'(B*JFThe passwords are not identicalstick20HiddenVolumeDialog’'DEF7B) 'D*J DE JC*( 9DJG' EH,H/) DD,2! 'DE.AJ (JF %1 H %2 EF 'D-,E 'DCDJ[The unwritten area available for hidden volume is between %1 % and %2 % of the storage sizestick20HiddenVolumeDialogH-/)Unit:stick20HiddenVolumeDialogBHJ ,/' Very Strongstick20HiddenVolumeDialog69JA ,/' Very Weakstick20HiddenVolumeDialog69JAWeakstick20HiddenVolumeDialog(-,E .7# DD,2! 'DE.AJWrong size of hidden volumestick20HiddenVolumeDialogXCDE) 'D31 B5J1) ,/'. '3*./E 8 #-1A 9DI 'D#BD6Your password is too short. Use at least 8 characters.stick20HiddenVolumeDialog7HDlengthstick20HiddenVolumeDialog-1A 5:J1 lower casestick20HiddenVolumeDialog #1B'Enumbersstick20HiddenVolumeDialog1EH2symbolsstick20HiddenVolumeDialog-1A C(J1 upper casestick20HiddenVolumeDialog#:DB 'DAJ1E HJ1 Lock Firmwarestick20LockFirmwareDialogˆÿÿÿ$ ÿ* nitrokey-app-1.3.2/i18n/nitrokey_arabic.ts0000644000175000017500000021731013314460010017771 0ustar janjan00000000000000 AboutDialog About حول App version: إصدار التطبيق Firmware version: إصدار الÙيرم وير Card serial number: الرقم التلسلي للكرت Status الحالة Hidden Volume: الجزء المخÙÙŠ <span style="color:#c80636">Warning</span> <span style="color:#c80636"> تحذير </span> Stick is not secure! Select Init keys. ذاكرة الÙلاش غير آمنة! اختر Ù…ÙØ§ØªÙŠØ­ التأسيس New SD card found وجد ذاكرة إس دي جديدة (Not erased with random data) (لم تمسح مسحا آمنا ببيانات عشوائية) SD ID: رقم الإس دي Logo Unencrypted volume: الجزء غير Ø§Ù„Ù…Ø´ÙØ± Encrypted volume: الجزء Ø§Ù„Ù…Ø´ÙØ± Password retry counters: عداد محاولات إدخال الرمز السري Admin: المستخدم المدير User: المستخدم <html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 by NitrokeyUG. </span></p><p><span style=" font-size:10pt; font-style:italic;">This software is licensed under the </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3</span></a><span style=" font-size:10pt; font-style:italic;">.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html> Detailed Status الحالة Ø§Ù„Ù…ÙØµÙ„Ø© OK نعم SD card is not accessible كرت الإس دي لا يمكن الدخول إليه Smartcard is not accessible الكرت الذكي لا يمكن الدخول إليه No connection Please retry لا يوجد إتصال الرجاء إعادة المحاولة READ/WRITE قراءة/كتابة READ ONLY للقراءة Ùقط Active نشط (hidden) Not active غير نشط No active Nitrokey لا يوجد نتروكي نشط Storage Capacity: مساحة التخزين %1 GB %1 جيجابايت <html><head/><body><p>This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.</p></body></html> <html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Instructions and help</span></a></p></body></html> *** Clearing data in progress *** *** Communication error *** *** Firmware is locked *** Licenses and 3rd-party components Cannot open dialog: Authentication Wrong PIN. Please try again. كلمة سر خطأ. يرجى إعادة المحاولة DebugDialog Debug Log DialogChangePassword Change user PIN غير الرقم السري للمستخدم Show PIN أظهر الرقم السري Retry count left: عدد محاولات الإعادة المتبقية Change Firmware Password قم بتغيير كلمة السر للÙيرم وير Unfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset password لسوء الحظ، Ø§Ø³ØªÙ†ÙØ°Øª كل محاولات الإعادة. يرجى استخدام خيار "إعادة تهيئة الرقم السري للمستخدم" من القائمة لإعادة تهيئة كلمة السر. Unfortunately you have no more trials left. Please check instruction how to reset Admin password. لسوء الحظ، Ø§Ø³ØªÙ†ÙØ°Øª كل محاولات الإعادة. يرجى مطالعة التعليمات Ù„Ù…Ø¹Ø±ÙØ© كيÙية إعادة تهيئة كلمة السر للمدير. Set User PIN هيئ الرقم السري المستخدم Current User PIN: كلمة السر الحالية New User PIN: كلمة السر الجديدة للمستخدم Set Admin PIN هيئ كلمة السر للمدير Current Admin PIN: الرقم السري الحالي للمدير: Reset User PIN هيئ كلمة السر للمستخدم Current Firmware Password: كلمة السر الحالية للÙيرم وير Show password أظهر كلمة السر Current password is not correct. Please retry. الرقم السري الحالي غير صحيح. يرجى إعادة المحاولة New password is set تم تهيئة الرقم السري الجديد The minimum length of the old password is الحد الأدنى لطول كلمة السر القديمة هو chars خانات The maximum length of a password is الحد الأقصى لكملة السر هو The minimum length of a password is الحد الأدنى لكلمة السر هو Device is not yet initialized. Please try again later. الجهاز لم يتم تأسيسه بعد. يرجى إعادة المحاولة The new password entries are not the same Current PIN or password New PIN or password <html><head/><body><p><span style=" font-style:italic;">Nitrokey prevents against brute force password guessing attacks by allowing a maximum of 3 incorrect PIN attempts. Therefore a PIN of %1 digits is sufficient. The PIN must be between %1 and %2 characters.</span></p></body></html> New PIN: Confirm New PIN: Confirm New User PIN: New Password: Confirm New Password: The Firmware password doesn’t have a retry counter, and therefore doesn’t prevent against password guessing attacks. A secure and complex password should be created with the use of: lower and upper case letters, numbers and special characters; with a length between %2 and %3 characters.<br/>Default firmware password is: '%1'. WARNING! If you lose your Firmware password, Nitrokey can’t be updated or reset! LicenseDialog License information (ESC to Exit) MainWindow OTP Slot Configuration تهيئة موضع كلمة السر لمرة واحدة Manage slots التحكم ÙÙŠ المواضع TOTP كلمة السر لمرة واحدة قصيرة الامد HOTP كلمة السر لمرة واحدة طويلة الامد Slot: موضع Erase Slot إلغاء موضع Name: إسم Secret key Ù…ÙØªØ§Ø­ سري Secret Key: Ù…ÙØªØ§Ø­ سري ******************************** ******************************** Secret copied to clipboard السر نسخ إلى Ø§Ù„Ø­Ø§ÙØ¸Ø© Hide secret أخ٠السر Generate random secret ÙˆÙ„Ù‘ÙØ¯ السر العشوائي Input format: صيغة المدخلات Hex الاساس الست عشري Note: 2<sup>nd</sup> factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. ملاحظة: 2<sup>الثاني</sup> المعاملات غير محمية ضد الهجمات الحسية. قم بتغيير كل كلمات السر عند Ùقدانك لنتروكي Parameters معاملات Set to zero اضبطه ØµÙØ±Ø§ Set to random اضبطه عشوائيا 6 digits 6 أرقام 8 digits 8 أرقام Moving factor seed: تحريك معامل البذر العشوائي HOTP length: طول كلمة السر لمرة واحدة طويلة الأمد TOTP interval: مدى كلمة السر لمرة واحدة قصيرة الأمد Token ID رقم التوكن Send token ID أرسل رقم التوكن MUI: MUI TT: TT OMP: OMP Cancel ألغ Save Ø§Ø­ÙØ¸ (Recommendation: Use TOTP for web applications and HOTP for local applications) (توصية: استخدم كلمة سر لمرة واحدة قصيرة الأمد لتطبيقات الوب، وطويلة الأمد للتطبيقات المحلية) Base32 أساس 32 Send 'enter' as the last keystroke أرسل 'enter' كآخر مدخل من لوحة Ø§Ù„Ù…ÙØ§ØªÙŠØ­ 00000000000000000000 00000000000000000000 OTP General OTP العام OTP Password settings إعدادات كلمة السر OTP Double press NumLock: اضغط مرتين على NumLock Double press CapsLock: اضغط مرتين على CapsLock Double press ScrollLock: اضغط مرتين على ScrollLock Do nothing لا ØªÙØ¹Ù„ شيئا Send HOTP1 أرسل HOTP1 Send HOTP2 أرسل HTOP2 Password Safe خزانة كلمات السر Password: كلمة سر Login name: اسم الدخول Slot name: اسم الموضع Static password 0 كلمة سر ثابتة 0 Generate random password ولد كلمة سر عشوائية Characters left: أحر٠متبقية ... Unlock password safe Ø§ÙØªØ­ خزانة كلمات السر Nitrokey disconnected نتروكي غير متصل Nitrokey Pro connected نتروكي برو متصل Nitrokey Storage connected نتروكي ستوريج متصل Counter value not copied - there was an error in conversion. Setting counter value to 0. Please retry. قيمة العداد لم يتم نسخها. هناك خطأ ÙÙŠ التحويل. ضبط قيمة العداد Ù„ØµÙØ±. يرجى إعادة المحاولة Reset Nitrokey's time? TOTP length: طول TOTP Wrong PIN. Please try again. كلمة سر خطأ. يرجى إعادة المحاولة Device has been locked الجهاز تم إغلاقه Counter must be a value between 0 and %1 For Nitrokey Storage counter must be a value between 0 and 9999999 لنتروكي ستوريج يجب أن يتكون قيمة العداد بين ØµÙØ± Ùˆ 9999999 Please enter a slotname. يرجى إدخال اسم الموضع Configuration successfully written. تمت كتابة التهيئة بنجاح Error writing configuration! خطأ ÙÙŠ كتابة التهيئة Nitrokey is not connected! نتروكي ليس متصلا One-time password has been copied to clipboard. كلمة السر لمرة واحدة تم نسخها Ù„Ù„Ø­Ø§ÙØ¸Ø© WARNING: Are you sure you want to erase the slot? هل أنت متأكد من رغبتك مسح الموصع؟ Slot has been erased successfully. الموضع تم مسحه بنجاح Slot موضع Can't clear slot. لم يمكن تحرير الموضع Slot is erased already. الموضع ممسح مسبقا Please enter a password. يرجى إدخال كلمة سر Can't save slot. %1 لم يمكن Ø­ÙØ¸ موضع %1 Generate random password ولد كلمة سر عشوائيا Time is out-of-sync الوقت خارج المزامنة WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? تحذير! الوقت ÙÙŠ جهاز الكمبيوتر غير متزامن مع نتروكي. يمكن أن يكون الكمبيوتر هيئ بزمن خطأ أو أنه تم اختراق الجهاز. إذا تم اختراق نتروكي أو أصيب ببرمجية خبيثة، Ùينبغي إعادة تهيئة السر لكلمة السر المؤقتة لمرة واحدة. إذا كان الوقت خطأ بجهازك Ùينبغي تصحيحه ثم إعادة تهيئة الوقت على نتروكي. هل ترغب ÙÙŠ إعادة تهيئة الوقت ÙÙŠ نتروكي؟ Time reset! تمت إعادة تهيئة الوقت! Nitrokey connected تم توصيل نتروكي Warning: Encrypted volume is not secure, Select "Initialize storage with random data" تحذير: الجزء Ø§Ù„Ù…Ø´ÙØ± غير آمن. اختر "أسس نتروكي ببيانات عشوائية" TOTP slot موصع TOTP HOTP slot موضع HOTP Can't unlock password safe. لم يمكن ÙØªØ­ خزانة كلمات السر Wrong user password. كلمة سر خاطئة Password safe [%1] خزانة كلمات السر [%1] Protect OTP by user PIN (will be requested on first use each session) قم بحماية كلمة السر لمرة واحدة برقم سري للمستخدم (سو٠يطلب منك إدخاله ÙÙŠ كل استخدام جديد) Forget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) امح كلمة السر للمستخدم بعد 10 دقائق (إذا لم يتم اختياره ÙØ¥Ù† كلمة سر المستخدم ستبقى ÙÙŠ الذاكرة إلى حين الخروج من البرنامج) Command execution failed. Please try again. ÙØ´Ù„ تنÙيذ الأمر. يرجى إعادة المحاولة To handle this functionality application will keep your user PIN in memory. Do you want to continue? للتعامل مع هذه الخاصية، التطبيق Ø³ÙˆÙ ÙŠØ­ÙØ¸ كلمة سر المستخدم ÙÙŠ الذاكرة. هل تريد الاستمرار؟ Nitrokey Pro v0.7 does not support secrets starting from null byte. Please change the secret. نتروكي برو إصدار 0.7 لا يدعم الأسرار التي تبدأ من بايت ÙØ§Ø±Øº. يرجى تغيير السر Your secret is invalid. Please change the secret. السر غير صحيح. يرجى تغيير السر Slot successfully written. تمت كتابة الموضع بنجاح <html><head/><body><p>The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to.</p></body></html> <html><head/><body><p>Hide or show the secret.</p></body></html> <html><head/><body><p>Password Safe fields support UTF8 data. It means that you can use your national characters here. Please remember however that non-English characters could take more space (up to 4 characters). The counters next to each field are to inform how much more standard English characters can given field accept.</p></body></html> <Select Password Safe slot> Password safe unlocked AES keys not initialized. Please provide Admin PIN. Keys generated. Please unlock Password Safe again. Wrong admin password. User not authenticated Wrong Pin. Please try again. Factory reset was successful. Locking device Select slot type: TOTP Select slot type: HOTP Select OTP slot number Slot name The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to. OTP secret key Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. After generating a random secret, you would need to copy it into your application or service where you want to login to. Example: "ZR3M5I..." Secret input format: base32 Example: "A3911C05..." (remove any 0x prefix) Secret input format: hex Entered OTP 'Secret Key' string is longer than supported by this device Label shown when the OTP secret key is too long HOTP moving factor seed Set HOTP counter to zero Set HOTP counter to random value OTP code length: 6 digits OTP code length: 8 digits TOTP interval value OMP part of Token ID TT part of Token ID MUI part of Token ID Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Erase Password Safe slot Password Safe slot number Unlock Password Safe The Nitrokey App is available as an icon in the tray bar. The secret string you have entered is invalid. Please reenter it. Connecting device <html><head/><body><p><span style=" font-weight:600; color:#a40000;">Entered OTP 'Secret Key' string is longer than supported by this device</span></p></body></html> Label shown when the OTP secret key is too long secret is not passing validation. Provided secret hex string is invalid. Please check input and try again. Details: WARNING: This Storage firmware version is old. Application may be unresponsive and unlocking encrypted volume may not work. Please update the firmware to the latest version. Guide should be available at: <br/><a href='https://www.nitrokey.com/en/doc/firmware-update-storage'>www.nitrokey.com/en/doc/firmware-update-storage</a>. Nitrokey App Overview Unlock Encrypted Volume Unlock Hidden Volume Lock Device Help Quit Copy secret to clipboard Copy to clipboard Settings General Show first-run message Show warning when no partitions could be detected on Encrypted Volume (Linux only) Show message about device's connection / disconnection Show main window when device connects Hide main window when device disconnects Do not quit when the main window is closed <html><head/><body><p>Translation file (needs restart)</p></body></html> Translation file (needs restart) Debug log settings Path for debug log file: Verbosity level: Select path Logging enabled Log to console Clipboard settings Time to store OTP secrets in clipboard (in seconds): Time to store Password Safe secrets in clipboard (in seconds): TIme to store Password Safe secrets in clipboard (in seconds): You can find application’s tray icon in system tray in the right down corner of your screen (Windows) or in the upper right (Linux, MacOS). Idle Would you like to show this message again? Device lock detected, please remove and insert the device again. If problem will occur again please: 1. Close the application 2. Reinsert the device 3. Wait 30 seconds and start application Warning: Application could not detect any partition on the Encrypted Volume. Please use graphical GParted or terminal fdisk/parted tools for this. Would you like to be reminded again? Device connected. Waiting for initialization... Please run the application again to apply new settings. Would you like to quit now? Debug file location (will be overwritten) current: Communication error. Please reinsert the device. Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. تحذير: الجزء Ø§Ù„Ù…Ø³ÙØ± غير آمن. اختر خاصية "أسس الجهاز" من القائمة الخاصة به PinDialog Password dialog Ù†Ø§ÙØ°Ø© كلمة السر Enter card password: أدخل كلمة سر الكرت Show password أظهر كلمة السر &Cancel &ألغ &OK &نعم Your PIN is too long! Use not more than 30 characters. كلمة السر طويلة كثيرا! استخدم كلمة لا تزيد عن 30 Ø­Ø±ÙØ§ Your PIN is too short. Use at least 6 characters. كلمة السر قصيرة كثيرا. استخدم كلمة لا تقل عن 8 أحر٠Warning: Default PIN is used. Please change the PIN. تحذير: لقد استخدمت الرقم السري Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ. يرجى تغيير الرقم السري Tries left: %1 المحاولات المتبقية:%1 Device is not yet initialized. Please try again later. الجهاز لم يتم تأسيسه بعد. يرجى إعادة المحاولة Enter user PIN كلمة سر المستخدم: User PIN: كلمة سر المستخدم: Enter admin PIN Admin PIN: كلمة سر المستخدم المدير Enter Firmware Password أدخل كلمة السر للÙيرم وير Enter Firmware Password: أدخل كلمة السر للÙيرم وير: Enter password for hidden volume أدخل كلمة سر الجزء المخÙÙŠ Enter password for hidden volume: أدخل كلمة سر الجزء المخÙÙŠ: Enter card PIN Would you like to so now? Please enter the new PIN/password QApplication Critical error encountered. Please restart application. Message: Stick20ResponseDialog Progress التقدم StorageActions This activity locks your hidden volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding. هذا العمل يغلق الجزء المخÙÙŠ. هل تريد الاستمرار؟ لتجنب Ùقدان البيانات، يرجى تنزيل الأجزاء المحملة قبل الاستمرار Enabling encrypted volume Encrypted volume enabled Could not enable encrypted volume. Wrong password. الرقم السري خاطئ Status code: %1 This activity locks your encrypted volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding. هذا الإجراء يغلق الجزء Ø§Ù„Ù…Ø´ÙØ±. هل تريد الاستمرار؟ لتجنب Ùقدان البيانات، يرجى تنزيل الجهاز قبل الاستمرار Disabling encrypted volume Encrypted volume disabled Could not lock encrypted volume. Please enable the encrypted volume first. يرجى ØªÙØ¹ÙŠÙ„ الجزء Ø§Ù„Ù…Ø´ÙØ± أولا Enabling hidden volume Hidden volume enabled Could not enable hidden volume. Disabling hidden volume Hidden volume disabled Could not lock hidden volume. Locking device Device locked Could not lock device. Device set in update mode Device could not be set in update mode. Firmware exported Could not export firmware. WARNING: Generating new AES keys will destroy the encrypted volumes, hidden volumes, and password safe! Continue? تحذير: توليد Ù…ÙØ§ØªÙŠØ­ AES الجديدة سو٠يدمر الجزء Ø§Ù„Ù…Ø´ÙØ±ØŒ الجزء المخÙÙŠØŒ وخزانة كلمات السر. هل ترغب ÙÙŠ الاستمرار؟ Generating new AES keys New AES keys generated Keys could not be generated. Could not clear SD card. Communication issue. Flag cannot be cleared. Flag cleared. Cannot set unencrypted volume read-only Unencrypted volume set read-only Cannot set unencrypted volume read-write Unencrypted volume set read-write Cannot set encrypted volume read-only Encrypted volume set read-only Cannot set encrypted volume read-write Encrypted volume set read-write Functionality not implemented in current version Hidden volume created Hidden volume could not be created. To complete the lock procedure, please remove and reconnect the Nitrokey. Tray Active (debug mode) نشط (وضع التصحيح) Active نشط Nitrokey is not connected! نتروكي ليس متصلا Unlock password safe Ø§ÙØªØ­ خزانة كلمات السر &OTP &OTP &Factory reset &تهيئة المصنع &Change User PIN &غير كلمة سر المستخدم &Change Admin PIN &غير كلمة سر المدير &Debug &صحح &Quit &أخرج &About Nitrokey &حول نتروكي &OTP and Password safe &Unlock encrypted volume &Ø§ÙØªØ­ الجزء Ø§Ù„Ù…Ø´ÙØ± &Lock encrypted volume &أغلق الجزء Ø§Ù„Ù…Ø´ÙØ± &Unlock hidden volume &Ø§ÙØªØ­ الجزء المخÙÙŠ &Lock hidden volume &Change Firmware Password &غير كلمة سر الÙيرم وير &Enable firmware update &ÙØ¹Ù„ تحديث الÙيرم وير &Export firmware to file &صدر الÙيرم وير لمل٠&Destroy encrypted data &دمر بيانات الجزء Ø§Ù„Ù…Ø´ÙØ± &Initialize device &أسس الجهاز &Initialize storage with random data &أسس الذاكرة ببيانات عشوائية &Set unencrypted volume read-only &اجعل الجزء غير Ø§Ù„Ù…Ø´ÙØ± للقراءة Ùقط &Set unencrypted volume read-write &اجعل الجزء غير Ø§Ù„Ù…Ø´ÙØ± للقراءة والكتابة &Set encrypted volume read-only &Set encrypted volume read-write &Setup hidden volume &هيء الجزء المخÙÙŠ &Disable 'initialize storage with random data' warning &عطل رسالة تحذير "أسس الذاكرة ببيانات عشوائية" &Lock stick hardware &أقÙÙ„ عتاد الÙلاش &Reset User PIN &أعد تهيئة كلمة سر المسخدم &Lock Device &أغلق الجهاز Smartcard or SD card are not ready الإس دي أو الكرت الذكي غير جاهز Passwords كلمات السر (empty) Configure تهيئة Special Configure تهيئة خاصة Long operation in progress: %1% &Help &Overview UpdateDialog Firmware update تحديث الÙيرم وير <html><head/><body><p>When you select &quot;OK&quot; the device enters the <br/>firmware update mode. There is no way back!<br/>Please read the <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;">documentation </span></a>how to <br/>update the firmware.</p><p>Continue entering the firmware update mode?</p><p><br/></p></body></html> main Nitrokey App - Manage your Nitrokey sticks Show additional information about binary Enable extra administrative functions List available languages Enable debug messages Save debug log to file with name <log-file-name> (experimental) Save debug log to App's window (experimental) Set delay between commands sent to device (in ms) to <delay> Load translation file with given name and store this choice in settings file. Set debug level, 0-4 Clear all application's settings securitydialog Dialog شاشة OK نعم I read and understood this security warning قرأت ÙˆÙهمت التحذير الأمني <html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Security Information</span></p><p>Please read the following carefully.</p><p><span style=" font-weight:600;">PIN Protection</span></p><p>Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.</p><p><span style=" font-weight:600;">Physical Protection</span></p><p>All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.</p><p><span style=" font-weight:600;">Hidden Volumes</span></p><p>Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are however stored on a flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.</p></body></html> stick20HiddenVolumeDialog Setup hidden volume هيء الجزء المخÙÙŠ Password settings إعدادات كلمة السر Password strength: طول كلمة السر: length طول lower case حر٠صغير upper case حر٠كبير numbers أرقام symbols رموز Hidden Volume settings إعدادات الجزء المخÙÙŠ Hidden volume slot 1 الجزء المخÙÙŠ موضع 1 Hidden volume slot 2 الجزء المخÙÙŠ موضع 2 Hidden volume slot 3 الجزء المخÙÙŠ موضع 3 Hidden volume slot 4 الجزء المخÙÙŠ موضع 4 Password: كلمة السر Show password أظهر كلمة السر Your password is too short. Use at least 8 characters. كلمة السر قصيرة جدا. استخدم 8 أحر٠على الأقل The passwords are not identical كلمت السر غير متطابقتين Wrong size of hidden volume حجم خطأ للجزء المخÙÙŠ Unit: وحدة % % MB ميجابايت GB جيجابايت Very Weak ضعي٠جدا Weak ضعي٠Medium متوسط Strong قوي Very Strong قوي جدا The unwritten area available for hidden volume is between %1 % and %2 % of the storage size المنطقة التي لم يكتب عليها موجودة للجزء المخÙÙŠ بين %1 Ùˆ %2 من الحجم الكلي Storage capacity: %1GB حجم التخزين: %1 جيجابايت Start hidden volume at %1 of the encrypted storage: إبدأ الجزء المخÙÙŠ عند %1 من الجزء Ø§Ù„Ù…Ø´ÙØ± End hidden volume at %1 of the encrypted storage: حدد نهاية الجزء المخÙÙŠ عند %1 من الجزء Ø§Ù„Ù…Ø´ÙØ± <html><head/><body><p><span style=" font-weight:600;">You should understand the properties of hidden volumes before proceeding. It can destroy your encrypted data! <br/>Please read </span><a href="https://www.nitrokey.com/documentation/hidden-volumes"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">these instructions</span></a><span style=" font-weight:600;"> first.</span></p></body></html> <html><head/><body><p>1. You may want to copy some innocuous files to the encrypted data.<br/>2. Configure hidden volumes in this dialogue. <br/>3. Once you configured a hidden volume you must not use/write to the encryption volume anymore. Otherwise it may destroy the data in your hidden volume.</p></body></html> Hidden volume not positioned in unwritten space. Please set your volume between %1% and %2% of total SD card size. Hidden volume password Please use shift+tab key shortcut for instructions Hidden volume password (repeated) Slot under which hidden volume information will be stored Use this as hidden volume size unit Size will be rounded down to integral percent of total storage size (%1MB) stick20LockFirmwareDialog Lock Firmware أغلق الÙيرم وير <html><head/><body><p>When you select &quot;OK&quot; the stick lock the firmware and close the hardware debug port.This disables any external hardware access to the data in the device (processor).</p><p>There is no way back! </p><p>After this you can't update the firmware.</p></body></html> nitrokey-app-1.3.2/i18n/nitrokey_de_DE.qm0000644000175000017500000022733313404176655017530 0ustar janjan00000000000000<¸dÊÍ!¿`¡½ÝB %ÿE² T¯;D;ÿ+;¡…12 NÈY#Yz€ð7Z¡¦´ÐÔWÑì0Xöû%ZT)Ê^S5ß‹B:f¤Œp4”D˜ÅpÚÛ{ûæ H°$%·<(4²¦*ì0Í£+ŒÐþ9ôOpeA º‹FD$äVG=Š]¶G–ÄïME^©8TƒŠ_YÙ ]Z6`{’Z6z}¿\PzK\œZ kØ%¶HqqO‹¡v±¹WvíƺyþàDæ"s’º…- ÐÞÝ´Ö°y·î® ª¾ñUÓQÄ•šPÍbjtíÿþl²ïØ~7 RXåÓö"oÕÒ$d¢Ø+ÛuÏÅ-Dä Î-cîm-Ké/-\Q´%\Q´§\Q´Œ\œšc^?`Ò_;”·u_*¢{÷~ÿv‰jþd‹ˆþʈ™ÂÐ{ôa²Ö€éS¿â)hÇ¡õôÊUÐÑQƒT^åh ‰º¿ uÏak>9”BRÄ;k³ßÙ@j£SBqc^vDÆOv?GçgÞJìTfGY@÷eQu¤Ìiè“|^I÷}Âð€SðX³„)Ó#„PÞgw“FWb™Ùugª¹·ÊÙ¬áÑ ÿ¬áÒk¬áÓ׬áÔC³å4ºÊÔùvÌÉY0˜ö(²æÑZN¡Î5\°Î5¿\+–§\302ÂP®ÐTÁÊ ok“1Aa…VŽCXˆýnZÍÇN˜.ç¶ZŸé¡x™í %!GúLnüÞZ DqM „é/u*fBN`Vì[h¥‰pµ!Ëz°Åz°ÅÕt{@Lˆ˜b@ƘI¼Be›ñ_5¯ƒWþ)¹h¥ÔaÈrŽŸ¿ϦåÕ÷ÿ–E\l²àsµòàt ‡:¶$§5¶¸;9®{Æ;°½ã=Fs ˆPXOÙQNÀ*BXžÑ,X4ž#Reu‰În_7NdnÞþ&oFž´5vMzQ†‰¥ÌM¡ê¿‘'§Žª‹Ãw«–G3«Ç Ol¸°j„¿ 3ÂíutoÃŒãBÄñ^ž=È9T·µѯŠ ÞɼZëF0}ó÷]÷_¥ÌÃgéäÃdˆZ–Eα'ˆ¥Îò3CnJüAÏDŠÍJÕqtôJÕru3TÉJUª¥\`ëN_åg|½hLΈpxÊWôqàê|÷€¥ ¯ã3V¯ã33ÂŽS!ÓÚ^ÕÞ¼N,*áashSñ>tó}ôÍ2ªÉшîÉÈ!h¯ò%£¾Q,N¨®0xÊ€3ÄÞ©Gç~iIÕ [ÐõµCˆ\ª¤v”W$FD »G[°§¨„]V¯ß¾³“Ð=žªÕR´Zן„Ñä`n¾ÍñNÀ)· ©â‹ãÚŽ5“ßC6èáB9Äió`šNÃg§®>3u*˃Î"ŒÚ"„ fdX5¯)×bÄ irÃȇé TÊÄk3ñ>TÊ$úþÁ q½à 2—ž; 5Ñbu 5ÑÖ¿ :s~Äï DxÞ£Ñ IHe­ Oþz [0ªO ^‰Ó«õ `gt"Þ p/ùáß qkäQ< äa9 Žó›µ µ‡»¬ ·NYˆ‘ ¹çÕ »f©­æ ¾>¾6+ Ô£¥µÍ Õ.‰É„ ë×n=. âéÆ ç)¸¸ ´-¢ {Db ŒÎÔ ô„½r äM½ Ìq 02Î4 >ªso Ckên FÞ$) FøçË~ h¶Þ[ €|I½ …^~ ¼ ˆ²^¼Ê ˜Iœ¡L ¦ÇÄEÅ ®>3×, ®>úk– ®>úî µûÊ# Â$îDë Äí.¯— ÙQ kÐ –Cƒ 餀– óž !֮ؠ $Ð*Í -Ònbè /Ù¾‘Ù 7‡2™r B€^ãÖ OÊÿvú Qù¤PÑ c gäc j:êŽ lS?¨É ¯EÍÍ ³þy² Y1' ¾Yt_x ÍIN@ ÍINœV ÍkNœÏ Ø¡Šj Ø¡ØC Ú¡5Š Þ©5®´ ßN  âË.}F ëÏU×ï ù N úìô]ö 3„q ]·¦3 Õt!… &•ÔØ ±Äã] 3 ¥u¼ 3ïùÕ >¦Jq A_õÒ A®Eì EЧ° NHÞo- OG|M S=UÖ3 X1$} \Õº• hÞ¥Ý q;ž±4 „]3g ‰á‰T¨ ‹÷eÐS ”@¹¬= •IZ!í ˜ÃÚ … žò¾â §0þÀ ´Vôï »swB ÄÓùzi Éʧiº Éä§ÐÈ Ê_—þ^ ÌÎ 2! Ó§þD, Õü¾l9 ÝØòÉ à „¾Q å@~É. Öþ? ˆ¸1 ÎÁÀÎ )}š¾ *ޤ2 *'^ ” *'^¡ò ,jBœ @þJZ… LnEEy `º#» dí›G l>NAÓ tIÃ7 u_Z ‘¥ãBï ’üô¿¥ °út¦~ ÄÈ<VI Ò2u\õ àlÔur áën– æ%w æöørL í:…+n îûôJŸ ðZ<fÇ ùx„´÷ ®GEµ‰˜&pªõB2v¬MÛƒy[¬:Çe>ª"0gDcY[‹mÕÝü©D^à Ä{™ÕHï9õj.óí®d•úªéJ FqÌ c)Ò¹Á/†ý½_Ç|%ãIR*êc«D– wƒVÍiR[L~M[Lz†e'®`iQN$ÖIÞ±Úèõ;‘¢ÑF¨𔾲g› ýjÞœœƒ}ŸŽ»I¤›êàͯê æ‰IéæÔtŽý Þ§ñi!¢H Kann nicht auf SD-Karte zugreifen  SD card is not accessible  AboutDialogJ Kann nicht auf Chipkarte zugreifen  Smartcard is not accessible  AboutDialogL *** Daten werden entfernt... ***' *** Clearing data in progress *** AboutDialog@ *** Verbindungsproblem ***! *** Communication error *** AboutDialogF *** Firmware ist gesperrt *** *** Firmware is locked *** AboutDialogÿÿÿÿ%1 GB AboutDialogB(Nicht mit Zufallsdaten gelöscht)(Not erased with random data) AboutDialog(versteckt)(hidden) AboutDialogV<html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Anleitungen und Hilfe</span></a></p></body></html>«

Instructions and help

 AboutDialogž<html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 durch Nitrokey UG. </span></p><p><span style=" font-size:10pt; font-style:italic;">Diese Software ist unter der </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3</span></a><span style=" font-size:10pt; font-style:italic;"> lizensiert.</span></p><p><a href="https://www.nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html>C

Copyright %1 by NitrokeyUG.

This software is licensed under the GNU General Public License v3.

www.nitrokey.com

 AboutDialog<html><head/><body><p>Dieses Programm dient zum Konfigurieren und Verwenden des Nitrokey Pro und Nitrokey Storage.</p></body></html>

This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.

 AboutDialogT<span style="color:#c80636">Warnung</span>*Warning AboutDialogÜberAbout AboutDialog aktivActive AboutDialogAdministrator:Admin: AboutDialogApp Version: App version: AboutDialogJDialog konnte nicht geöffnet werden: Cannot open dialog:  AboutDialog(Karten-Seriennummer:Card serial number: AboutDialog(Detaillierter StatusDetailed Status AboutDialog0Verschlüsseltes Volumen:Encrypted volume: AboutDialog"Firmware Version:Firmware version: AboutDialog&Versteckte Volumen:Hidden Volume: AboutDialog@Lizenzen und Komponenten Dritter!Licenses and 3rd-party components AboutDialogLogoLogo AboutDialog,Neue SD-Karte gefundenNew SD card found AboutDialog.Kein aktiver Nitrokey No active Nitrokey  AboutDialog\Keine Verbindung Bitte versuchen Sie es erneutNo connection Please retry AboutDialoginaktiv Not active AboutDialogÿÿÿÿOK AboutDialog0Passwort-Eingabe-Zähler:Password retry counters: AboutDialogNUR-LESEN READ ONLY AboutDialogLESEN/SCHREIBEN READ/WRITE AboutDialogÿÿÿÿSD ID: AboutDialogÿÿÿÿStatus AboutDialogrGerät ist nicht sicher! Initialisieren Sie die Schlüssel.&Stick is not secure! Select Init keys. AboutDialogSpeichergröße:Storage Capacity: AboutDialog4Unverschlüsseltes Volumen:Unencrypted volume: AboutDialogBenutzer:User: AboutDialogVFalsche PIN. Bitte versuchen Sie es erneut.Wrong PIN. Please try again.AuthenticationFehlerprotokoll Debug Log DebugDialog Zeichen charsDialogChangePasswordR<html><head/><body><p><span style=" font-style:italic;">Nitrokey schützt gegen Bruteforce-Angriffe, die Passwörter ausprobieren, indem nur 3 falsche PIN-Eingaben erlaubt sind. Dadurch ist eine %1-stellige PIN ausreichend. Die PIN muss zwischen %1 und %2 Zeichen lang sein.</span></p></body></html>

Nitrokey prevents against brute force password guessing attacks by allowing a maximum of 3 incorrect PIN attempts. Therefore a PIN of %1 digits is sufficient. The PIN must be between %1 and %2 characters.

DialogChangePassword0Firmware-Passwort ändernChange Firmware PasswordDialogChangePassword&Ändere Benutzer-PINChange user PINDialogChangePassword(Wiederhole neue PIN:Confirm New PIN:DialogChangePassword4Wiederhole neues Passwort:Confirm New Password:DialogChangePassword:Wiederhole neue Benutzer-PIN:Confirm New User PIN:DialogChangePassword&Aktuelle Admin-PIN:Current Admin PIN:DialogChangePassword8Aktuelles Firmware-Passwort:Current Firmware Password:DialogChangePassword4Aktuelle PIN oder PasswortCurrent PIN or passwordDialogChangePassword,Aktuelle Benutzer-PIN:Current User PIN:DialogChangePasswordzAktuelles Passwort ist falsch. Bitte versuchen Sie es erneut..Current password is not correct. Please retry.DialogChangePassword’Gerät ist noch nicht initialisiert. Bitte versuchen Sie es später erneut.6Device is not yet initialized. Please try again later.DialogChangePassword,Neue PIN oder PasswortNew PIN or passwordDialogChangePasswordNeue PIN:New PIN:DialogChangePasswordNeues Passwort: New Password:DialogChangePassword$Neue Benutzer-PIN: New User PIN:DialogChangePassword8Neues Passwort wurde gesetztNew password is setDialogChangePassword2Benutzer-PIN zurücksetzenReset User PINDialogChangePassword4Anzahl möglicher Versuche:Retry count left:DialogChangePasswordSetze Admin-PIN Set Admin PINDialogChangePassword$Setze Benutzer-PIN Set User PINDialogChangePasswordPIN anzeigenShow PINDialogChangePassword"Passwort anzeigen Show passwordDialogChangePasswordÌDas Firmware-Passwort hat keinen Wiederholungs-Zähler und schützt daher nicht gegen Angriffe, die versuchen das Passwort zu erraten. Ein sicheres und komplexes Passwort sollte erzeugt werden, indem kleine und große Buchstaben, Zahlen und Sonderzeichen mit einer Länge zwischen %2 und %3 Zeichen verwendet werden.<br/>Das standard Firmware-Passwort ist: '%1'.KThe Firmware password doesn’t have a retry counter, and therefore doesn’t prevent against password guessing attacks. A secure and complex password should be created with the use of: lower and upper case letters, numbers and special characters; with a length between %2 and %3 characters.
Default firmware password is: '%1'.DialogChangePassword>Maximale Passwortlänge beträgt $The maximum length of a password is DialogChangePassword>Minimale Passwortlänge beträgt $The minimum length of a password is DialogChangePasswordNMinimale Länge des alten Passworts ist *The minimum length of the old password is DialogChangePasswordjDie neu eingegebenen Passwörter stimmen nicht überein)The new password entries are not the sameDialogChangePasswordîLeider sind keine Eingaben mehr möglich. Bitte lesen Sie die Dokumentation wie die Admin-PIN zurückgesetzt werden kann.aUnfortunately you have no more trials left. Please check instruction how to reset Admin password.DialogChangePasswordøLeider sind keine Eingaben mehr möglich. Bitte nutzen Sie die Option "Reset Benutzer-PIN" im Menü um Ihre PIN zurückzusetzenjUnfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset passwordDialogChangePasswordðWARNUNG! Falls Sie das Firmware-Passwort verlieren, kann der Nitrokey nicht mehr aktualisiert oder zurückgesetzt werden!RWARNING! If you lose your Firmware password, Nitrokey can’t be updated or reset!DialogChangePasswordLLizenz-Informationen (ESC zum Beenden)!License information (ESC to Exit) LicenseDialogŒ(Tipp: Verwenden Sie TOTP für Webseiten und HOTP für lokale Programme)O(Recommendation: Use TOTP for web applications and HOTP for local applications) MainWindow@******************************** ******************************** MainWindowÿÿÿÿ... MainWindow(0000000000000000000000000000000000000000 MainWindow6 Ziffern6 digits MainWindow8 Ziffern8 digits MainWindowP<Wählen Sie einen Passwort-Safe Eintrag> MainWindowD<html><head/><body><p><span style=" font-weight:600; color:#a40000;">Entered OTP 'Secret Key' string is longer than this device supports.</span></p></body></html>¥

Entered OTP 'Secret Key' string is longer than supported by this device

 MainWindowˆ<html><head/><body><p>Hide or show the secret key.</p></body></html>@

Hide or show the secret.

 MainWindowš<html><head/><body><p>Password Safe fields support UTF8 data, allowing you to use multi-national character sets. Please remember that non-English characters could take up more space (up to 4 characters). The counters next to each field show you how many more standard English characters each given field can accept.</p></body></html>X

Password Safe fields support UTF8 data. It means that you can use your national characters here. Please remember however that non-English characters could take more space (up to 4 characters). The counters next to each field are to inform how much more standard English characters can given field accept.

 MainWindowR<html><head/><body><p>The secret key is provided by your service provider, you can login or it can be configured in your local application after login.</p></body></html>¼

The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to.

 MainWindowÿÿÿÿ3AES keys not initialized. Please provide Admin PIN. MainWindowÌAfter generating a random secret, copy it into your application or service where you want to login to.xAfter generating a random secret, you would need to copy it into your application or service where you want to login to. MainWindowÿÿÿÿBase32 MainWindowÿÿÿÿCan't clear slot. MainWindowÿÿÿÿCan't save slot. %1 MainWindow6Password Safe.can't unlock.Can't unlock password safe. MainWindowÿÿÿÿCancel MainWindowÿÿÿÿCharacters left: MainWindowÿÿÿÿ+Command execution failed. Please try again. MainWindow:Configuration was successful.#Configuration successfully written. MainWindow"Device connectingConnecting device MainWindowÿÿÿÿ(Counter must be a value between 0 and %1 MainWindowÔCounter value not copied - there was an error in conversion. Setting counter value to 0. Please try again.fCounter value not copied - there was an error in conversion. Setting counter value to 0. Please retry. MainWindowÿÿÿÿ Details:  MainWindowÿÿÿÿDevice has been locked MainWindowÿÿÿÿ Do nothing MainWindowÿÿÿÿDouble press CapsLock: MainWindowÿÿÿÿDouble press NumLock: MainWindowÿÿÿÿDouble press ScrollLock: MainWindowˆEntered OTP 'Secret Key' string is longer than this device supports.GEntered OTP 'Secret Key' string is longer than supported by this device MainWindowÿÿÿÿErase Password Safe slot MainWindowÿÿÿÿ Erase Slot MainWindowÿÿÿÿError writing configuration! MainWindowÿÿÿÿ-Example: "A3911C05..." (remove any 0x prefix) MainWindowÿÿÿÿExample: "ZR3M5I..." MainWindow|Nitrokey Storage counter must be a value between 0 and 9999999BFor Nitrokey Storage counter must be a value between 0 and 9999999 MainWindowÿÿÿÿfForget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) MainWindowÿÿÿÿGenerate random password MainWindowÿÿÿÿGenerate random password  MainWindow4Generate random secret keyGenerate random secret MainWindowÿÿÿÿHOTP MainWindowÿÿÿÿ HOTP length: MainWindowÿÿÿÿHOTP moving factor seed MainWindowÿÿÿÿ HOTP slot  MainWindowÿÿÿÿHex MainWindowHide secret key Hide secret MainWindowÿÿÿÿ Input format: MainWindowÿÿÿÿ2Keys generated. Please unlock Password Safe again. MainWindowÿÿÿÿ/Label shown when the OTP secret key is too long MainWindowDevice lockingLocking device MainWindowÿÿÿÿ Login name: MainWindowÿÿÿÿMUI part of Token ID MainWindowÿÿÿÿMUI: MainWindowÿÿÿÿ Manage slots MainWindowÿÿÿÿMoving factor seed: MainWindowÿÿÿÿName: MainWindowÿÿÿÿNitrokey Pro connected MainWindowÿÿÿÿ]Nitrokey Pro v0.7 does not support secrets starting from null byte. Please change the secret. MainWindowÿÿÿÿNitrokey Storage connected MainWindowÿÿÿÿNitrokey connected MainWindowÿÿÿÿNitrokey disconnected MainWindowÿÿÿÿNitrokey is not connected! MainWindowöNote: 2<sup>nd</sup> factors are not protected against physical attacks. If Nitrokey has been lost, change all OTP secrets.~Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. MainWindowÔNote: 2nd factors are not protected against physical attacks. If Nitrokey is lost, change all OTP secrets.sNote: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. MainWindowÿÿÿÿOMP part of Token ID MainWindowÿÿÿÿOMP: MainWindowÿÿÿÿ OTP General MainWindowÿÿÿÿOTP Password settings MainWindowÿÿÿÿOTP Slot Configuration MainWindowÿÿÿÿOTP code length: 8 digits MainWindowÿÿÿÿOTP code length: 6 digits MainWindowÿÿÿÿOTP secret key MainWindowÿÿÿÿ/One-time password has been copied to clipboard. MainWindowÿÿÿÿ Parameters MainWindowÿÿÿÿ Password Safe MainWindowÿÿÿÿPassword Safe slot number MainWindowÿÿÿÿPassword safe [%1] MainWindowÿÿÿÿPassword safe unlocked MainWindowÿÿÿÿ Password: MainWindowÿÿÿÿPlease enter a password. MainWindow2Please enter a slot name.Please enter a slotname. MainWindowProtect OTP by user PIN (it will be requested on first use each session)EProtect OTP by user PIN (will be requested on first use each session) MainWindowÿÿÿÿHProvided secret hex string is invalid. Please check input and try again. MainWindowÿÿÿÿReset Nitrokey's time? MainWindowÿÿÿÿSave MainWindowÿÿÿÿ Secret Key: MainWindow<Secret key copied to clipboardSecret copied to clipboard MainWindowÿÿÿÿSecret input format: base32 MainWindowÿÿÿÿSecret input format: hex MainWindowÿÿÿÿ Secret key MainWindowÿÿÿÿSelect OTP slot number MainWindowÿÿÿÿSelect slot type: HOTP MainWindowÿÿÿÿSelect slot type: TOTP MainWindowFPress 'enter' as the last keystroke"Send 'enter' as the last keystroke MainWindowÿÿÿÿ Send HOTP1 MainWindowÿÿÿÿ Send HOTP2 MainWindowÿÿÿÿ Send token ID MainWindowÿÿÿÿ Set HOTP counter to random value MainWindowÿÿÿÿSet HOTP counter to zero MainWindowÿÿÿÿ Set to random MainWindowÿÿÿÿ Set to zero MainWindowÿÿÿÿQSettings for inserting HOTP code through special key shortcut (USB-Keyboard only) MainWindowÿÿÿÿSlot  MainWindowDSlot has been successfully erased."Slot has been erased successfully. MainWindow:Slot has been erased already.Slot is erased already. MainWindowÿÿÿÿ Slot name MainWindowÿÿÿÿ Slot name: MainWindowÿÿÿÿSlot successfully written. MainWindowÿÿÿÿSlot: MainWindowÿÿÿÿStatic password 0 MainWindowÿÿÿÿTOTP MainWindowÿÿÿÿTOTP interval value MainWindowÿÿÿÿTOTP interval: MainWindowÿÿÿÿ TOTP length: MainWindowÿÿÿÿ TOTP slot  MainWindowÿÿÿÿTT part of Token ID MainWindowÿÿÿÿTT: MainWindowÿÿÿÿ9The Nitrokey App is available as an icon in the tray bar. MainWindowThe secret key is provided by your service provider, you can login or it can be configured in your local application after login.”The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to. MainWindowŠThe secret string you have entered is invalid. Please enter it again.AThe secret string you have entered is invalid. Please reenter it. MainWindowÿÿÿÿTime is out-of-sync MainWindowÿÿÿÿ Time reset! MainWindowÐTo handle this functionality the application will keep your user PIN in memory. Do you want to continue?dTo handle this functionality application will keep your user PIN in memory. Do you want to continue? MainWindowÿÿÿÿToken ID MainWindowÿÿÿÿUnlock Password Safe MainWindowÿÿÿÿUnlock password safe MainWindowÿÿÿÿUser not authenticated MainWindowFWARNING! The time on your computer and Nitrokey are out of sync. Your computer may be configured with the wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords immediately. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time?•WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? MainWindowdWARNING: Are you sure you want to erase this slot?1WARNING: Are you sure you want to erase the slot? MainWindowºWARNING: Encrypted volume is not secure, Select "Initialize device" option from context menu.]Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. MainWindowªWARNING: Encrypted volume is not secure, Select "Initialize storage with random data"UWarning: Encrypted volume is not secure, Select "Initialize storage with random data" MainWindowÿÿÿÿWrong PIN. Please try again. MainWindowÿÿÿÿWrong admin password. MainWindowWrong user PIN.Wrong user password. MainWindowÿÿÿÿ1Your secret is invalid. Please change the secret. MainWindowBSecret is not passing validation.!secret is not passing validation. MainWindowÿÿÿÿ&Cancel PinDialogÿÿÿÿ&OK PinDialogÿÿÿÿ Admin PIN: PinDialogÿÿÿÿ6Device is not yet initialized. Please try again later. PinDialogÿÿÿÿEnter Firmware Password PinDialogÿÿÿÿEnter Firmware Password: PinDialogÿÿÿÿEnter admin PIN PinDialogÿÿÿÿEnter card PIN PinDialogÿÿÿÿEnter card password: PinDialogÿÿÿÿ Enter password for hidden volume PinDialogÿÿÿÿ!Enter password for hidden volume: PinDialogÿÿÿÿEnter user PIN PinDialogÿÿÿÿPassword dialog PinDialog"Show PIN/password Show password PinDialog"Attempts left: %1Tries left: %1 PinDialogÿÿÿÿ User PIN: PinDialoghWARNING: Default PIN is used. Please change the PIN.4Warning: Default PIN is used. Please change the PIN. PinDialog8Would you like to do so now?Would you like to so now? PinDialogrYour PIN is too long! Please use less than 30 characters.6Your PIN is too long! Use not more than 30 characters. PinDialogpYour PIN is too short! Please use at least 6 characters.1Your PIN is too short. Use at least 6 characters. PinDialogÿÿÿÿACritical error encountered. Please restart application. Message:  QApplicationÿÿÿÿProgressStick20ResponseDialogÿÿÿÿ'Cannot set unencrypted volume read-onlyStorageActionsÿÿÿÿ(Cannot set unencrypted volume read-writeStorageActionsÿÿÿÿCommunication issue.StorageActionsÿÿÿÿCould not clear SD card.StorageActionsDCould not unlock encrypted volume."Could not enable encrypted volume.StorageActions>Could not unlock hidden volume.Could not enable hidden volume.StorageActionsÿÿÿÿCould not export firmware.StorageActionsÿÿÿÿCould not lock device.StorageActionsÿÿÿÿ Could not lock encrypted volume.StorageActionsÿÿÿÿCould not lock hidden volume.StorageActionsÿÿÿÿ'Device could not be set in update mode.StorageActionsÿÿÿÿ Device lockedStorageActionsÿÿÿÿDevice set in update modeStorageActions0Locking encrypted volumeDisabling encrypted volumeStorageActions*Locking hidden volumeDisabling hidden volumeStorageActions4Unlocking encrypted volumeEnabling encrypted volumeStorageActions.Unlocking hidden volumeEnabling hidden volumeStorageActions.Encrypted volume lockedEncrypted volume disabledStorageActions2Encrypted volume unlockedEncrypted volume enabledStorageActionsrFirmware exported to unencrypted volume as 'firmware.bin'Firmware exportedStorageActionsÿÿÿÿFlag cannot be cleared.StorageActionsÿÿÿÿ Flag cleared.StorageActionsÿÿÿÿ0Functionality not implemented in current versionStorageActionsÿÿÿÿGenerating new AES keysStorageActionsÿÿÿÿ#Hidden volume could not be created.StorageActionsÿÿÿÿHidden volume createdStorageActions(Hidden volume lockedHidden volume disabledStorageActions,Hidden volume unlockedHidden volume enabledStorageActionsÿÿÿÿKeys could not be generated.StorageActionsÿÿÿÿLocking deviceStorageActionsÿÿÿÿNew AES keys generatedStorageActionsRPlease unlock the encrypted volume first.)Please enable the encrypted volume first.StorageActionsÿÿÿÿStatus code: %1StorageActionsÿÿÿÿ‡This activity locks your encrypted volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding.StorageActionsÿÿÿÿ„This activity locks your hidden volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding.StorageActionsÿÿÿÿ Unencrypted volume set read-onlyStorageActionsÿÿÿÿ!Unencrypted volume set read-writeStorageActionsÿÿÿÿqWARNING: Generating new AES keys will destroy the encrypted volumes, hidden volumes, and password safe! Continue?StorageActionsWrong PIN.Wrong password.StorageActionsÿÿÿÿ&About NitrokeyTrayÿÿÿÿ&Change Admin PINTrayÿÿÿÿ&Change Firmware PasswordTrayÿÿÿÿ&Change User PINTrayÿÿÿÿ&DebugTrayÿÿÿÿ&Destroy encrypted dataTrayÿÿÿÿ6&Disable 'initialize storage with random data' warningTrayÿÿÿÿ&Enable firmware updateTrayÿÿÿÿ&Export firmware to fileTrayÿÿÿÿ&Factory resetTray &Help&HelpTrayÿÿÿÿ&Initialize deviceTrayÿÿÿÿ$&Initialize storage with random dataTrayÿÿÿÿ &Lock DeviceTrayÿÿÿÿ&Lock encrypted volumeTrayÿÿÿÿ&Lock hidden volumeTray*&Lock device hardware&Lock stick hardwareTrayÿÿÿÿ&OTPTrayÿÿÿÿ&OTP and Password safeTrayÿÿÿÿ&QuitTrayÿÿÿÿ&Reset User PINTrayH&Set unencrypted volume to read-only!&Set unencrypted volume read-onlyTrayJ&Set unencrypted volume to read-write"&Set unencrypted volume read-writeTrayÿÿÿÿ&Setup hidden volumeTrayÿÿÿÿ&Unlock encrypted volumeTrayÿÿÿÿ&Unlock hidden volumeTrayÿÿÿÿ(empty)TrayÿÿÿÿActiveTrayÿÿÿÿActive (debug mode)Trayÿÿÿÿ ConfigureTrayÿÿÿÿLong operation in progress: %1%Trayÿÿÿÿ PasswordsTrayÿÿÿÿ"Smartcard or SD card are not readyTrayÿÿÿÿSpecial ConfigureTrayÿÿÿÿUnlock password safeTray2<html><head/><body><p>When you select &quot;OK&quot; the device enters into <br/>firmware update mode. There is no way back!<br/>Please read the <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;">documentation </span></a>on how to <br/>update the firmware.</p><p>Continue entering the firmware update mode?</p><p><br/></p></body></html>•

When you select "OK" the device enters the
firmware update mode. There is no way back!
Please read the documentation how to
update the firmware.

Continue entering the firmware update mode?


 UpdateDialogÿÿÿÿFirmware update UpdateDialogÿÿÿÿEnable debug messagesmainÿÿÿÿ%Enable extra administrative functionsmainÿÿÿÿList available languagesmainÿÿÿÿMLoad translation file with given name and store this choice in settings file.mainVNitrokey App - Manage your Nitrokey devices*Nitrokey App - Manage your Nitrokey sticksmainÿÿÿÿ-Save debug log to App's window (experimental)mainÿÿÿÿ?Save debug log to file with name (experimental)mainÿÿÿÿSet debug level, 0-4mainÿÿÿÿmainÿÿÿÿ(Show additional information about binarymainì<html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Security Information</span></p><p>Please read the following carefully.</p><p><span style=" font-weight:600;">PIN Protection</span></p><p>Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.</p><p><span style=" font-weight:600;">Physical Protection</span></p><p>All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.</p><p><span style=" font-weight:600;">Hidden Volumes</span></p><p>Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are, however, stored on flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.</p></body></html>v

Security Information

Please read the following carefully.

PIN Protection

Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.

Physical Protection

All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.

Hidden Volumes

Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are however stored on a flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.

securitydialogÿÿÿÿDialogsecuritydialog`I have read and understood this security warning+I read and understood this security warningsecuritydialogÿÿÿÿOKsecuritydialogÿÿÿÿ%stick20HiddenVolumeDialog~<html><head/><body><p>1. You may want to copy some sensitive files to the hidden volume.<br/>2. Configure hidden volumes in this dialogue. <br/>3. Once you have configured a hidden volume you must not use/write to the encryption volume anymore, otherwise it may destroy the data in your hidden volume.</p></body></html>;

1. You may want to copy some innocuous files to the encrypted data.
2. Configure hidden volumes in this dialogue.
3. Once you configured a hidden volume you must not use/write to the encryption volume anymore. Otherwise it may destroy the data in your hidden volume.

stick20HiddenVolumeDialogÿÿÿÿ¤

You should understand the properties of hidden volumes before proceeding. It can destroy your encrypted data!
Please read
these instructions first.

stick20HiddenVolumeDialogÿÿÿÿ1End hidden volume at %1 of the encrypted storage:stick20HiddenVolumeDialogÿÿÿÿGBstick20HiddenVolumeDialogÿÿÿÿHidden Volume settingsstick20HiddenVolumeDialogÿÿÿÿrHidden volume not positioned in unwritten space. Please set your volume between %1% and %2% of total SD card size.stick20HiddenVolumeDialogÿÿÿÿHidden volume passwordstick20HiddenVolumeDialogÿÿÿÿ!Hidden volume password (repeated)stick20HiddenVolumeDialogÿÿÿÿHidden volume slot 1stick20HiddenVolumeDialogÿÿÿÿHidden volume slot 2stick20HiddenVolumeDialogÿÿÿÿHidden volume slot 3stick20HiddenVolumeDialogÿÿÿÿHidden volume slot 4stick20HiddenVolumeDialogÿÿÿÿMBstick20HiddenVolumeDialogÿÿÿÿMediumstick20HiddenVolumeDialogÿÿÿÿPassword settingsstick20HiddenVolumeDialogÿÿÿÿPassword strength:stick20HiddenVolumeDialogÿÿÿÿ Password:stick20HiddenVolumeDialogÿÿÿÿ2Please use shift+tab key shortcut for instructionsstick20HiddenVolumeDialogÿÿÿÿSetup hidden volumestick20HiddenVolumeDialogShow password Show passwordstick20HiddenVolumeDialogÿÿÿÿJSize will be rounded down to integral percent of total storage size (%1MB)stick20HiddenVolumeDialogÿÿÿÿ9Slot under which hidden volume information will be storedstick20HiddenVolumeDialogÿÿÿÿ3Start hidden volume at %1 of the encrypted storage:stick20HiddenVolumeDialogÿÿÿÿStorage capacity: %1GBstick20HiddenVolumeDialogÿÿÿÿStrongstick20HiddenVolumeDialogÿÿÿÿThe passwords are not identicalstick20HiddenVolumeDialogÿÿÿÿ[The unwritten area available for hidden volume is between %1 % and %2 % of the storage sizestick20HiddenVolumeDialogÿÿÿÿUnit:stick20HiddenVolumeDialogÿÿÿÿ#Use this as hidden volume size unitstick20HiddenVolumeDialogÿÿÿÿ Very Strongstick20HiddenVolumeDialogÿÿÿÿ Very Weakstick20HiddenVolumeDialogÿÿÿÿWeakstick20HiddenVolumeDialogÿÿÿÿWrong size of hidden volumestick20HiddenVolumeDialogzYour password is too short! Please use at least 8 characters.6Your password is too short. Use at least 8 characters.stick20HiddenVolumeDialogÿÿÿÿlengthstick20HiddenVolumeDialogÿÿÿÿ lower casestick20HiddenVolumeDialogÿÿÿÿnumbersstick20HiddenVolumeDialogÿÿÿÿsymbolsstick20HiddenVolumeDialogÿÿÿÿ upper casestick20HiddenVolumeDialogR<html><head/><body><p>When you select &quot;OK&quot; the device will lock the firmware and close the hardware debug port.This disables any external hardware access to the data on the device (processor).</p><p>There is no way back! </p><p>After this you can't update the firmware.</p></body></html>#

When you select "OK" the stick lock the firmware and close the hardware debug port.This disables any external hardware access to the data in the device (processor).

There is no way back!

After this you can't update the firmware.

stick20LockFirmwareDialogÿÿÿÿ Lock Firmwarestick20LockFirmwareDialogˆnitrokey-app-1.3.2/i18n/nitrokey_en.ts0000644000175000017500000020630613404176655017200 0ustar janjan00000000000000 AboutDialog About <html><head/><body><p>This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.</p></body></html> <html><head/><body><p>This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.</p></body></html> App version: Firmware version: Card serial number: <html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 by NitrokeyUG. </span></p><p><span style=" font-size:10pt; font-style:italic;">This software is licensed under the </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3</span></a><span style=" font-size:10pt; font-style:italic;">.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html> <html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 by Nitrokey UG. </span></p><p><span style=" font-size:10pt; font-style:italic;">This software is licensed under the </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3</span></a><span style=" font-size:10pt; font-style:italic;">.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html> <html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Instructions and help</span></a></p></body></html> Status Hidden Volume: <span style="color:#c80636">Warning</span> <span style="color:#c80636">WARNING</span> Stick is not secure! Select Init keys. Device is not secure! Select Init keys. New SD card found (Not erased with random data) (Device not erased with random data) SD ID: Unencrypted volume: Encrypted volume: Password retry counters: PIN retry counters: Admin: Logo User: Detailed Status OK SD card is not accessible SD card is inaccessible Smartcard is not accessible Smartcard is inaccessible No connection Please retry No connection Please try again READ/WRITE READ ONLY Active (hidden) Not active No active Nitrokey Nitrokey is not active Storage Capacity: %1 GB Licenses and 3rd-party components *** Clearing data in progress *** *** Communication error *** *** Firmware is locked *** Cannot open dialog: Authentication Wrong PIN. Please try again. DebugDialog Debug Log DialogChangePassword Change user PIN Show PIN Retry count left: PIN attempts left: Change Firmware Password Unfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset password Unfortunately you have no more attempts left. Please use 'Reset User PIN' option from menu to reset PIN Unfortunately you have no more trials left. Please check instruction how to reset Admin password. Unfortunately you have no more attempts left. Please check the instructions on how to reset the Admin PIN. Set User PIN Current User PIN: New User PIN: Set Admin PIN Current Admin PIN: Reset User PIN Current Firmware Password: Show password Show password Current password is not correct. Please retry. Current PIN is not correct. Please try again. New password is set New PIN is set The minimum length of the old password is The minimum length of the old PIN/password is chars The maximum length of a password is The maximum length of a PIN/password is The minimum length of a password is The minimum length of a PIN/password is Device is not yet initialized. Please try again later. The new password entries are not the same Current PIN or password New PIN or password <html><head/><body><p><span style=" font-style:italic;">Nitrokey prevents against brute force password guessing attacks by allowing a maximum of 3 incorrect PIN attempts. Therefore a PIN of %1 digits is sufficient. The PIN must be between %1 and %2 characters.</span></p></body></html> New PIN: Confirm New PIN: Confirm New User PIN: New Password: Confirm New Password: The Firmware password doesn’t have a retry counter, and therefore doesn’t prevent against password guessing attacks. A secure and complex password should be created with the use of: lower and upper case letters, numbers and special characters; with a length between %2 and %3 characters.<br/>Default firmware password is: '%1'. WARNING! If you lose your Firmware password, Nitrokey can’t be updated or reset! LicenseDialog License information (ESC to Exit) MainWindow OTP Slot Configuration Manage slots TOTP HOTP Slot: Erase Slot Name: Secret key <html><head/><body><p>The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to.</p></body></html> <html><head/><body><p>The secret key is provided by your service provider, you can login or it can be configured in your local application after login.</p></body></html> Secret Key: ******************************** Secret copied to clipboard Secret key copied to clipboard <html><head/><body><p>Hide or show the secret.</p></body></html> <html><head/><body><p>Hide or show the secret key.</p></body></html> Hide secret Hide secret key Generate random secret Generate random secret key Input format: Hex Note: 2<sup>nd</sup> factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. Note: 2<sup>nd</sup> factors are not protected against physical attacks. If Nitrokey has been lost, change all OTP secrets. Parameters Set to zero Set to random 6 digits 8 digits Moving factor seed: HOTP length: TOTP interval: Token ID Send token ID MUI: TT: OMP: Cancel Save (Recommendation: Use TOTP for web applications and HOTP for local applications) Base32 Send 'enter' as the last keystroke Press 'enter' as the last keystroke 00000000000000000000 OTP General OTP Password settings Double press NumLock: Double press CapsLock: Double press ScrollLock: Do nothing Send HOTP1 Send HOTP2 Password Safe Password: Login name: Slot name: Static password 0 Generate random password Characters left: ... <html><head/><body><p>Password Safe fields support UTF8 data. It means that you can use your national characters here. Please remember however that non-English characters could take more space (up to 4 characters). The counters next to each field are to inform how much more standard English characters can given field accept.</p></body></html> <html><head/><body><p>Password Safe fields support UTF8 data, allowing you to use multi-national character sets. Please remember that non-English characters could take up more space (up to 4 characters). The counters next to each field show you how many more standard English characters each given field can accept.</p></body></html> Unlock password safe Nitrokey disconnected Nitrokey Pro connected Nitrokey Storage connected Counter value not copied - there was an error in conversion. Setting counter value to 0. Please retry. Counter value not copied - there was an error in conversion. Setting counter value to 0. Please try again. TOTP length: Wrong PIN. Please try again. Wrong Pin. Please try again. Factory reset was successful. Device has been locked Counter must be a value between 0 and %1 For Nitrokey Storage counter must be a value between 0 and 9999999 Nitrokey Storage counter must be a value between 0 and 9999999 Please enter a slotname. Please enter a slot name. Configuration successfully written. Configuration was successful. Error writing configuration! Nitrokey is not connected! One-time password has been copied to clipboard. WARNING: Are you sure you want to erase the slot? WARNING: Are you sure you want to erase this slot? Slot has been erased successfully. Slot has been successfully erased. Slot Can't clear slot. Slot is erased already. Slot has been erased already. Please enter a password. Can't save slot. %1 Generate random password Time is out-of-sync WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? WARNING! The time on your computer and Nitrokey are out of sync. Your computer may be configured with the wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords immediately. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? Time reset! Nitrokey connected Warning: Encrypted volume is not secure, Select "Initialize storage with random data" WARNING: Encrypted volume is not secure, Select "Initialize storage with random data" TOTP slot HOTP slot Can't unlock password safe. Password Safe.can't unlock. Wrong user password. Wrong user PIN. Password safe [%1] Protect OTP by user PIN (will be requested on first use each session) Protect OTP by user PIN (it will be requested on first use each session) Forget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) Command execution failed. Please try again. To handle this functionality application will keep your user PIN in memory. Do you want to continue? To handle this functionality the application will keep your user PIN in memory. Do you want to continue? Nitrokey Pro v0.7 does not support secrets starting from null byte. Please change the secret. Your secret is invalid. Please change the secret. Slot successfully written. Select slot type: TOTP Select slot type: HOTP Select OTP slot number Slot name The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to. The secret key is provided by your service provider, you can login or it can be configured in your local application after login. OTP secret key Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. Note: 2nd factors are not protected against physical attacks. If Nitrokey is lost, change all OTP secrets. After generating a random secret, you would need to copy it into your application or service where you want to login to. After generating a random secret, copy it into your application or service where you want to login to. Example: "ZR3M5I..." Secret input format: base32 Example: "A3911C05..." (remove any 0x prefix) Secret input format: hex Entered OTP 'Secret Key' string is longer than supported by this device Entered OTP 'Secret Key' string is longer than this device supports. Label shown when the OTP secret key is too long HOTP moving factor seed Set HOTP counter to zero Set HOTP counter to random value OTP code length: 6 digits OTP code length: 8 digits TOTP interval value OMP part of Token ID TT part of Token ID MUI part of Token ID Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Erase Password Safe slot Password Safe slot number Unlock Password Safe The Nitrokey App is available as an icon in the tray bar. The secret string you have entered is invalid. Please reenter it. The secret string you have entered is invalid. Please enter it again. <Select Password Safe slot> Password safe unlocked AES keys not initialized. Please provide Admin PIN. Keys generated. Please unlock Password Safe again. Wrong admin password. User not authenticated Reset Nitrokey's time? Locking device Device locking Connecting device Device connecting <html><head/><body><p><span style=" font-weight:600; color:#a40000;">Entered OTP 'Secret Key' string is longer than supported by this device</span></p></body></html> Label shown when the OTP secret key is too long <html><head/><body><p><span style=" font-weight:600; color:#a40000;">Entered OTP 'Secret Key' string is longer than this device supports.</span></p></body></html> secret is not passing validation. Secret is not passing validation. Provided secret hex string is invalid. Please check input and try again. Details: WARNING: This Storage firmware version is old. Application may be unresponsive and unlocking encrypted volume may not work. Please update the firmware to the latest version. Guide should be available at: <br/><a href='https://www.nitrokey.com/en/doc/firmware-update-storage'>www.nitrokey.com/en/doc/firmware-update-storage</a>. Nitrokey App Overview Unlock Encrypted Volume Unlock Hidden Volume Lock Device Help Quit Copy secret to clipboard Copy to clipboard Settings General Show first-run message Show warning when no partitions could be detected on Encrypted Volume (Linux only) Show message about device's connection / disconnection Show main window when device connects Hide main window when device disconnects Do not quit when the main window is closed <html><head/><body><p>Translation file (needs restart)</p></body></html> Translation file (needs restart) Debug log settings Path for debug log file: Verbosity level: Select path Logging enabled Log to console Clipboard settings Time to store OTP secrets in clipboard (in seconds): Time to store Password Safe secrets in clipboard (in seconds): TIme to store Password Safe secrets in clipboard (in seconds): You can find application’s tray icon in system tray in the right down corner of your screen (Windows) or in the upper right (Linux, MacOS). Idle Would you like to show this message again? Device lock detected, please remove and insert the device again. If problem will occur again please: 1. Close the application 2. Reinsert the device 3. Wait 30 seconds and start application Warning: Application could not detect any partition on the Encrypted Volume. Please use graphical GParted or terminal fdisk/parted tools for this. Would you like to be reminded again? Device connected. Waiting for initialization... Please run the application again to apply new settings. Would you like to quit now? Debug file location (will be overwritten) current: Communication error. Please reinsert the device. Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. WARNING: Encrypted volume is not secure, Select "Initialize device" option from context menu. PinDialog Password dialog Enter card password: Show password Show PIN/password &Cancel &OK Your PIN is too long! Use not more than 30 characters. Your PIN is too long! Please use less than 30 characters. Your PIN is too short. Use at least 6 characters. Your PIN is too short! Please use at least 6 characters. Warning: Default PIN is used. Please change the PIN. WARNING: Default PIN is used. Please change the PIN. Tries left: %1 Attempts left: %1 Device is not yet initialized. Please try again later. Enter card PIN Enter user PIN User PIN: Enter admin PIN Admin PIN: Enter Firmware Password Enter Firmware Password: Enter password for hidden volume Enter password for hidden volume: Would you like to so now? Would you like to do so now? Please enter the new PIN/password QApplication Critical error encountered. Please restart application. Message: Stick20ResponseDialog Progress StorageActions This activity locks your hidden volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding. Enabling encrypted volume Unlocking encrypted volume Encrypted volume enabled Encrypted volume unlocked Could not enable encrypted volume. Could not unlock encrypted volume. Wrong password. Wrong PIN. Status code: %1 This activity locks your encrypted volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding. Disabling encrypted volume Locking encrypted volume Encrypted volume disabled Encrypted volume locked Could not lock encrypted volume. Please enable the encrypted volume first. Please unlock the encrypted volume first. Enabling hidden volume Unlocking hidden volume Hidden volume enabled Hidden volume unlocked Could not enable hidden volume. Could not unlock hidden volume. Disabling hidden volume Locking hidden volume Hidden volume disabled Hidden volume locked Could not lock hidden volume. Locking device Device locked Could not lock device. Device set in update mode Device could not be set in update mode. Firmware exported Firmware exported to unencrypted volume as 'firmware.bin' Could not export firmware. WARNING: Generating new AES keys will destroy the encrypted volumes, hidden volumes, and password safe! Continue? Generating new AES keys New AES keys generated Keys could not be generated. Could not clear SD card. Communication issue. Flag cannot be cleared. Flag cleared. Cannot set unencrypted volume read-only Unencrypted volume set read-only Cannot set unencrypted volume read-write Unencrypted volume set read-write Cannot set encrypted volume read-only Encrypted volume set read-only Cannot set encrypted volume read-write Encrypted volume set read-write Functionality not implemented in current version Hidden volume created Hidden volume could not be created. To complete the lock procedure, please remove and reconnect the Nitrokey. Tray Active (debug mode) Active Nitrokey is not connected! Unlock password safe &OTP &Factory reset &Change User PIN &Change Admin PIN &Debug &Quit &Help &Help &About Nitrokey &OTP and Password safe &Unlock encrypted volume &Lock encrypted volume &Unlock hidden volume &Lock hidden volume &Change Firmware Password &Enable firmware update &Export firmware to file &Destroy encrypted data &Initialize device &Initialize storage with random data &Set unencrypted volume read-only &Set unencrypted volume to read-only &Set unencrypted volume read-write &Set unencrypted volume to read-write &Set encrypted volume read-only &Set encrypted volume read-write &Setup hidden volume &Disable 'initialize storage with random data' warning &Lock stick hardware &Lock device hardware &Reset User PIN &Lock Device Smartcard or SD card are not ready Passwords (empty) Configure Special Configure Long operation in progress: %1% &Overview UpdateDialog Firmware update <html><head/><body><p>When you select &quot;OK&quot; the device enters the <br/>firmware update mode. There is no way back!<br/>Please read the <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;">documentation </span></a>how to <br/>update the firmware.</p><p>Continue entering the firmware update mode?</p><p><br/></p></body></html> <html><head/><body><p>When you select &quot;OK&quot; the device enters into <br/>firmware update mode. There is no way back!<br/>Please read the <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;">documentation </span></a>on how to <br/>update the firmware.</p><p>Continue entering the firmware update mode?</p><p><br/></p></body></html> main Nitrokey App - Manage your Nitrokey sticks Nitrokey App - Manage your Nitrokey devices Enable debug messages Save debug log to file with name <log-file-name> (experimental) Save debug log to App's window (experimental) Set delay between commands sent to device (in ms) to <delay> Show additional information about binary Enable extra administrative functions List available languages Load translation file with given name and store this choice in settings file. Set debug level, 0-4 Clear all application's settings securitydialog Dialog <html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Security Information</span></p><p>Please read the following carefully.</p><p><span style=" font-weight:600;">PIN Protection</span></p><p>Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.</p><p><span style=" font-weight:600;">Physical Protection</span></p><p>All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.</p><p><span style=" font-weight:600;">Hidden Volumes</span></p><p>Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are however stored on a flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.</p></body></html> <html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Security Information</span></p><p>Please read the following carefully.</p><p><span style=" font-weight:600;">PIN Protection</span></p><p>Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.</p><p><span style=" font-weight:600;">Physical Protection</span></p><p>All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.</p><p><span style=" font-weight:600;">Hidden Volumes</span></p><p>Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are, however, stored on flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.</p></body></html> OK I read and understood this security warning I have read and understood this security warning stick20HiddenVolumeDialog Setup hidden volume <html><head/><body><p><span style=" font-weight:600;">You should understand the properties of hidden volumes before proceeding. It can destroy your encrypted data! <br/>Please read </span><a href="https://www.nitrokey.com/documentation/hidden-volumes"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">these instructions</span></a><span style=" font-weight:600;"> first.</span></p></body></html> <html><head/><body><p>1. You may want to copy some innocuous files to the encrypted data.<br/>2. Configure hidden volumes in this dialogue. <br/>3. Once you configured a hidden volume you must not use/write to the encryption volume anymore. Otherwise it may destroy the data in your hidden volume.</p></body></html> <html><head/><body><p>1. You may want to copy some sensitive files to the hidden volume.<br/>2. Configure hidden volumes in this dialogue. <br/>3. Once you have configured a hidden volume you must not use/write to the encryption volume anymore, otherwise it may destroy the data in your hidden volume.</p></body></html> Password settings Password strength: length lower case upper case numbers symbols Hidden Volume settings Hidden volume slot 1 Hidden volume slot 2 Hidden volume slot 3 Hidden volume slot 4 Password: Show password Show password Your password is too short. Use at least 8 characters. Your password is too short! Please use at least 8 characters. The passwords are not identical Wrong size of hidden volume Unit: % MB GB Hidden volume not positioned in unwritten space. Please set your volume between %1% and %2% of total SD card size. Very Weak Weak Medium Strong Very Strong The unwritten area available for hidden volume is between %1 % and %2 % of the storage size Storage capacity: %1GB Start hidden volume at %1 of the encrypted storage: End hidden volume at %1 of the encrypted storage: Hidden volume password Please use shift+tab key shortcut for instructions Hidden volume password (repeated) Slot under which hidden volume information will be stored Use this as hidden volume size unit Size will be rounded down to integral percent of total storage size (%1MB) stick20LockFirmwareDialog Lock Firmware <html><head/><body><p>When you select &quot;OK&quot; the stick lock the firmware and close the hardware debug port.This disables any external hardware access to the data in the device (processor).</p><p>There is no way back! </p><p>After this you can't update the firmware.</p></body></html> <html><head/><body><p>When you select &quot;OK&quot; the device will lock the firmware and close the hardware debug port.This disables any external hardware access to the data on the device (processor).</p><p>There is no way back! </p><p>After this you can't update the firmware.</p></body></html> nitrokey-app-1.3.2/i18n/nitrokey_fr.qm0000644000175000017500000020153613314460010017151 0ustar janjan00000000000000<¸dÊÍ!¿`¡½ÝB È%Õ’²àsæ; ;Õm+;|N1(NÈF§YzgÉ7Z|o´¥ÛÔEZ)ÊIpB:R”eó˜Å[Û{ð´$%(4²Ì+Œ¦9ôOZD$äCúG=ŠHÍG–ÄME^ƒ…TƒŠJlYÙ vZ6`büZ6zeW\Pzï$\œZ!kØ%Ž&qqOpeví›Ãyþ´Áæ"]> Ð³6´ÖˆÓ·î® ξñU§ÉÄ•š(ÍbV/íÿþXÄïØ~*ƒRè®X娄$d}+Ûu¥^-Däã \Q´]\Q´Á\Q´é#\œš3_;”[u_*Æ{÷~ÕÁ‰jþ‹ˆþŸÏÐ{ôL®Ö€éAfâ)TošõôÊiÐÑ?ŽT^º ‰¼ u¤úk>Ú:9”BA ;k³´L@j~ BqcI“DÆO`ßGçSzJìTQ³Y5ÅeQuïiè“.}Âðg"ðF\„)Óæ€„PÞS“FDï™Ùufª¹· .¬áÑä"¬áÒ䞬áÓå¬áÔå–³å4LÊÔù:ÌÉY%ïö(ŠúÑZ=,Î5HrÎ5•++–‚$30(3P®ñƒTÁÊߤk“169…VŽ8ˆýnGaÇNw+ç¶Z§í %øúLYI D[/u*2BN`Dspµ! _z°ÅNz°Å©î{@‚ˆ˜b5 ˜I¼7y¯ƒWÔ–¹h¥¨çÈrŽ{eϦåª{²à]Éòà^R ‡:˜$§5Žš;9®c8;°½æB=Fsà£QNÀ nXž¦¯X4ždeu‰œn_7<énÞþóÛoFžŒ)vMz)†‰¥¡Ä¡ê¿v_§Žg몋Ã]«–Gìè«Ç >¸°j‚¿ (ÜÂíu^ÛÃŒãòÿÈ9T{ѯŠÞÉ’qëF0e•÷]÷ð¥¢Hgé¹Ödn©–E¤B'ˆ¥¤AÏDoêJÕq_jJÕr_­TÉJÒUª€y`ëNJûgd=hLΚpxÊE}qàêd€¥Ì¯ã(¡¯ã3(fÓÚIêÞ¼N"’áasSõñ>ts}ô¢Íîžå!hˆR%£¾w,N¨òk0xÊfÓ3ÄÞïGç~T¼IÕß[Ðõ+ˆ\ªu¯ß¾‹•Ð=ž„WÕR´FÉןlÐä`n”¬ñNÀà ©·lãÚÈ5“³¤6èµù9ÄU„`šNâg§®2óu*ûƒ£—ŒÚŠ fdEЯ)«èÄ i\ýȇéã‰ÊÄW`ñ>TŸKúþ— q“é 2—ž0< 5ÑM_ 5Ñ«7 DxÞ~¨ Oþz [0ª=Ÿ ^‰Ó† `gtò p/ù¶ˆ qkä?; äLA µ‡»ðg ¹çß »f©†J ¾>¾)œ Ô£¥« Õ.‰ž“ âé› ´$< {DM ŒÎ{ ô„“} Ìí$ Ckêå FÞ5 Føç Í ˆ²^’í ˜Iœ| ®>3«¬ ®>úX ®>úça Â$î9V Äí.‡ë –CóD é¤gm óžá !Ö®­V $Ð! -ÒnMÚ 7‡2x¥ B€^¸ë OÊÿaŽ Qù¤>Œ cíÁ gäcâ j:êæó ¯E£D Y&– ¾YtJš ÍIN` ÍINz Ø¡o] Ø¡¬Ï Ú¡5nÐ Þ©5‡ ßN 2 âË.dâ ëÏU¬y ù N úìôI 3l` ]·f &•©X ±Ä¸r 3 ¥`B 3ïùª >¦J[9 A_õó‰ A®Eò¯ EŠ‚t OGcÇ S=Uª± X1¥ hÞ q;ž‰f „]3R ‰á‰Ba ‹÷e¦ žò¾hý §0þ– ´Vôê¦ Ê_—Ô¿ ÌÎ 'Ð Ó§þ8Ÿ Õü¾XO ÝØòìn à „”N å@~ž7 Öþ3ÿ ˆç ÎÁ–Ç *Ž *'^¡ *'^|¿ ,j7¬ @þJG LnE9ì `ºÛ l>N6¿ tIÃç´ u_Zâ ’üô•Š àlÔ_ð æöø\Š í:…!Ø îûô<„ ðZ<R5 ùx„ŒÛ ®:÷&p…B2aP[¬:f~‹mղΩD^™#Ä{™©Âï9õUÁóí®O× F\ c)§Á/m4½_œ“*êc•D– aÒVÍi@Ge'®z˜iQNIÞ‰òèõðò‘¢Ñ:Bš”¾Š}› ýV㜜k<ŸŽ‘F¤›êë›ͯêræ‰IéŒæÔtïeý Þ‚½iøuF La carte SD n'est pas accessible  SD card is not accessible  AboutDialogH La smartcard n'est pas accessible  Smartcard is not accessible  AboutDialogX *** Nettoyage des données en cours ***' *** Clearing data in progress *** AboutDialogJ *** Erreur de communication ***! *** Communication error *** AboutDialogZ *** Le micrologiciel est verrouillé *** *** Firmware is locked *** AboutDialog %1 GB%1 GB AboutDialogb(N'a pas été effacée avec des données aléatoires)(Not erased with random data) AboutDialogŠ<html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Guides et aide en ligne (anglais exclusivement)</span></a></p></body></html>«

Instructions and help

 AboutDialog|<html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 by NitrokeyUG. </span></p><p><span style=" font-size:10pt; font-style:italic;">Ce logiciel est distribué sous </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">licence GNU General Public v3</span></a><span style=" font-size:10pt; font-style:italic;">.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html>C

Copyright %1 by NitrokeyUG.

This software is licensed under the GNU General Public License v3.

www.nitrokey.com

 AboutDialog <html><head/><body><p>Cette application vous permet de configurer et utiliser vos Nitrokey Pro et Nitrokey Storage.</p></body></html>

This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.

 AboutDialogX<span style="color:#c80636">Attention</span>*Warning AboutDialogÀ proposAbout AboutDialogActivéeActive AboutDialog Administrateur :Admin: AboutDialog4Version de l'application : App version: AboutDialog:Numéro de série de la carte :Card serial number: AboutDialogStatut détailléDetailed Status AboutDialog Volume chiffré :Encrypted volume: AboutDialog4Version du micrologiciel :Firmware version: AboutDialogVolume caché :Hidden Volume: AboutDialog8Licences et composants tiers!Licenses and 3rd-party components AboutDialogFUne nouvelle carte SD a été trouvéeNew SD card found AboutDialog4Aucune Nitrokey détectée No active Nitrokey  AboutDialogXAucune connexion détectée Merci de réessayerNo connection Please retry AboutDialogNon activée Not active AboutDialogOKOK AboutDialog2Compteur d'essai de PIN :Password retry counters: AboutDialogLECTURE SEULE READ ONLY AboutDialog LECTURE/ÉCRITURE READ/WRITE AboutDialogSD ID :SD ID: AboutDialog StatutStatus AboutDialog”La clef USB n'est pas sécurisée ! Sélectionner les clefs d'initialisation.&Stick is not secure! Select Init keys. AboutDialog,Capacité de stockage :Storage Capacity: AboutDialog(Volume non chiffré :Unencrypted volume: AboutDialogUtilisateur :User: AboutDialog@Mauvais PIN. Merci de réessayer.Wrong PIN. Please try again.Authentication&Journal de débogage Debug Log DebugDialog caractères charsDialogChangePasswordRModifier le mot de passe du micrologicielChange Firmware PasswordDialogChangePassword4Changer le PIN utilisateurChange user PINDialogChangePassword8PIN administrateur courant :Current Admin PIN:DialogChangePasswordNMot de passe courant du micrologiciel :Current Firmware Password:DialogChangePassword2PIN utilisateur courant :Current User PIN:DialogChangePasswordhLe PIN courant n'est pas valide. Merci de réessayer..Current password is not correct. Please retry.DialogChangePasswordŠLa clef n'a pas encore été initialisée. Merci de réessayer plus tard.6Device is not yet initialized. Please try again later.DialogChangePassword2Nouveau PIN utilisateur : New User PIN:DialogChangePassword6Le nouveau PIN est installéNew password is setDialogChangePassword@Réinitialiser le PIN utilisateurReset User PINDialogChangePassword Essais restant :Retry count left:DialogChangePassword:Définir le PIN administrateur Set Admin PINDialogChangePassword4Définir le PIN utilisateur Set User PINDialogChangePasswordAfficher le PINShow PINDialogChangePassword0Afficher le mot de passe Show passwordDialogChangePassword^La longueur maximale d'un PIN/mot de passe est $The maximum length of a password is DialogChangePassword^La longueur minimale d'un PIN/mot de passe est $The minimum length of a password is DialogChangePasswordlLa longueur minimale de l'ancien PIN/mot de passe est *The minimum length of the old password is DialogChangePasswordhLes nouveaux mots de passe entrées ne concordent pas)The new password entries are not the sameDialogChangePassword Malheureusement vous n'avez plus d'essai possible. Merci de vous reporter aux instructions concernant la réinitialisation du PIN administrateur.aUnfortunately you have no more trials left. Please check instruction how to reset Admin password.DialogChangePassword Malheureusement vous n'avez plus d'essai possible. Merci d'utiliser la fonction 'Réinitialiser le PIN utilisateur' du menu pour le réinitialiserjUnfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset passwordDialogChangePassworddInformations sur les licences (Échap. pour sortir)!License information (ESC to Exit) LicenseDialogÌ(Recommandation : utilisez un TOTP pour des applications web et un HOTP pour des applications locales)O(Recommendation: Use TOTP for web applications and HOTP for local applications) MainWindowÿÿÿÿ ******************************** MainWindow &... MainWindowÿÿÿÿ00000000000000000000 MainWindow6 chiffres6 digits MainWindow8 chiffres8 digits MainWindow†<Sélectionner l'emplacement de l'espace sécurisé des mots de passe> MainWindowJ<html><head/><body><p><span style=" font-weight:600; color:#a40000;">La "Chiave Segreta" OTP inserita è troppo lunga per questo dispositivo.</span></p></body></html>¥

Entered OTP 'Secret Key' string is longer than supported by this device

 MainWindow˜<html><head/><body><p>Nascondi o mostra la chiave segreta.</p></body></html>@

Hide or show the secret.

 MainWindowÒ<html><head/><body><p>I campi Password Safe supportano i dati UTF8, consentendo di utilizzare set di caratteri internazionali. Ricorda che i caratteri non inglesi potrebbero occupare più spazio (fino a 4 caratteri). I contatori accanto a ciascun campo mostrano quanti altri caratteri inglesi standard possono essere accettati da ciascun campo.</p></body></html>X

Password Safe fields support UTF8 data. It means that you can use your national characters here. Please remember however that non-English characters could take more space (up to 4 characters). The counters next to each field are to inform how much more standard English characters can given field accept.

 MainWindowr<html><head/><body><p>La chiave segreta viene fornita dal fornitore dei servizi, è possibile accedere o può essere configurata nell'applicazione locale dopo l'accesso.</p></body></html>¼

The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to.

 MainWindow”<html><head/><body><p>Fila traduzioni (richiede riavvio)</p></body></html>H

Translation file (needs restart)

 MainWindow’Chiavi AES non inizializzate. Per favore inserisci il PIN Amministratore.3AES keys not initialized. Please provide Admin PIN. MainWindowÐDopo aver generato un segreto casuale, copialo nell'applicazione o nel servizio a cui desideri accedere.xAfter generating a random secret, you would need to copy it into your application or service where you want to login to. MainWindow Base32Base32 MainWindow>Impossibile cancellare lo Slot.Can't clear slot. MainWindow>Impossibile salvare lo Slot. %1Can't save slot. %1 MainWindowPImpossibile bloccare la Password Sicura.Can't unlock password safe. MainWindowCancellaCancel MainWindow(Caratteri rimanenti:Characters left: MainWindow(Impostazione appuntiClipboard settings MainWindow^Esecuzione comando fallita. Per favore riprova.+Command execution failed. Please try again. MainWindowŽErrore di comuncazione. Per favore inserisci nuovamente il dispositivo.0Communication error. Please reinsert the device. MainWindowHConfigurazione scritta con successo.#Configuration successfully written. MainWindow.Connessione dispositivoConnecting device MainWindow<Copia il segreto negli appuntiCopy secret to clipboard MainWindow&Copia negli appuntiCopy to clipboard MainWindowZIl contatore deve essere un valore fra 0 e %1(Counter must be a value between 0 and %1 MainWindowêValore contatore non copiato - c'è stato un errore nella conversione. Impostazione contatore a 0. Per favore riprova.fCounter value not copied - there was an error in conversion. Setting counter value to 0. Please retry. MainWindowRPosizione file debug (verrà sovrascritto))Debug file location (will be overwritten) MainWindow2Impostazioni log di debugDebug log settings MainWindowDettagli:  Details:  MainWindownDispositivo connesso. Attendi per l'inizializzazione.../Device connected. Waiting for initialization... MainWindow>Il dispositivo è stato bloccatoDevice has been locked MainWindowØRilevato il blocco del dispositivo, rimuovere e inserire nuovamente il dispositivo. Se il problema si ripresenta, per favore: 1. Chiudi l'applicazione 2. Reinserisci il dispositivo 3. Attendi 30 secondi e avvia nuovamente l'applicazione¾Device lock detected, please remove and insert the device again. If problem will occur again please: 1. Close the application 2. Reinsert the device 3. Wait 30 seconds and start application MainWindowjNon uscire quando la finestra principale viene chiusa*Do not quit when the main window is closed MainWindowFai nulla Do nothing MainWindow6Premi due volte BlocMaiusc:Double press CapsLock: MainWindow0Premi due volte BlocNum:Double press NumLock: MainWindow4Premi due volte BlocScorr:Double press ScrollLock: MainWindow®La 'Chiave Segreta' OTP inserita è più lunga di quanto supportato da questo dispositivoGEntered OTP 'Secret Key' string is longer than supported by this device MainWindow:Cancella Slot Password SicuraErase Password Safe slot MainWindowCancella Slot Erase Slot MainWindowXErrore nella scrittura della configurazione!Error writing configuration! MainWindowbEsempio: "A3911C05..." (rimuovi ogni prefisso 0x)-Example: "A3911C05..." (remove any 0x prefix) MainWindow(Esempio: "ZR3M5I..."Example: "ZR3M5I..." MainWindowvReimpostazione ai valori di fabbrica eseguita con successo.Factory reset was successful. MainWindowŽIl contatore per Nitrokey Storage deve essere un valore fra 0 e 9999999BFor Nitrokey Storage counter must be a value between 0 and 9999999 MainWindowDimentica il PIN Utente dopo 10 minuti (se non selezionato il PIN Utente rimarrà in memoria durante l'intera esecuzione dell'applicazione)fForget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) MainWindowGeneraleGeneral MainWindow.Genera password casualeGenerate random password MainWindow0Genera password casuale Generate random password  MainWindowBGenera una chiave segreta casualeGenerate random secret MainWindowHOTPHOTP MainWindowLunghezza HOTP: HOTP length: MainWindow<Fattore di movimento seme HOTPHOTP moving factor seed MainWindowSlot HOTP  HOTP slot  MainWindow AiutoHelp MainWindowEsadecimaleHex MainWindowŽNascondi la finestra principale quando il dispositivo viene disconnesso(Hide main window when device disconnects MainWindow.Noscondi chiave segreta Hide secret MainWindowInattivoIdle MainWindow(Formato di ingresso: Input format: MainWindow„Chiavi Generate. Per favore sblocca la Password Sicura nuovamente.2Keys generated. Please unlock Password Safe again. MainWindow|Etichetta mostrata quando la chiave segreta OTP è troppo lunga/Label shown when the OTP secret key is too long MainWindow*Blocca il dispositivo Lock Device MainWindow$Blocco dispositivoLocking device MainWindowLog su consoleLog to console MainWindowLog abilitatoLogging enabled MainWindow$Utente di accesso: Login name: MainWindow.Parte MUI dell'Token IDMUI part of Token ID MainWindowMUI:MUI: MainWindowGestione Slot Manage slots MainWindow<Fattore di movimento del Seme:Moving factor seed: MainWindow Nome:Name: MainWindowNitrokey App Nitrokey App MainWindow*Nitrokey Pro connessaNitrokey Pro connected MainWindowÈNitrokey Pro v0.7 non supporta segreti che iniziano con un byte nullo. Per favore cambia il segreto.]Nitrokey Pro v0.7 does not support secrets starting from null byte. Please change the secret. MainWindow2Nitrokey Storage connessoNitrokey Storage connected MainWindow"Nitrokey connessoNitrokey connected MainWindow*Nitrokey non connessaNitrokey disconnected MainWindow.Nitrokey non collegata!Nitrokey is not connected! MainWindowNota: i fattori secondari non sono protetti dagli attacchi fisici. Se la Nitrokey viene persa, è necessario cambiare tutti i segreti OTP.~Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. MainWindow*Nota: i fattori di autenticazione secondaria non sono protetti dagli attacchi fisici. Cambia tutti segreti OTP in caso di smarrimento della Nitrokey.sNote: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. MainWindow.Parte OMP dell'Token IDOMP part of Token ID MainWindowOMP:OMP: MainWindowOTP Generale OTP General MainWindow2Impostazioni Password OTPOTP Password settings MainWindow.Configurazione Slot OTPOTP Slot Configuration MainWindow:Lunghezza codice OTP: 8 cifreOTP code length: 8 digits MainWindow:Lunghezza codice OTP: 6 cifreOTP code length: 6 digits MainWindow$Chiave segreta OTPOTP secret key MainWindowVPassword usa e getta copiata negli appunti./One-time password has been copied to clipboard. MainWindowPanoramicaOverview MainWindowParametri Parameters MainWindowPassword Sicura Password Safe MainWindow6Numero Slot Password SicuraPassword Safe slot number MainWindow(Password sicura [%1]Password safe [%1] MainWindow2Password Sicura sbloccataPassword safe unlocked MainWindowPassword: Password: MainWindow2Percorso del file di log:Path for debug log file: MainWindowDPer favore inserisci una password.Please enter a password. MainWindowPPer favore inserisci il nome dello Slot.Please enter a slotname. MainWindowŒPer favore riavvia l'applicazione per applicare le nuove impostazioni.7Please run the application again to apply new settings. MainWindow²Proteggi password OTP con PIN Utente (verrà richiesto al primo utilizzo di ogni sessione)EProtect OTP by user PIN (will be requested on first use each session) MainWindow²La stringa esadecimale del segreto non è valida. Per favore controlla e prova nuovamente.HProvided secret hex string is invalid. Please check input and try again. MainWindowEsciQuit MainWindow:Reimposta l'ora sul Nitrokey?Reset Nitrokey's time? MainWindow SalvaSave MainWindowChiave segreta: Secret Key: MainWindowHChiave segreta copiata negli appuntiSecret copied to clipboard MainWindow.Formato segreto: base32Secret input format: base32 MainWindow8Formato segreto: esadecimaleSecret input format: hex MainWindowChiave segreta Secret key MainWindow>Seleziona il numero di Slot OTPSelect OTP slot number MainWindow$Seleziona percorso Select path MainWindow<Tipo di Slot selezionato: HOTPSelect slot type: HOTP MainWindow<Tipo di Slot selezionato: TOTPSelect slot type: TOTP MainWindow>Premi 'invio' come ultimo tasto"Send 'enter' as the last keystroke MainWindowInvia HOTP1 Send HOTP1 MainWindowInvia HOTP2 Send HOTP2 MainWindowInvia Token ID Send token ID MainWindow\Imposta il contatore HOTP ad un valore casuale Set HOTP counter to random value MainWindow:Imposta il contatore HOTP a 0Set HOTP counter to zero MainWindowImposta casuale Set to random MainWindowImposta a zero Set to zero MainWindowImpostazioniSettings MainWindowÌImpostazioni per inserire un codice HOTP attraverso combinazioni speciali di tasti (solo Tastiere USB)QSettings for inserting HOTP code through special key shortcut (USB-Keyboard only) MainWindowFMostra il messaggio del primo avvioShow first-run message MainWindow‚Mostra la finestra principale quando il dipositivo viene connesso%Show main window when device connects MainWindowŒMostra un messaggio quando il dispositivo viene connesso / disconnesso6Show message about device's connection / disconnection MainWindowÄMostra messaggio quando nessuna partizione può essere identificata sul Volume Cifrato (Solo Linux)RShow warning when no partitions could be detected on Encrypted Volume (Linux only) MainWindow Slot Slot  MainWindow:Slot cancellato con successo."Slot has been erased successfully. MainWindow(Slot già cancellato.Slot is erased already. MainWindowNome Slot Slot name MainWindowNome Slot: Slot name: MainWindow4Slot scritto con successo.Slot successfully written. MainWindow Slot:Slot: MainWindow$Password statica 0Static password 0 MainWindowTempo di memorizzazione delle Pasword Sicure negli appunti (in secondi):>TIme to store Password Safe secrets in clipboard (in seconds): MainWindowTOTPTOTP MainWindow,Valore intervallo TOTPTOTP interval value MainWindow Intervallo TOTP:TOTP interval: MainWindowLunghezza TOTP: TOTP length: MainWindowSlot TOTP  TOTP slot  MainWindow,Parte TT dell'Token IDTT part of Token ID MainWindowTT:TT: MainWindowŠLa Nitrokey App è disponibile come icona nella barra delle notifiche.9The Nitrokey App is available as an icon in the tray bar. MainWindowLa chiave segreta viene fornita dal fornitore di servizi, è possibile accedere o può essere configurata nell'applicazione locale dopo il login.”The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to. MainWindow˜La stringa segreta inserita non è valida. Per favore inseriscila nuovamente.AThe secret string you have entered is invalid. Please reenter it. MainWindow.Il tempo è fuori sincroTime is out-of-sync MainWindow Ora reimpostata! Time reset! MainWindow†Tempo di memorizzare delle Password OTP negli appunti (In secondi):4Time to store OTP secrets in clipboard (in seconds): MainWindowTempo di memorizzazione delle Pasword Sicure negli appunti (in secondi):>Time to store Password Safe secrets in clipboard (in seconds): MainWindowÎPer gestire questa funzionalità, l'applicazione manterrà il tuo PIN Utente in memoria. Vuoi continuare?dTo handle this functionality application will keep your user PIN in memory. Do you want to continue? MainWindowToken IDToken ID MainWindowDFile traduzioni (richiede riavvio) Translation file (needs restart) MainWindow,Sblocca Volume CifratoUnlock Encrypted Volume MainWindow.Sblocca Volume NascostoUnlock Hidden Volume MainWindow.Sblocca Password SicuraUnlock Password Safe MainWindow.Sblocca Password SicuraUnlock password safe MainWindow,Utente non autenticatoUser not authenticated MainWindow$Livello verbosità:Verbosity level: MainWindowäATTENZIONE! L'ora del tuo computer e del Nitrokey non sono sincronizzate. Il tuo computer potrebbe essere configurato con l'ora sbagliata o il tuo Nitrokey potrebbe essere stato attaccato. Se un utente malintenzionato o un malware può aver utilizzato il tuo Nitrokey, è necessario ripristinare immediatamente i segreti delle password usa e getta (OTP) configurate. Se l'ora del tuo computer è sbagliata, configurala correttamente e ripristina l'ora di Nitrokey. Reimpostare il tempo sul Nitrokey?•WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? MainWindowfATTENZIONE: Sei sicuro di voler cancellare lo Slot?1WARNING: Are you sure you want to erase the slot? MainWindowATTENZIONE: questa versione del firmware di archiviazione è obsoleta. L'applicazione potrebbe non rispondere e lo sblocco del volume crittografato potrebbe non funzionare. Si prega di aggiornare il firmware alla versione più recente. La guida dovrebbe essere disponibile su: <br/><a href='https://www.nitrokey.com/en/doc/firmware-update-storage'>www.nitrokey.com/en/doc/firmware-update-storage</a>.GWARNING: This Storage firmware version is old. Application may be unresponsive and unlocking encrypted volume may not work. Please update the firmware to the latest version. Guide should be available at:
www.nitrokey.com/en/doc/firmware-update-storage. MainWindow`Avviso: l'applicazione non è in grado di rilevare alcuna partizione sul Volume Crittografato. Si prega di utilizzare strumenti grafici GParted o su terminali come fdisk/parted.’Warning: Application could not detect any partition on the Encrypted Volume. Please use graphical GParted or terminal fdisk/parted tools for this. MainWindowÞATTENZIONE: Il volume cifrato non è sicuro, Seleziona l'opzione "Inizializza dispositivo" dal menu contestuale.]Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. MainWindow¾ATTENZIONE: Il volume cifrato non è sicuro, Seleziona "Inizializza la memoria con dati casuali"UWarning: Encrypted volume is not secure, Select "Initialize storage with random data" MainWindowNVuoi che ti venga ricordato nuovamente?$Would you like to be reminded again? MainWindow.Desideri uscire adesso?Would you like to quit now? MainWindowdVuoi che questo messaggio sia mostrato nuovamente?*Would you like to show this message again? MainWindow>PIN errato. Per favore riprova.Wrong PIN. Please try again. MainWindow>PIN errato. Per favore riprova.Wrong Pin. Please try again. MainWindow4PIN Amministratore errato.Wrong admin password. MainWindow$PIN Utente errato.Wrong user password. MainWindowDÈ possibile trovare l'icona dell'applicazione nella barra delle notifiche nell'angolo in basso a destra dello schermo (Windows) o in alto a destra (Linux, MacOS).You can find application’s tray icon in system tray in the right down corner of your screen (Windows) or in the upper right (Linux, MacOS). MainWindowpIl tuo segreto è invalido. Per favore cambia il segreto.1Your secret is invalid. Please change the secret. MainWindowcorrente:current: MainWindowTIl segreto non ha superato la validazione.!secret is not passing validation. MainWindow&Cancella&Cancel PinDialog&Ok&OK PinDialog&PIN Amministratore: Admin PIN: PinDialogœIl dispositivo non è stato ancora inizializzato. Per favore riprova più tardi.6Device is not yet initialized. Please try again later. PinDialogDInserisci la Password del FirmwareEnter Firmware Password PinDialogFInserisci la Password del Firmware:Enter Firmware Password: PinDialog>Inserisci il PIN AmministratoreEnter admin PIN PinDialog:Inserisci il PIN della schedaEnter card PIN PinDialogFInserisci la password della scheda:Enter card password: PinDialogXInserisci la password per il Volume Nascosto Enter password for hidden volume PinDialogZInserisci la password per il Volume Nascosto:!Enter password for hidden volume: PinDialog.Inserisci il PIN UtenteEnter user PIN PinDialog"Finestra PasswordPassword dialog PinDialogTPer favore inserisci il nuovo PIN/password!Please enter the new PIN/password PinDialog&Mostra PIN/password Show password PinDialog.Tentativi rimanenti: %1Tries left: %1 PinDialogPIN Utente: User PIN: PinDialogzAttenzione: PIN predefinito in uso. Per favore cambia il PIN.4Warning: Default PIN is used. Please change the PIN. PinDialogVuoi farlo ora?Would you like to so now? PinDialognIl tuo PIN è troppo lungo! Usa non più di 30 caratteri.6Your PIN is too long! Use not more than 30 characters. PinDialogdIl tuo PIN è troppo corto. Usa almeno 6 caratteri.1Your PIN is too short. Use at least 6 characters. PinDialog”Riscontrato errore critico. Per favore riavvia l'applicazione. Messaggio: ACritical error encountered. Please restart application. Message:  QApplicationAvanzamentoProgressStick20ResponseDialognImpossibile impostare il volume cifrato in sola lettura%Cannot set encrypted volume read-onlyStorageActionsxImpossibile impostare il volume cifrato in lettura/scrittura&Cannot set encrypted volume read-writeStorageActionsvImpossibile impostare il volume non cifrato in sola lettura'Cannot set unencrypted volume read-onlyStorageActions€Impossibile impostare il volume non cifrato in lettura/scrittura(Cannot set unencrypted volume read-writeStorageActions4Problema di comunicazione.Communication issue.StorageActionsJImpossibile cancellare la memoria SD.Could not clear SD card.StorageActionsDCould not unlock encrypted volume."Could not enable encrypted volume.StorageActions>Could not unlock hidden volume.Could not enable hidden volume.StorageActionsDImpossibile esportare il firmware.Could not export firmware.StorageActionsHImpossibile bloccare il dispositivo.Could not lock device.StorageActionsNImpossibile bloccare il volume cifrato. Could not lock encrypted volume.StorageActionsPImpossibile bloccare il volume nascosto.Could not lock hidden volume.StorageActions~Impossibile commutare il dispositovo in modalità aggiornamento.'Device could not be set in update mode.StorageActions(Dispositivo bloccato Device lockedStorageActionsJDispositivo in modalità aggiornamentoDevice set in update modeStorageActions0Locking encrypted volumeDisabling encrypted volumeStorageActions*Locking hidden volumeDisabling hidden volumeStorageActions4Unlocking encrypted volumeEnabling encrypted volumeStorageActions.Unlocking hidden volumeEnabling hidden volumeStorageActions.Encrypted volume lockedEncrypted volume disabledStorageActions2Encrypted volume unlockedEncrypted volume enabledStorageActionsPVolume cifrato impostato in sola letturaEncrypted volume set read-onlyStorageActionsFVolume cifrato in lettura/scritturaEncrypted volume set read-writeStorageActions$Firmware esportatoFirmware exportedStorageActions@Il flag non può essere azzerato.Flag cannot be cleared.StorageActionsFlag azzerato. Flag cleared.StorageActionsjFunzionalità non implementata nella versione corrente0Functionality not implemented in current versionStorageActions8Generazione nuove chiavi AESGenerating new AES keysStorageActionsRIl volume nascosto non può essere creato.#Hidden volume could not be created.StorageActions,Volume nascosto creatoHidden volume createdStorageActions(Hidden volume lockedHidden volume disabledStorageActions,Hidden volume unlockedHidden volume enabledStorageActionsLLe chiavi non possono essere generate.Keys could not be generated.StorageActions,Bloccaggio dispositivoLocking deviceStorageActions2Nuove chiavi AES generateNew AES keys generatedStorageActionsRPlease unlock the encrypted volume first.)Please enable the encrypted volume first.StorageActions&Codice di stato: %1Status code: %1StorageActionsQuesta attività blocca il tuo volume cifrato. Procedere? Per evitare la perdita di dati, per favore smonta le partizioni prima di procedere.‡This activity locks your encrypted volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding.StorageActionsQuesta attività blocca il tuo volume nascosto. Procedere? Per evitare la perdita di dati, per favore smonta le partizioni prima di procedere.„This activity locks your hidden volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding.StorageActions¦Per completare la procedura di blocco, per favore rimuovi e riconnetti la Nitrokey.ITo complete the lock procedure, please remove and reconnect the Nitrokey.StorageActionsXVolume non cifrato impostato in sola lettura Unencrypted volume set read-onlyStorageActionsbVolume non cifrato impostato in lettura/scrittura!Unencrypted volume set read-writeStorageActionsAttenzione: La generazione di nuove chiavi AES distruggerà i volumi cifrati, i volumi nascosti e le password sicure. Continuare?qWARNING: Generating new AES keys will destroy the encrypted volumes, hidden volumes, and password safe! Continue?StorageActionsWrong PIN.Wrong password.StorageActions2&Informazioni su Nitrokey&About NitrokeyTray:&Cambia il PIN Amministratore&Change Admin PINTray@&Cambia la Password del Firmware&Change Firmware PasswordTray*&Cambia il PIN Utente&Change User PINTray &Debug&DebugTray2&Distruggi i dati cifrati&Destroy encrypted dataTray|&Disabilita l'avviso "Inizializza la memoria con dati casuali"6&Disable 'initialize storage with random data' warningTrayJ&Abilita l'aggiornamento del Firmware&Enable firmware updateTray8&Esporta il firmware su File&Export firmware to fileTray6Reimpostazione di &Fabbrica&Factory resetTray &Aiuto&HelpTray6&Inizializza il dispositivo&Initialize deviceTrayP&Inizializza la memoria con dati casulai$&Initialize storage with random dataTray,&Blocca il dispositivo &Lock DeviceTray,&Blocca Volume cifrato&Lock encrypted volumeTray.&Blocca Volume Nascosto&Lock hidden volumeTray>B&locca il dispositivo hardware&Lock stick hardwareTray&OYP&OTPTray2Sicurezza &OTP e Password&OTP and Password safeTrayPan&oramica &OverviewTray &Esci&QuitTray0&Reimposta il PIN Utente&Reset User PINTrayf&Imposta il volume cifrato in modalità solo lettura&Set encrypted volume read-onlyTrayp&Imposta il volume cifrato in modalità lettura/scrittura &Set encrypted volume read-writeTraynImpo&sta il volume non cifrato in modalità sola lettura!&Set unencrypted volume read-onlyTraypImpo&sta il volume cifrato in modalità lettura/scrittura"&Set unencrypted volume read-writeTray:&Configura il Volume Nascosto&Setup hidden volumeTray.&Sblocca volume cifrato&Unlock encrypted volumeTray0&Sblocca Volume Nascosto&Unlock hidden volumeTray(vuoto)(empty)Tray AttivoActiveTray&Attivo (modo debug)Active (debug mode)TrayConfigura ConfigureTray<Operazione lunga in corso: %1%Long operation in progress: %1%Tray.Nitrokey non collegata!Nitrokey is not connected!TrayPassword PasswordsTrayDSmart-card o memoria SD non pronta"Smartcard or SD card are not readyTray$Configura specialeSpecial ConfigureTray.Sblocca password sicuraUnlock password safeTrayV<html><head/><body><p>Selezionando &quot;OK&quot; il dipositivo entrerà nel<br/>modo aggiornamento firmware. Non c'è alcun modo per tornare indietro!<br/>Leggi il documento <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;"> </span></a>su come<br/>aggiornare il firmware.</p><p>Continuare con il modo aggiornamento firmware?</p><p><br/></p></body></html>•

When you select "OK" the device enters the
firmware update mode. There is no way back!
Please read the documentation how to
update the firmware.

Continue entering the firmware update mode?


 UpdateDialog,Aggiornamento FirmwareFirmware update UpdateDialog`Cancella tutte le impostazioni dell'applicazione Clear all application's settingsmain6Abilita i messaggi di debugEnable debug messagesmainZAbilita le funzioni amministrative aggiuntive%Enable extra administrative functionsmain8Elenca le lingue disponibiliList available languagesmainÂCarica il file delle traduzioni specificato e memorizza questa scelta nel file di configurazione.MLoad translation file with given name and store this choice in settings file.main\Nitrokey App - Gestisci le tue chiavi Nitrokey*Nitrokey App - Manage your Nitrokey sticksmainŠSalva il log di debug nella finestra dell'applicazione (sperimentale)-Save debug log to App's window (experimental)mainSalva il log di debug su un file con nome <log-file-name> (sperimentale)?Save debug log to file with name (experimental)main@Imposta il levello di debug, 0-4Set debug level, 0-4main–Imposta il ritardo fra l'invio dei comandi al dispositivo (in ms) a <delay>mainpMostra informazioni addizionali relativamente al binario(Show additional information about binarymainx<html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Informazioni di sicurezza</span></p><p>Leggi le seguenti istruzioni con molta attenzione.</p><p><span style=" font-weight:600;">Protezione PIN</span></p><p>Nitrokey è protetta da un PIN Utente e da un PIN Amministratore. Il PIN Utente può sbloccare il disco cifrato, la password sicura, la smart-card e (se abilitato) le password Usa e Getta (One-Time Password - OTP). Le password OTP di base non sono protette da PIN in quanto usate solo come fattori secondari. La smart-card è sbloccata all'inserimento del PIN, a prescindere dal motivo di inserimento del PIN stesso. Il PIN Amministratore può essere usato per configurare le impostazioni e per aggiungere o rimuovere voci. Devi cambiare entrambi i PIN di base e mantenerli riservati. Se il PIN Utente e il PIN Amministratore sono inserriti erroneamente tre volte ciascuno, o se la smart-card è stata ripristinata ai valori di fabbrica, tutti i tuoi dati sensibili saranno persi irrimediabilmente.</p><p><span style=" font-weight:600;">Protezione Fisica</span></p><p>Tutti i dati sensibili sono cifrati e assicurati dagli attacchi fisici. Questo non vale per le password OTP perché sono usate solo come fattore secondario.</p><p><span style=" font-weight:600;">Volumi Nascosti</span></p><p>I Volumi Nascosti richiedono che la memoria di massa sia inizializzata con dati casuali. I Volumi Nascosti sono protetti contemporaneamente dal PIN Utente e da una password separata che è differente per ogni Volume Nascosto. Senza la conoscenza di entrambi, PIN Utente e password, il Volume Nascosto non può essere trovato e la sua esistenza non essere provata o negata. La password per il Volume Nascosto deve essere sufficientemente lunga e robusta per proteggersi da un attacco di forza bruta. I Volumi Nascosti, tuttavia, sono archiviati su una memoria flash con livellamento dell'usura integrato (wear levelling), e le informazioni potrebbero potenzialmente essere divulgate ad un aggressore sofisticato, rivelando in tal modo l'esistenza di volumi nascosti.</p></body></html>v

Security Information

Please read the following carefully.

PIN Protection

Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.

Physical Protection

All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.

Hidden Volumes

Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are however stored on a flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.

securitydialogDialogoDialogsecuritydialogfHo letto ed ho ben compreso gli avvisi di sicurezza+I read and understood this security warningsecuritydialogOkOKsecuritydialog%%stick20HiddenVolumeDialog®<html><head/><body><p>1. Potresti voler copiare alcuni file sensibili nel Volume Nascosto.<br/>2. Configurare i Volumi nascosti in questa finestra.<br/>3. Una volta configurato un Volume Nascosto non è più possibile utilizzare/scrivere sul volume cifrato, altrimenti potresti distruggere i dati contenuti nel Volume Nascosto.</p></body></html>;

1. You may want to copy some innocuous files to the encrypted data.
2. Configure hidden volumes in this dialogue.
3. Once you configured a hidden volume you must not use/write to the encryption volume anymore. Otherwise it may destroy the data in your hidden volume.

stick20HiddenVolumeDialog¶<html><head/><body><p><span style=" font-weight:600;">Dovresti ben comprendere le proprietà dei Volumi Nascosti prima di procedere. Potresti involontariamente distruggere tutti i tuoi dati cifrati! <br/>Per favore leggi </span><a href="https://www.nitrokey.com/documentation/hidden-volumes"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">queste istruzioni</span></a><span style=" font-weight:600;"> prima di andare avanti.</span></p></body></html>¤

You should understand the properties of hidden volumes before proceeding. It can destroy your encrypted data!
Please read
these instructions first.

stick20HiddenVolumeDialoglFinisci il Volume Nascosto a %1 della memoria cifrata:1End hidden volume at %1 of the encrypted storage:stick20HiddenVolumeDialogGBGBstick20HiddenVolumeDialog8Impostazioni Volume NascostoHidden Volume settingsstick20HiddenVolumeDialogVolume Nascosto non posizionato su uno spazio libero. Per favore imposta il tuo volume fra %1% e %2% della dimensione totale dalla scheda SD.rHidden volume not positioned in unwritten space. Please set your volume between %1% and %2% of total SD card size.stick20HiddenVolumeDialog8Password del Volume NascostoHidden volume passwordstick20HiddenVolumeDialogJPassword del Volume Nascosto (ripeti)!Hidden volume password (repeated)stick20HiddenVolumeDialog,Volume Nascosto Slot 1Hidden volume slot 1stick20HiddenVolumeDialog,Volume Nascosto Slot 2Hidden volume slot 2stick20HiddenVolumeDialog,Volume Nascosto sSot 3Hidden volume slot 3stick20HiddenVolumeDialog,Volume Nascosto Slot 4Hidden volume slot 4stick20HiddenVolumeDialogMBMBstick20HiddenVolumeDialog MediaMediumstick20HiddenVolumeDialog*Impostazione PasswordPassword settingsstick20HiddenVolumeDialog(Robustezza Password:Password strength:stick20HiddenVolumeDialogPassword: Password:stick20HiddenVolumeDialogfPer favore, usa i tasti shift-tab per le istruzioni2Please use shift+tab key shortcut for instructionsstick20HiddenVolumeDialog8Impostazione Volume NascostoSetup hidden volumestick20HiddenVolumeDialogMostra password Show passwordstick20HiddenVolumeDialogÚLa dimensione sarà arrotondata alla percentuale intera inferiore della dimensione totale della memoria (%1MB)JSize will be rounded down to integral percent of total storage size (%1MB)stick20HiddenVolumeDialogrSlot dove memorizzare le informazioni del Volume Nascosto9Slot under which hidden volume information will be storedstick20HiddenVolumeDialogjInizia il Volume Nascosto a %1 della memoria cifrata:3Start hidden volume at %1 of the encrypted storage:stick20HiddenVolumeDialog@Capacità di memorizzazione: %1GBStorage capacity: %1GBstick20HiddenVolumeDialogRobustaStrongstick20HiddenVolumeDialog<Le password non sono identicheThe passwords are not identicalstick20HiddenVolumeDialogÐL'area libera disponibile per il Volume Nascosto è compresa fra %1% e %2% della dimensione della memoria[The unwritten area available for hidden volume is between %1 % and %2 % of the storage sizestick20HiddenVolumeDialog Unità:Unit:stick20HiddenVolumeDialogtUsa questo come unità della dimensione del Volume Nascosto#Use this as hidden volume size unitstick20HiddenVolumeDialogMolto Robusta Very Strongstick20HiddenVolumeDialogMolto debole Very Weakstick20HiddenVolumeDialog DeboleWeakstick20HiddenVolumeDialogJDimensione del Volume Nascosto errataWrong size of hidden volumestick20HiddenVolumeDialog\Password troppo corta! Usa almeno 8 caratteri.6Your password is too short. Use at least 8 characters.stick20HiddenVolumeDialoglunghezzalengthstick20HiddenVolumeDialogminuscole lower casestick20HiddenVolumeDialog numerinumbersstick20HiddenVolumeDialogsimbolisymbolsstick20HiddenVolumeDialogmaiuscole upper casestick20HiddenVolumeDialogÆ<html><head/><body><p>Quando selezioni &quot;OK&quot; il dispositivo bloccherà il firmware e chiuderà la porta di debug dell'hardware. Questo disabilita qualsiasi accesso hardware esterno ai dati sul dispositivo (processore).</p><p>Non è possibile tornare indietro!</p><p>Dopo questo non sarà possibile aggiornare nuovamente il firmware.</p></body></html>#

When you select "OK" the stick lock the firmware and close the hardware debug port.This disables any external hardware access to the data in the device (processor).

There is no way back!

After this you can't update the firmware.

stick20LockFirmwareDialogBlocca Firmware Lock Firmwarestick20LockFirmwareDialogˆnitrokey-app-1.3.2/i18n/nitrokey_it.ts0000644000175000017500000024470513314460010017174 0ustar janjan00000000000000 AboutDialog About Informazioni su <html><head/><body><p>This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.</p></body></html> <html><head/><body><p>Questa applicazione permette la configurzione e l'uso delle chiavette Nitrokey Pro e Nitrokey Storage.</p></body></html> App version: Versione applicazione: Firmware version: Versione firmware: Card serial number: Numero seriale scheda: <html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 by NitrokeyUG. </span></p><p><span style=" font-size:10pt; font-style:italic;">This software is licensed under the </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3</span></a><span style=" font-size:10pt; font-style:italic;">.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html> <html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 Nitrokey UG. </span></p><p><span style=" font-size:10pt; font-style:italic;">Questo software è rilasciato sotto licenza </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3</span></a><span style=" font-size:10pt; font-style:italic;">.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html> <html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Instructions and help</span></a></p></body></html> <html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Instruzioni ed aiuto</span></a></p></body></html> Status Stato Hidden Volume: Volume nascosto: <span style="color:#c80636">Warning</span> <span style="color:#c80636">Attenzione</span> Stick is not secure! Select Init keys. Il dispositivo non è sicuro! Seleziona Inizializzazione delle chaivi. New SD card found Trovata nuova scheda SD (Not erased with random data) (Dispositivo non cancellato con dati casuali) SD ID: SD ID: Unencrypted volume: Volume non cifrato: Encrypted volume: Volume cifrato: Password retry counters: Tentativi inserimento PIN : Admin: Amministratore: Logo Logo User: Utente: Detailed Status Stato dettagliatio OK Ok SD card is not accessible Scheda SD non accessibile Smartcard is not accessible Smartcard non accessibile No connection Please retry Nessuna connessione Riprova per favore READ/WRITE Lettura/Scrittura READ ONLY Solo lettura Active Attiva (hidden) (nascosto) Not active Non attiva No active Nitrokey Nitrokey non è attiva Storage Capacity: Capacità disco: %1 GB %1 GB Licenses and 3rd-party components Licenze e componenti di terze parti *** Clearing data in progress *** *** Cancellazione in corso *** *** Communication error *** *** Errore di comunicazione *** *** Firmware is locked *** *** Firmware bloccato *** Cannot open dialog: Impossibile aprire la finestra di dialogo: Authentication Wrong PIN. Please try again. PIN errato. Riprova per favore. DebugDialog Debug Log Log di Debug DialogChangePassword Change user PIN Cambia il PIN utente Show PIN Mostra PIN Retry count left: Tentativi rimanenti: Change Firmware Password Cambia la password del Firmware Unfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset password Sfortunatamente non è possibile riprovare ancora. Per favore usa 'Reimposta PIN Utente' dal menu per reimposare il PIN Unfortunately you have no more trials left. Please check instruction how to reset Admin password. Sfortunatamente non è possibile riprovare ancora. Per favore controlla le istruzioni per reimpostare la password di Amministratore. Set User PIN Cambia PIN Utente Current User PIN: PIN Utente corrente: New User PIN: Nuovo PIN Utente: Set Admin PIN Cambia PIN Amministratore Current Admin PIN: PIN Amministratore corrente: Reset User PIN Reimposta PIN Utente Current Firmware Password: Password Firmware corrente: Show password Mostra Password Current password is not correct. Please retry. Il PIN corrente non è corretto. Prova nuovamente. New password is set Il nuovo PIN è stato cambiato The minimum length of the old password is La minima lunghezza del vecchio PIN è chars caratteri The maximum length of a password is La massima lunghezza del PIN è The minimum length of a password is La minima lunghezza del PIN è Device is not yet initialized. Please try again later. Dispositivo non inizializzato. Per favore riprova più tardi. The new password entries are not the same Le password inserite non coincidono Current PIN or password PIN o password corrente New PIN or password Nuovo PIN o password <html><head/><body><p><span style=" font-style:italic;">Nitrokey prevents against brute force password guessing attacks by allowing a maximum of 3 incorrect PIN attempts. Therefore a PIN of %1 digits is sufficient. The PIN must be between %1 and %2 characters.</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">Nitrokey previene gli attacchi di identificazione della password tramite forza bruta consentendo fino a 3 tentativi di PIN errati. Pertanto è già sufficiente un PIN di %1 cifre. Il PIN deve essere tra %1 e %2 caratteri.</span></p></body></html> New PIN: Nuovo PIN: Confirm New PIN: Conferma il nuovo PIN: Confirm New User PIN: Conferma il nuovo PIN Utente: New Password: Nuova Password: Confirm New Password: Conferma la nuova Password: The Firmware password doesn’t have a retry counter, and therefore doesn’t prevent against password guessing attacks. A secure and complex password should be created with the use of: lower and upper case letters, numbers and special characters; with a length between %2 and %3 characters.<br/>Default firmware password is: '%1'. La password del firmware non ha un contatore di tentativi, e quindi non previene attacchi di ricerca della password per tentativi. Una password sicura e complessa dovrebbe essere creata con l'uso di: lettere maiuscole e minuscole, numeri e caratteri speciali; con una lunghezza compresa tra %2 e %3 caratteri. <br/> La password del firmware predefinita è: '%1'. WARNING! If you lose your Firmware password, Nitrokey can’t be updated or reset! ATTENZIONE! Se perdi la tua password del Firmware, la Nitrokey non potrà più essere aggiornata o reinizializzata con i valori di fabbrica! LicenseDialog License information (ESC to Exit) Informazioni sulle licenze (premi ESC per uscire) MainWindow OTP Slot Configuration Configurazione Slot OTP Manage slots Gestione Slot TOTP TOTP HOTP HOTP Slot: Slot: Erase Slot Cancella Slot Name: Nome: Secret key Chiave segreta <html><head/><body><p>The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to.</p></body></html> <html><head/><body><p>La chiave segreta viene fornita dal fornitore dei servizi, è possibile accedere o può essere configurata nell'applicazione locale dopo l'accesso.</p></body></html> Secret Key: Chiave segreta: ******************************** ******************************** Secret copied to clipboard Chiave segreta copiata negli appunti <html><head/><body><p>Hide or show the secret.</p></body></html> <html><head/><body><p>Nascondi o mostra la chiave segreta.</p></body></html> Hide secret Noscondi chiave segreta Generate random secret Genera una chiave segreta casuale Input format: Formato di ingresso: Hex Esadecimale Note: 2<sup>nd</sup> factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. Nota: i fattori secondari non sono protetti dagli attacchi fisici. Se la Nitrokey viene persa, è necessario cambiare tutti i segreti OTP. Parameters Parametri Set to zero Imposta a zero Set to random Imposta casuale 6 digits 6 cifre 8 digits 8 cifre Moving factor seed: Fattore di movimento del Seme: HOTP length: Lunghezza HOTP: TOTP interval: Intervallo TOTP: Token ID Token ID Send token ID Invia Token ID MUI: MUI: TT: TT: OMP: OMP: Cancel Cancella Save Salva (Recommendation: Use TOTP for web applications and HOTP for local applications) (Raccomandazione: Usa i TOTP per le applicazioni web e HOTP per le applicazioni locali) Base32 Base32 Send 'enter' as the last keystroke Premi 'invio' come ultimo tasto 00000000000000000000 00000000000000000000 OTP General OTP Generale OTP Password settings Impostazioni Password OTP Double press NumLock: Premi due volte BlocNum: Double press CapsLock: Premi due volte BlocMaiusc: Double press ScrollLock: Premi due volte BlocScorr: Do nothing Fai nulla Send HOTP1 Invia HOTP1 Send HOTP2 Invia HOTP2 Password Safe Password Sicura Password: Password: Login name: Utente di accesso: Slot name: Nome Slot: Static password 0 Password statica 0 Generate random password Genera password casuale Characters left: Caratteri rimanenti: ... ... <html><head/><body><p>Password Safe fields support UTF8 data. It means that you can use your national characters here. Please remember however that non-English characters could take more space (up to 4 characters). The counters next to each field are to inform how much more standard English characters can given field accept.</p></body></html> <html><head/><body><p>I campi Password Safe supportano i dati UTF8, consentendo di utilizzare set di caratteri internazionali. Ricorda che i caratteri non inglesi potrebbero occupare più spazio (fino a 4 caratteri). I contatori accanto a ciascun campo mostrano quanti altri caratteri inglesi standard possono essere accettati da ciascun campo.</p></body></html> Unlock password safe Sblocca Password Sicura Nitrokey disconnected Nitrokey non connessa Nitrokey Pro connected Nitrokey Pro connessa Nitrokey Storage connected Nitrokey Storage connesso Counter value not copied - there was an error in conversion. Setting counter value to 0. Please retry. Valore contatore non copiato - c'è stato un errore nella conversione. Impostazione contatore a 0. Per favore riprova. TOTP length: Lunghezza TOTP: Wrong PIN. Please try again. PIN errato. Per favore riprova. Wrong Pin. Please try again. PIN errato. Per favore riprova. Factory reset was successful. Reimpostazione ai valori di fabbrica eseguita con successo. Device has been locked Il dispositivo è stato bloccato Counter must be a value between 0 and %1 Il contatore deve essere un valore fra 0 e %1 For Nitrokey Storage counter must be a value between 0 and 9999999 Il contatore per Nitrokey Storage deve essere un valore fra 0 e 9999999 Please enter a slotname. Per favore inserisci il nome dello Slot. Configuration successfully written. Configurazione scritta con successo. Error writing configuration! Errore nella scrittura della configurazione! Nitrokey is not connected! Nitrokey non collegata! One-time password has been copied to clipboard. Password usa e getta copiata negli appunti. WARNING: Are you sure you want to erase the slot? ATTENZIONE: Sei sicuro di voler cancellare lo Slot? Slot has been erased successfully. Slot cancellato con successo. Slot Slot Can't clear slot. Impossibile cancellare lo Slot. Slot is erased already. Slot già cancellato. Please enter a password. Per favore inserisci una password. Can't save slot. %1 Impossibile salvare lo Slot. %1 Generate random password Genera password casuale Time is out-of-sync Il tempo è fuori sincro WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? ATTENZIONE! L'ora del tuo computer e del Nitrokey non sono sincronizzate. Il tuo computer potrebbe essere configurato con l'ora sbagliata o il tuo Nitrokey potrebbe essere stato attaccato. Se un utente malintenzionato o un malware può aver utilizzato il tuo Nitrokey, è necessario ripristinare immediatamente i segreti delle password usa e getta (OTP) configurate. Se l'ora del tuo computer è sbagliata, configurala correttamente e ripristina l'ora di Nitrokey. Reimpostare il tempo sul Nitrokey? Time reset! Ora reimpostata! Nitrokey connected Nitrokey connesso Warning: Encrypted volume is not secure, Select "Initialize storage with random data" ATTENZIONE: Il volume cifrato non è sicuro, Seleziona "Inizializza la memoria con dati casuali" TOTP slot Slot TOTP HOTP slot Slot HOTP Can't unlock password safe. Impossibile bloccare la Password Sicura. Wrong user password. PIN Utente errato. Password safe [%1] Password sicura [%1] Protect OTP by user PIN (will be requested on first use each session) Proteggi password OTP con PIN Utente (verrà richiesto al primo utilizzo di ogni sessione) Forget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) Dimentica il PIN Utente dopo 10 minuti (se non selezionato il PIN Utente rimarrà in memoria durante l'intera esecuzione dell'applicazione) Command execution failed. Please try again. Esecuzione comando fallita. Per favore riprova. To handle this functionality application will keep your user PIN in memory. Do you want to continue? Per gestire questa funzionalità, l'applicazione manterrà il tuo PIN Utente in memoria. Vuoi continuare? Nitrokey Pro v0.7 does not support secrets starting from null byte. Please change the secret. Nitrokey Pro v0.7 non supporta segreti che iniziano con un byte nullo. Per favore cambia il segreto. Your secret is invalid. Please change the secret. Il tuo segreto è invalido. Per favore cambia il segreto. Slot successfully written. Slot scritto con successo. Select slot type: TOTP Tipo di Slot selezionato: TOTP Select slot type: HOTP Tipo di Slot selezionato: HOTP Select OTP slot number Seleziona il numero di Slot OTP Slot name Nome Slot The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to. La chiave segreta viene fornita dal fornitore di servizi, è possibile accedere o può essere configurata nell'applicazione locale dopo il login. OTP secret key Chiave segreta OTP Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. Nota: i fattori di autenticazione secondaria non sono protetti dagli attacchi fisici. Cambia tutti segreti OTP in caso di smarrimento della Nitrokey. After generating a random secret, you would need to copy it into your application or service where you want to login to. Dopo aver generato un segreto casuale, copialo nell'applicazione o nel servizio a cui desideri accedere. Example: "ZR3M5I..." Esempio: "ZR3M5I..." Secret input format: base32 Formato segreto: base32 Example: "A3911C05..." (remove any 0x prefix) Esempio: "A3911C05..." (rimuovi ogni prefisso 0x) Secret input format: hex Formato segreto: esadecimale Entered OTP 'Secret Key' string is longer than supported by this device La 'Chiave Segreta' OTP inserita è più lunga di quanto supportato da questo dispositivo Label shown when the OTP secret key is too long Etichetta mostrata quando la chiave segreta OTP è troppo lunga HOTP moving factor seed Fattore di movimento seme HOTP Set HOTP counter to zero Imposta il contatore HOTP a 0 Set HOTP counter to random value Imposta il contatore HOTP ad un valore casuale OTP code length: 6 digits Lunghezza codice OTP: 6 cifre OTP code length: 8 digits Lunghezza codice OTP: 8 cifre TOTP interval value Valore intervallo TOTP OMP part of Token ID Parte OMP dell'Token ID TT part of Token ID Parte TT dell'Token ID MUI part of Token ID Parte MUI dell'Token ID Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Impostazioni per inserire un codice HOTP attraverso combinazioni speciali di tasti (solo Tastiere USB) Erase Password Safe slot Cancella Slot Password Sicura Password Safe slot number Numero Slot Password Sicura Unlock Password Safe Sblocca Password Sicura The Nitrokey App is available as an icon in the tray bar. La Nitrokey App è disponibile come icona nella barra delle notifiche. The secret string you have entered is invalid. Please reenter it. La stringa segreta inserita non è valida. Per favore inseriscila nuovamente. <Select Password Safe slot> <Seleziona lo Slot Password Sicura> Password safe unlocked Password Sicura sbloccata AES keys not initialized. Please provide Admin PIN. Chiavi AES non inizializzate. Per favore inserisci il PIN Amministratore. Keys generated. Please unlock Password Safe again. Chiavi Generate. Per favore sblocca la Password Sicura nuovamente. Wrong admin password. PIN Amministratore errato. User not authenticated Utente non autenticato Reset Nitrokey's time? Reimposta l'ora sul Nitrokey? Locking device Blocco dispositivo Connecting device Connessione dispositivo <html><head/><body><p><span style=" font-weight:600; color:#a40000;">Entered OTP 'Secret Key' string is longer than supported by this device</span></p></body></html> Label shown when the OTP secret key is too long <html><head/><body><p><span style=" font-weight:600; color:#a40000;">La "Chiave Segreta" OTP inserita è troppo lunga per questo dispositivo.</span></p></body></html> secret is not passing validation. Il segreto non ha superato la validazione. Provided secret hex string is invalid. Please check input and try again. La stringa esadecimale del segreto non è valida. Per favore controlla e prova nuovamente. Details: Dettagli: WARNING: This Storage firmware version is old. Application may be unresponsive and unlocking encrypted volume may not work. Please update the firmware to the latest version. Guide should be available at: <br/><a href='https://www.nitrokey.com/en/doc/firmware-update-storage'>www.nitrokey.com/en/doc/firmware-update-storage</a>. ATTENZIONE: questa versione del firmware di archiviazione è obsoleta. L'applicazione potrebbe non rispondere e lo sblocco del volume crittografato potrebbe non funzionare. Si prega di aggiornare il firmware alla versione più recente. La guida dovrebbe essere disponibile su: <br/><a href='https://www.nitrokey.com/en/doc/firmware-update-storage'>www.nitrokey.com/en/doc/firmware-update-storage</a>. Nitrokey App Nitrokey App Overview Panoramica Unlock Encrypted Volume Sblocca Volume Cifrato Unlock Hidden Volume Sblocca Volume Nascosto Lock Device Blocca il dispositivo Help Aiuto Quit Esci Copy secret to clipboard Copia il segreto negli appunti Copy to clipboard Copia negli appunti Settings Impostazioni General Generale Show first-run message Mostra il messaggio del primo avvio Show warning when no partitions could be detected on Encrypted Volume (Linux only) Mostra messaggio quando nessuna partizione può essere identificata sul Volume Cifrato (Solo Linux) Show message about device's connection / disconnection Mostra un messaggio quando il dispositivo viene connesso / disconnesso Show main window when device connects Mostra la finestra principale quando il dipositivo viene connesso Hide main window when device disconnects Nascondi la finestra principale quando il dispositivo viene disconnesso Do not quit when the main window is closed Non uscire quando la finestra principale viene chiusa <html><head/><body><p>Translation file (needs restart)</p></body></html> <html><head/><body><p>Fila traduzioni (richiede riavvio)</p></body></html> Translation file (needs restart) File traduzioni (richiede riavvio) Debug log settings Impostazioni log di debug Path for debug log file: Percorso del file di log: Verbosity level: Livello verbosità: Select path Seleziona percorso Logging enabled Log abilitato Log to console Log su console Clipboard settings Impostazione appunti Time to store OTP secrets in clipboard (in seconds): Tempo di memorizzare delle Password OTP negli appunti (In secondi): Time to store Password Safe secrets in clipboard (in seconds): Tempo di memorizzazione delle Pasword Sicure negli appunti (in secondi): TIme to store Password Safe secrets in clipboard (in seconds): Tempo di memorizzazione delle Pasword Sicure negli appunti (in secondi): You can find application’s tray icon in system tray in the right down corner of your screen (Windows) or in the upper right (Linux, MacOS). È possibile trovare l'icona dell'applicazione nella barra delle notifiche nell'angolo in basso a destra dello schermo (Windows) o in alto a destra (Linux, MacOS). Idle Inattivo Would you like to show this message again? Vuoi che questo messaggio sia mostrato nuovamente? Device lock detected, please remove and insert the device again. If problem will occur again please: 1. Close the application 2. Reinsert the device 3. Wait 30 seconds and start application Rilevato il blocco del dispositivo, rimuovere e inserire nuovamente il dispositivo. Se il problema si ripresenta, per favore: 1. Chiudi l'applicazione 2. Reinserisci il dispositivo 3. Attendi 30 secondi e avvia nuovamente l'applicazione Warning: Application could not detect any partition on the Encrypted Volume. Please use graphical GParted or terminal fdisk/parted tools for this. Avviso: l'applicazione non è in grado di rilevare alcuna partizione sul Volume Crittografato. Si prega di utilizzare strumenti grafici GParted o su terminali come fdisk/parted. Would you like to be reminded again? Vuoi che ti venga ricordato nuovamente? Device connected. Waiting for initialization... Dispositivo connesso. Attendi per l'inizializzazione... Please run the application again to apply new settings. Per favore riavvia l'applicazione per applicare le nuove impostazioni. Would you like to quit now? Desideri uscire adesso? Debug file location (will be overwritten) Posizione file debug (verrà sovrascritto) current: corrente: Communication error. Please reinsert the device. Errore di comuncazione. Per favore inserisci nuovamente il dispositivo. Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. ATTENZIONE: Il volume cifrato non è sicuro, Seleziona l'opzione "Inizializza dispositivo" dal menu contestuale. PinDialog Password dialog Finestra Password Enter card password: Inserisci la password della scheda: Show password Mostra PIN/password &Cancel &Cancella &OK &Ok Your PIN is too long! Use not more than 30 characters. Il tuo PIN è troppo lungo! Usa non più di 30 caratteri. Your PIN is too short. Use at least 6 characters. Il tuo PIN è troppo corto. Usa almeno 6 caratteri. Warning: Default PIN is used. Please change the PIN. Attenzione: PIN predefinito in uso. Per favore cambia il PIN. Tries left: %1 Tentativi rimanenti: %1 Device is not yet initialized. Please try again later. Il dispositivo non è stato ancora inizializzato. Per favore riprova più tardi. Enter card PIN Inserisci il PIN della scheda Enter user PIN Inserisci il PIN Utente User PIN: PIN Utente: Enter admin PIN Inserisci il PIN Amministratore Admin PIN: PIN Amministratore: Enter Firmware Password Inserisci la Password del Firmware Enter Firmware Password: Inserisci la Password del Firmware: Enter password for hidden volume Inserisci la password per il Volume Nascosto Enter password for hidden volume: Inserisci la password per il Volume Nascosto: Would you like to so now? Vuoi farlo ora? Please enter the new PIN/password Per favore inserisci il nuovo PIN/password QApplicatio WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? ATTENZIONE! L'ora del tuo computer e del Nitrokey non sono sincronizzate. Il tuo computer potrebbe essere configurato con l'ora sbagliata o il tuo Nitrokey potrebbe essere stato attaccato. Se un utente malintenzionato o un malware può aver utilizzato il tuo Nitrokey, è necessario ripristinare immediatamente i segreti delle password usa e getta (OTP) configurate. Se l'ora del tuo computer è sbagliata, configurala correttamente e ripristina l'ora di Nitrokey. Reimpostare il tempo sul Nitrokey? QApplication Communication error. Please reinsert the device. Errore di comuncazione. Per favore inserisci nuovamente il dispositivo. The secret string you have entered is invalid. Please reenter it. La stringa segreta inserita non è valida. Per favore inseriscila di nuovo. Details: Dettagli: Warning: Encrypted volume is not secure, Select "Initialize device" option from context menu. ATTENZIONE: Il volume cifrato non è sicuro, Seleziona l'opzione "Inizializza dispositivo" dal menu contestuale. Critical error encountered. Please restart application. Message: Riscontrato errore critico. Per favore riavvia l'applicazione. Messaggio: WARNING! The time of your computer and Nitrokey are out of sync. Your computer may be configured with a wrong time or your Nitrokey may have been attacked. If an attacker or malware could have used your Nitrokey you should reset the secrets of your configured One Time Passwords. If your computer's time is wrong, please configure it correctly and reset the time of your Nitrokey. Reset Nitrokey's time? ATTENZIONE! L'ora del tuo computer e del Nitrokey non sono sincronizzate. Il tuo computer potrebbe essere configurato con l'ora sbagliata o il tuo Nitrokey potrebbe essere stato attaccato. Se un utente malintenzionato o un malware può aver utilizzato il tuo Nitrokey, è necessario ripristinare immediatamente i segreti delle password usa e getta (OTP) configurate. Se l'ora del tuo computer è sbagliata, configurala correttamente e ripristina l'ora di Nitrokey. Reimpostare il tempo sul Nitrokey? Stick20ResponseDialog Progress Avanzamento StorageActions Enabling encrypted volume Unlocking encrypted volume Encrypted volume enabled Encrypted volume unlocked Could not enable encrypted volume. Could not unlock encrypted volume. Wrong password. Wrong PIN. Disabling encrypted volume Locking encrypted volume Encrypted volume disabled Encrypted volume locked Please enable the encrypted volume first. Please unlock the encrypted volume first. Enabling hidden volume Unlocking hidden volume Hidden volume enabled Hidden volume unlocked Could not enable hidden volume. Could not unlock hidden volume. Disabling hidden volume Locking hidden volume Hidden volume disabled Hidden volume locked Locking device Bloccaggio dispositivo This activity locks your hidden volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding. Questa attività blocca il tuo volume nascosto. Procedere? Per evitare la perdita di dati, per favore smonta le partizioni prima di procedere. Status code: %1 Codice di stato: %1 This activity locks your encrypted volume. Do you want to proceed? To avoid data loss, please unmount the partitions before proceeding. Questa attività blocca il tuo volume cifrato. Procedere? Per evitare la perdita di dati, per favore smonta le partizioni prima di procedere. To complete the lock procedure, please remove and reconnect the Nitrokey. Per completare la procedura di blocco, per favore rimuovi e riconnetti la Nitrokey. Could not lock encrypted volume. Impossibile bloccare il volume cifrato. Could not lock hidden volume. Impossibile bloccare il volume nascosto. Device locked Dispositivo bloccato Could not lock device. Impossibile bloccare il dispositivo. Device set in update mode Dispositivo in modalità aggiornamento Device could not be set in update mode. Impossibile commutare il dispositovo in modalità aggiornamento. Firmware exported Firmware esportato Could not export firmware. Impossibile esportare il firmware. WARNING: Generating new AES keys will destroy the encrypted volumes, hidden volumes, and password safe! Continue? Attenzione: La generazione di nuove chiavi AES distruggerà i volumi cifrati, i volumi nascosti e le password sicure. Continuare? Generating new AES keys Generazione nuove chiavi AES New AES keys generated Nuove chiavi AES generate Keys could not be generated. Le chiavi non possono essere generate. Could not clear SD card. Impossibile cancellare la memoria SD. Communication issue. Problema di comunicazione. Flag cannot be cleared. Il flag non può essere azzerato. Flag cleared. Flag azzerato. Cannot set unencrypted volume read-only Impossibile impostare il volume non cifrato in sola lettura Unencrypted volume set read-only Volume non cifrato impostato in sola lettura Cannot set unencrypted volume read-write Impossibile impostare il volume non cifrato in lettura/scrittura Unencrypted volume set read-write Volume non cifrato impostato in lettura/scrittura Cannot set encrypted volume read-only Impossibile impostare il volume cifrato in sola lettura Encrypted volume set read-only Volume cifrato impostato in sola lettura Cannot set encrypted volume read-write Impossibile impostare il volume cifrato in lettura/scrittura Encrypted volume set read-write Volume cifrato in lettura/scrittura Functionality not implemented in current version Funzionalità non implementata nella versione corrente Hidden volume created Volume nascosto creato Hidden volume could not be created. Il volume nascosto non può essere creato. Tray &Help &Aiuto &Set unencrypted volume read-only Impo&sta il volume non cifrato in modalità sola lettura &Set unencrypted volume read-write Impo&sta il volume cifrato in modalità lettura/scrittura &Lock stick hardware B&locca il dispositivo hardware Active (debug mode) Attivo (modo debug) Active Attivo Nitrokey is not connected! Nitrokey non collegata! Unlock password safe Sblocca password sicura &OTP &OYP &Factory reset Reimpostazione di &Fabbrica &Change User PIN &Cambia il PIN Utente &Change Admin PIN &Cambia il PIN Amministratore &Debug &Debug &Overview Pan&oramica &Quit &Esci &About Nitrokey &Informazioni su Nitrokey &OTP and Password safe Sicurezza &OTP e Password &Unlock encrypted volume &Sblocca volume cifrato &Lock encrypted volume &Blocca Volume cifrato &Unlock hidden volume &Sblocca Volume Nascosto &Lock hidden volume &Blocca Volume Nascosto &Change Firmware Password &Cambia la Password del Firmware &Enable firmware update &Abilita l'aggiornamento del Firmware &Export firmware to file &Esporta il firmware su File &Destroy encrypted data &Distruggi i dati cifrati &Initialize device &Inizializza il dispositivo &Initialize storage with random data &Inizializza la memoria con dati casulai &Set encrypted volume read-only &Imposta il volume cifrato in modalità solo lettura &Set encrypted volume read-write &Imposta il volume cifrato in modalità lettura/scrittura &Setup hidden volume &Configura il Volume Nascosto &Disable 'initialize storage with random data' warning &Disabilita l'avviso "Inizializza la memoria con dati casuali" &Reset User PIN &Reimposta il PIN Utente &Lock Device &Blocca il dispositivo Smartcard or SD card are not ready Smart-card o memoria SD non pronta Passwords Password (empty) (vuoto) Configure Configura Special Configure Configura speciale Long operation in progress: %1% Operazione lunga in corso: %1% UpdateDialog Firmware update Aggiornamento Firmware <html><head/><body><p>When you select &quot;OK&quot; the device enters the <br/>firmware update mode. There is no way back!<br/>Please read the <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;">documentation </span></a>how to <br/>update the firmware.</p><p>Continue entering the firmware update mode?</p><p><br/></p></body></html> <html><head/><body><p>Selezionando &quot;OK&quot; il dipositivo entrerà nel<br/>modo aggiornamento firmware. Non c'è alcun modo per tornare indietro!<br/>Leggi il documento <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;"> </span></a>su come<br/>aggiornare il firmware.</p><p>Continuare con il modo aggiornamento firmware?</p><p><br/></p></body></html> main Nitrokey App - Manage your Nitrokey sticks Nitrokey App - Gestisci le tue chiavi Nitrokey Clear all application's settings Cancella tutte le impostazioni dell'applicazione Enable debug messages Abilita i messaggi di debug Save debug log to file with name <log-file-name> (experimental) Salva il log di debug su un file con nome <log-file-name> (sperimentale) Save debug log to App's window (experimental) Salva il log di debug nella finestra dell'applicazione (sperimentale) Set debug level, 0-4 Imposta il levello di debug, 0-4 Set delay between commands sent to device (in ms) to <delay> Imposta il ritardo fra l'invio dei comandi al dispositivo (in ms) a <delay> Show additional information about binary Mostra informazioni addizionali relativamente al binario Enable extra administrative functions Abilita le funzioni amministrative aggiuntive List available languages Elenca le lingue disponibili Load translation file with given name and store this choice in settings file. Carica il file delle traduzioni specificato e memorizza questa scelta nel file di configurazione. securitydialog Dialog Dialogo <html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Security Information</span></p><p>Please read the following carefully.</p><p><span style=" font-weight:600;">PIN Protection</span></p><p>Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.</p><p><span style=" font-weight:600;">Physical Protection</span></p><p>All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.</p><p><span style=" font-weight:600;">Hidden Volumes</span></p><p>Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are however stored on a flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.</p></body></html> <html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Informazioni di sicurezza</span></p><p>Leggi le seguenti istruzioni con molta attenzione.</p><p><span style=" font-weight:600;">Protezione PIN</span></p><p>Nitrokey è protetta da un PIN Utente e da un PIN Amministratore. Il PIN Utente può sbloccare il disco cifrato, la password sicura, la smart-card e (se abilitato) le password Usa e Getta (One-Time Password - OTP). Le password OTP di base non sono protette da PIN in quanto usate solo come fattori secondari. La smart-card è sbloccata all'inserimento del PIN, a prescindere dal motivo di inserimento del PIN stesso. Il PIN Amministratore può essere usato per configurare le impostazioni e per aggiungere o rimuovere voci. Devi cambiare entrambi i PIN di base e mantenerli riservati. Se il PIN Utente e il PIN Amministratore sono inserriti erroneamente tre volte ciascuno, o se la smart-card è stata ripristinata ai valori di fabbrica, tutti i tuoi dati sensibili saranno persi irrimediabilmente.</p><p><span style=" font-weight:600;">Protezione Fisica</span></p><p>Tutti i dati sensibili sono cifrati e assicurati dagli attacchi fisici. Questo non vale per le password OTP perché sono usate solo come fattore secondario.</p><p><span style=" font-weight:600;">Volumi Nascosti</span></p><p>I Volumi Nascosti richiedono che la memoria di massa sia inizializzata con dati casuali. I Volumi Nascosti sono protetti contemporaneamente dal PIN Utente e da una password separata che è differente per ogni Volume Nascosto. Senza la conoscenza di entrambi, PIN Utente e password, il Volume Nascosto non può essere trovato e la sua esistenza non essere provata o negata. La password per il Volume Nascosto deve essere sufficientemente lunga e robusta per proteggersi da un attacco di forza bruta. I Volumi Nascosti, tuttavia, sono archiviati su una memoria flash con livellamento dell'usura integrato (wear levelling), e le informazioni potrebbero potenzialmente essere divulgate ad un aggressore sofisticato, rivelando in tal modo l'esistenza di volumi nascosti.</p></body></html> OK Ok I read and understood this security warning Ho letto ed ho ben compreso gli avvisi di sicurezza stick20HiddenVolumeDialog Setup hidden volume Impostazione Volume Nascosto <html><head/><body><p><span style=" font-weight:600;">You should understand the properties of hidden volumes before proceeding. It can destroy your encrypted data! <br/>Please read </span><a href="https://www.nitrokey.com/documentation/hidden-volumes"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">these instructions</span></a><span style=" font-weight:600;"> first.</span></p></body></html> <html><head/><body><p><span style=" font-weight:600;">Dovresti ben comprendere le proprietà dei Volumi Nascosti prima di procedere. Potresti involontariamente distruggere tutti i tuoi dati cifrati! <br/>Per favore leggi </span><a href="https://www.nitrokey.com/documentation/hidden-volumes"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">queste istruzioni</span></a><span style=" font-weight:600;"> prima di andare avanti.</span></p></body></html> <html><head/><body><p>1. You may want to copy some innocuous files to the encrypted data.<br/>2. Configure hidden volumes in this dialogue. <br/>3. Once you configured a hidden volume you must not use/write to the encryption volume anymore. Otherwise it may destroy the data in your hidden volume.</p></body></html> <html><head/><body><p>1. Potresti voler copiare alcuni file sensibili nel Volume Nascosto.<br/>2. Configurare i Volumi nascosti in questa finestra.<br/>3. Una volta configurato un Volume Nascosto non è più possibile utilizzare/scrivere sul volume cifrato, altrimenti potresti distruggere i dati contenuti nel Volume Nascosto.</p></body></html> Password settings Impostazione Password Password strength: Robustezza Password: length lunghezza lower case minuscole upper case maiuscole numbers numeri symbols simboli Hidden Volume settings Impostazioni Volume Nascosto Hidden volume slot 1 Volume Nascosto Slot 1 Hidden volume slot 2 Volume Nascosto Slot 2 Hidden volume slot 3 Volume Nascosto sSot 3 Hidden volume slot 4 Volume Nascosto Slot 4 Password: Password: Show password Mostra password Your password is too short. Use at least 8 characters. Password troppo corta! Usa almeno 8 caratteri. The passwords are not identical Le password non sono identiche Wrong size of hidden volume Dimensione del Volume Nascosto errata Unit: Unità: % % MB MB GB GB Hidden volume not positioned in unwritten space. Please set your volume between %1% and %2% of total SD card size. Volume Nascosto non posizionato su uno spazio libero. Per favore imposta il tuo volume fra %1% e %2% della dimensione totale dalla scheda SD. Very Weak Molto debole Weak Debole Medium Media Strong Robusta Very Strong Molto Robusta The unwritten area available for hidden volume is between %1 % and %2 % of the storage size L'area libera disponibile per il Volume Nascosto è compresa fra %1% e %2% della dimensione della memoria Storage capacity: %1GB Capacità di memorizzazione: %1GB Start hidden volume at %1 of the encrypted storage: Inizia il Volume Nascosto a %1 della memoria cifrata: End hidden volume at %1 of the encrypted storage: Finisci il Volume Nascosto a %1 della memoria cifrata: Hidden volume password Password del Volume Nascosto Please use shift+tab key shortcut for instructions Per favore, usa i tasti shift-tab per le istruzioni Hidden volume password (repeated) Password del Volume Nascosto (ripeti) Slot under which hidden volume information will be stored Slot dove memorizzare le informazioni del Volume Nascosto Use this as hidden volume size unit Usa questo come unità della dimensione del Volume Nascosto Size will be rounded down to integral percent of total storage size (%1MB) La dimensione sarà arrotondata alla percentuale intera inferiore della dimensione totale della memoria (%1MB) stick20LockFirmwareDialog Lock Firmware Blocca Firmware <html><head/><body><p>When you select &quot;OK&quot; the stick lock the firmware and close the hardware debug port.This disables any external hardware access to the data in the device (processor).</p><p>There is no way back! </p><p>After this you can't update the firmware.</p></body></html> <html><head/><body><p>Quando selezioni &quot;OK&quot; il dispositivo bloccherà il firmware e chiuderà la porta di debug dell'hardware. Questo disabilita qualsiasi accesso hardware esterno ai dati sul dispositivo (processore).</p><p>Non è possibile tornare indietro!</p><p>Dopo questo non sarà possibile aggiornare nuovamente il firmware.</p></body></html> nitrokey-app-1.3.2/i18n/nitrokey_pl.qm0000644000175000017500000022765113404176655017206 0ustar janjan00000000000000<¸dÊÍ!¿`¡½ÝB %¥² ¼û;Ò;|+;¢ó134NÈYoYzø7Z£´Ñ4ÔX_ì0YBû%Z²)Ê_5ßB:g‚Œp¼”€6˜ÅqfÛ{Oæ Hè$%¸(4²˜*ì0Η+ŒÑÞ9ôOpíA ºŒ|D$äW-G=Š^JG–ÄoME^ªÌTƒŠ_ÉYÙ ©Z6`|¾Z6z~Ù\Pz±\œZÿkØ%·qqOŒ×v±º#víÇlyþàöæ"sª’º†³ Ðß•´Ö±—·î® 2¾ñUÔkÄ•šìÍbk:íÿþmbïØ~7€RGXåÕ"oÕÓ$d¤H+ÛuÐÏ-Dä*-cîmÃKé/Ý\Q´&¥\Q´¨¹\Q´À\œšõ^?`n_;”Eu_*œ{÷~Ö‰jþ‚‹ˆþËn™ðÐ{ôblÖ€éT5â)i'õôÊGÐÑRT^æŽ ‰»Q uÐsk>)9”BS>;k³à•@j¤µBqc_FDÆOw)Gçh¾JìTgYAƒeQu¦|iè“|^JC}ÂðMðY„)Óo„PÞh]“FWò™Ùu€aª¹·ËϬáÑ3¬áÒ¥¬áÓ¬áÔ‰³å4ºáÊÔùÌÉY1ö(³¶ÑZOÎ5](Î5¿Ô+–¨ú303\P®TÁÊ ék“1Aç…VŽC¢ˆýn[5ÇN™Bç¶Zé¡yŸí %" úLnüß Dq× „ 5/u*øBN`WŒ[h¥Šzpµ!Ìz°Åªz°ÅÖ|{@Þˆ˜bAR˜I¼BË›ñ_ù¯ƒWÿW¹h¥ÕƒÈrŽ¡#Ϧå× ÿ–E\زàtUòàt¸ ‡:F$§5·ˆ;9®|ì;°½/=Fs ðPXP]QNÀ+*XžÒ X4ž$¨eu‰|n_7NÂnÞþ\oFž´ávMz†‰¥ÍY¡ê¿’1§Ž‚ ª‹Ã[«–G…«Ç O丰jt¿ 4ÂíuuÃŒãŒÄñ^ŸwÈ9T¸}ѯŠþÞɼîëF0÷]÷¯¥ÍÁgéåód‰Œ–EÏ»'ˆ¥Ð3CnKnAÏD‹ýJÕqu¾JÕruÿTÉJ¦Uª§`ëN`£g}ãhLÎŒpxÊXŠqàê~!€¥”¯ã3ê¯ã33·ÂŽS›ÓÚ_—Þ¼N,îáasi'ñ>t}ôÎ&ªÉÒvîÊ !h±"%£¾É,N¨ü0xÊ3ÄÞ§Gç~iÚIÕÅ[Ðõµÿˆ\ª¦”W$F\ »G\§¨„]à¯ß¾´SÐ=ž«œÕR´Zfן†Yä`n¿SñNÀ*¥ ©ããÚ 5“à 6èáþ9Äj¿`šN!g§®?u*½ƒÏŒÚ#Ì fdXϯ)ØTÄ iskȇéœÊÄkóñ>TËúþÁª q¾b 2—ž;¥ 5ÑcA 5Ñׯ :s~Å• DxÞ¥% IHe®M Oþz [0ªOt ^‰Ó­M `gt$4 p/ùâ© qkäQº äañ ŽóœÝ µ‡» ·NY‰Û ¹çÁ »f©¯ ¾>¾6 Ô£¥¶• Õ.‰ÊH ë×n> â鯭 ç)¹z ´.R {DbÝ ŒÎŸ ô„½ú äMÅ Ìà 02Î4‹ >ªt Ckê¾ FÞ%… FøçÌx h¶ÞS €|J …^~¢ ˆ²^½b ˜Iœ¢À ¦ÇÄEë ®>3Ø( ®>úlT ®>ú$ µûÊW Â$îDý Äí.°¿ ÙQ lˆ –CË é¤Š óž n !Ö®Ùœ $Ð+­ -Ònc´ /Ù¾’ó 7‡2š˜ B€^äô OÊÿwè Qù¤QS cX gäc’ j:êÎ lS?ª_ ¯EÎÁ ³þzÌ Y1­ ¾Yt`4 ÍIN: ÍINt ÍkNÿ Ø¡‹¤ Ø¡Ù? Ú¡5‹K Þ©5¯è ßN  âË.~b ëÏUØé ù N úìô^ª 3…í ]·§ï Õt"à &•Õð ±Ää 3 ¥v¢ 3ïùÖ© >¦Jq• A_õ A®E> EŠ©J NHÞo­ OG}s S=U×C X1%ó \Õº¿ hÞ§‹ q;ž²0 „]3h ‰á‰UF ‹÷eÑY ”@¹­‹ •IZ#5 ˜ÃÚ¡Ù žò¾ƒ §0þÀ° ´VôO »sx4 ÄÓù{‘ Éʧjˆ Éä§Ñª Ê_—ÿœ ÌÎ 2½ Ó§þDZ Õü¾m ÝØò à „¾Ù å@~Éî Öþ?ã ˆ¹ ÎÁÁZ )}›ì *Ž¥ *'^!ê *'^£p ,jBü @þJZç LnEE `º% díœw l>NBO tIÃg u_Zš ‘¥ãCM ’üôÀ/ °út¨D ÄÈ<Vû Ò2u]‡ àlÔv@ áën—{ æ&ñ æöørÒ í:…,F îûôJý ðZ<g­ ùx„µ£ ®GgµŠê&p¬eB2w”MÛƒz[¬:€¿e>ª#€gDcY­‹mÕÞ²©D^æÄ{™ÖNï9õjúóí®eoúªéT FrR c)ÓÁÁ/ˆO½_È%ãI”*êcGD– xoVÍiRš[LY[Lz‡re'®žŠiQN&ZIÞ²¾èõ‹‘¢ÑF®𔾳=› ýk¤œœ… ŸŽ»Ñ¤›ê6ͯêCæ‰IæÔtøý Þ©™i"h8 Karta SD jest niedostpna  SD card is not accessible  AboutDialogL Karta inteligentna jest niedostpna  Smartcard is not accessible  AboutDialogH *** Usuwanie danych w toku ***' *** Clearing data in progress *** AboutDialog< *** BBd komunikacji ***! *** Communication error *** AboutDialogN *** Firmware jest zablokowane *** *** Firmware is locked *** AboutDialogÿÿÿÿ%1 GB AboutDialogZ(Niewyczyszczono przy u|yciu losowych danych)(Not erased with random data) AboutDialog(ukryte)(hidden) AboutDialogP<html><head/><body><p><a href="https://www.nitrokey.com/start"><span style=" text-decoration: underline; color:#c80636;">Instrukcje i pomoc</span></a></p></body></html>«

Instructions and help

 AboutDialog(<html><head/><body><p><span style=" font-size:10pt; font-style:italic;">Copyright %1 by NitrokeyUG. </span></p><p><span style=" font-size:10pt; font-style:italic;">Licencja na to oprogramowanie udzielana jest na podstawie </span><a href="https://www.gnu.org/licenses/"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#c80636;">GNU General Public License v3.</span></a><span style=" font-size:10pt; font-style:italic;"> TBumaczenie polskiej wersji aplikacji: Grzegorz TrzciDski.</span></p><p><a href="https://nitrokey.com"><span style=" text-decoration: underline; color:#c80636;">www.nitrokey.com</span></a></p></body></html>C

Copyright %1 by NitrokeyUG.

This software is licensed under the GNU General Public License v3.

www.nitrokey.com

 AboutDialogø<html><head/><body><p>Ta aplikacja umo|liwia konfiguracj i korzystanie z Nitrokey Pro i Nitrokey Storage.</p></body></html>

This application allows you to configure and use the Nitrokey Pro and Nitrokey Storage.

 AboutDialog\<span style="color:#c80636">Ostrze|enie</span>*Warning AboutDialogO programieAbout AboutDialogAktywnyActive AboutDialogAdministrator:Admin: AboutDialog"Wersja aplikacji: App version: AboutDialogJNie mo|na otworzy okna dialogowego: Cannot open dialog:  AboutDialog(Numer seryjny karty:Card serial number: AboutDialog$SzczegóBowy statusDetailed Status AboutDialog*Zaszyfrowany wolumin:Encrypted volume: AboutDialog Wersja firmware:Firmware version: AboutDialogUkryty wolumin:Hidden Volume: AboutDialogFLicencje i komponenty firm trzecich!Licenses and 3rd-party components AboutDialogLogoLogo AboutDialog0Znaleziono now kart SDNew SD card found AboutDialog@Brak aktywnego klucza Nitrokey No active Nitrokey  AboutDialog@Brak poBczenia Spróbuj ponownieNo connection Please retry AboutDialogNieaktywny Not active AboutDialogOKOK AboutDialogLLiczniki prób ponownego podania hasBa:Password retry counters: AboutDialog TYLKO DO ODCZYTU READ ONLY AboutDialogODCZYT/ZAPIS READ/WRITE AboutDialog.Identyfikator karty SD:SD ID: AboutDialog StatusStatus AboutDialogtPami USB nie jest zabezpieczona! Inicjalizuj urzdzenie.&Stick is not secure! Select Init keys. AboutDialog$Pojemno[ pamici:Storage Capacity: AboutDialog0Niezaszyfrowany wolumin:Unencrypted volume: AboutDialogU|ytkownik:User: AboutDialogHNieprawidBowy PIN. Spróbuj ponownie.Wrong PIN. Please try again.Authentication(Dziennik debugowania Debug Log DebugDialog znaki/ów charsDialogChangePassword|<html><head/><body><p><span style=" font-style:italic;">Nitrokey zapobiega odgadywaniu ataków przy u|yciu metody Brute Force, pozwalajc na maksymalnie 3 nieprawidBowe próby podania kodu PIN, w zwizku z tym wystarczy kod PIN skBadajcy si z %1cyfr. Kod PIN musi zawiera od %1 do %2 znaków.</span></p></body></html>

Nitrokey prevents against brute force password guessing attacks by allowing a maximum of 3 incorrect PIN attempts. Therefore a PIN of %1 digits is sufficient. The PIN must be between %1 and %2 characters.

DialogChangePassword,ZmieD hasBo firmware'uChange Firmware PasswordDialogChangePassword6Zmiana kodu PIN u|ytkownikaChange user PINDialogChangePassword.Potwierdz nowy kod PIN:Confirm New PIN:DialogChangePassword*Potwierdz nowe hasBo:Confirm New Password:DialogChangePasswordFPotwierdz nowy kod PIN u|ytkownika:Confirm New User PIN:DialogChangePassword@Aktualny kod PIN administratora:Current Admin PIN:DialogChangePassword4Aktualne hasBo firmware'u:Current Firmware Password:DialogChangePassword4Aktualny kod PIN lub hasBoCurrent PIN or passwordDialogChangePassword:Aktualny kod PIN u|ytkownika:Current User PIN:DialogChangePasswordvAktualne hasBo jest niepoprawne. Prosz spróbowa ponownie..Current password is not correct. Please retry.DialogChangePasswordzUrzdzenie nie jest jeszcze gotowe. Spróbuj ponownie pózniej.6Device is not yet initialized. Please try again later.DialogChangePassword6Nowy kod PIN lub nowe hasBoNew PIN or passwordDialogChangePasswordNowy kod PIN:New PIN:DialogChangePasswordNowe hasBo: New Password:DialogChangePassword2Nowy kod PIN u|ytkownika: New User PIN:DialogChangePassword8Nowe hasBo zostaBo ustawioneNew password is setDialogChangePassword@Resetowanie kodu PIN u|ytkownikaReset User PINDialogChangePassword,PozostaBa liczba prób:Retry count left:DialogChangePassword8Ustaw kod PIN administratora Set Admin PINDialogChangePassword2Ustaw kod PIN u|ytkownika Set User PINDialogChangePasswordPoka| kod PINShow PINDialogChangePasswordPoka| hasBo Show passwordDialogChangePassword@HasBo firmware nie posiada licznika ponownych prób, dlatego nie zapobiega odgadywania hasBa metod Brute Force. HasBo bezpieczne i zBo|one nale|y tworzy za pomoc: maBych i du|ych liter, cyfr i znaków specjalnych; o dBugo[ci od %2 do %3 znaków. <br/>Domy[lnym hasBem firmware jest: '%1'.KThe Firmware password doesn’t have a retry counter, and therefore doesn’t prevent against password guessing attacks. A secure and complex password should be created with the use of: lower and upper case letters, numbers and special characters; with a length between %2 and %3 characters.
Default firmware password is: '%1'.DialogChangePassword8Maksymalna dBugo[ hasBa to $The maximum length of a password is DialogChangePassword6Minimalna dBugo[ hasBa to $The minimum length of a password is DialogChangePasswordFMinimalna dBugo[ starego hasBa to *The minimum length of the old password is DialogChangePasswordVNowe hasBo nie jest takie samo w obu polach)The new password entries are not the sameDialogChangePasswordÚNiestety, nie masz ju| wicej prób podania hasBa. Zapoznaj si z instrukcj resetowania hasBa administratora.aUnfortunately you have no more trials left. Please check instruction how to reset Admin password.DialogChangePasswordøNiestety, nie masz ju| wicej prób podania hasBa. U|yj opcji "Resetowanie kodu PIN u|ytkownika" z menu, aby zresetowa hasBojUnfortunately you have no more trials left. Please use 'Reset User PIN' option from menu to reset passwordDialogChangePasswordÄWARNING! W przypadku utraty hasBa do firmware'u nie mo|na zaktualizowa ani zresetowa Nitrokey'a!RWARNING! If you lose your Firmware password, Nitrokey can’t be updated or reset!DialogChangePasswordNInformacje o licencji (ESC aby zamkn)!License information (ESC to Exit) LicenseDialog¢(Zalecenie: U|yj TOTP dla aplikacji internetowych i HOTP dla aplikacji lokalnych)O(Recommendation: Use TOTP for web applications and HOTP for local applications) MainWindow8**************************** ******************************** MainWindow...... MainWindow(0000000000000000000000000000000000000000 MainWindow 6 cyfr6 digits MainWindow 8 cyfr8 digits MainWindow4<Wybierz slot banku haseB>"))); for (i = 0; i < PWS_SLOT_COUNT; i++) { if (libada::i()->getPWSSlotStatus(i)) { ui->PWS_ComboBoxSelectSlot->addItem( QString(tr("Slot ")) .append(QString::number(i + 1, 10)) .append(QString(" [") .append(QString::fromStdString(libada::i()->getPWSSlotName(i))) .append(QString("]")))); } else { ui->PWS_ComboBoxSelectSlot->addItem( QString(tr("Slot ")).append(QString::number(i + 1, 10))); } } } else { ui->PWS_ComboBoxSelectSlot->addItem(QString(tr("Unlock password safe"))); } } catch (LongOperationInProgressException &e){ long_operation_in_progress = true; return; } ui->PWS_ComboBoxSelectSlot->setEnabled(PWS_Access); ui->PWS_ButtonEnable->setVisible(!PWS_Access); ui->PWS_Lock->setVisible(PWS_Access); ui->PWS_EditSlotName->setMaxLength(PWS_SLOTNAME_LENGTH); ui->PWS_EditPassword->setMaxLength(PWS_PASSWORD_LENGTH); ui->PWS_EditLoginName->setMaxLength(PWS_LOGINNAME_LENGTH); ui->PWS_CheckBoxHideSecret->setChecked(true); ui->PWS_EditPassword->setEchoMode(QLineEdit::Password); } void MainWindow::on_PWS_ButtonClearSlot_clicked() { const auto item_number = ui->PWS_ComboBoxSelectSlot->currentIndex(); const int slot_number = item_number - 1; if (slot_number<0){ return; } bool answer = csApplet()->yesOrNoBox(tr("WARNING: Are you sure you want to erase the slot?"), false); if (!answer){ return; } if (!libada::i()->getPWSSlotStatus(slot_number)) // Is slot active? { csApplet()->messageBox(tr("Slot is erased already.")); return; } try{ libada::i()->erasePWSSlot(slot_number); ui->PWS_EditSlotName->setText(""); ui->PWS_EditPassword->setText(""); ui->PWS_EditLoginName->setText(""); ui->PWS_ComboBoxSelectSlot->setItemText( item_number, tr("Slot ").append(QString::number(slot_number + 1))); csApplet()->messageBox(tr("Slot has been erased successfully.")); emit PWS_slot_saved(slot_number); } catch (CommandFailedException &e){ csApplet()->warningBox(tr("Can't clear slot.")); } } void clear_free_cstr(char *_cstr){ auto max_string_length = 30ul; volatile char* cstr = _cstr; for (size_t i = 0; i < max_string_length; ++i) { if (cstr[i] == 0) break; cstr[i] = ' '; } free((void *) _cstr); } #include "src/core/ThreadWorker.h" void MainWindow::on_PWS_ComboBoxSelectSlot_currentIndexChanged(int index) { auto dummy_slot = index <= 0; PWS_set_controls_enabled(!dummy_slot); if (dummy_slot) return; //do not update for dummy slot index--; if (!PWS_Access) { return; } ui->PWS_ComboBoxSelectSlot->setEnabled(false); ui->PWS_progressBar->show(); connect(this, SIGNAL(PWS_progress(int)), ui->PWS_progressBar, SLOT(setValue(int))); new ThreadWorker( [index, this]() -> Data { Data data; data["slot_filled"] = libada::i()->getPWSSlotStatus(index); emit PWS_progress(100*1/4); if (data["slot_filled"].toBool()) { data["name"] = QString::fromStdString(libada::i()->getPWSSlotName(index)); emit PWS_progress(100*2/4); //FIXME use secure way auto pass_cstr = nm::instance()->get_password_safe_slot_password(index); data["pass"] = QString::fromStdString(pass_cstr); clear_free_cstr(const_cast(pass_cstr)); emit PWS_progress(100*3/4); auto login_cstr = nm::instance()->get_password_safe_slot_login(index); data["login"] = QString::fromStdString(login_cstr); clear_free_cstr(const_cast(login_cstr)); } emit PWS_progress(100*4/4); return data; }, [this](Data data){ if (data["slot_filled"].toBool()) { ui->PWS_EditSlotName->setText(data["name"].toString()); ui->PWS_EditPassword->setText(data["pass"].toString()); ui->PWS_EditLoginName->setText(data["login"].toString()); } ui->PWS_ComboBoxSelectSlot->setEnabled(true); QTimer::singleShot(2000, [this](){ ui->PWS_progressBar->hide(); }); }, this); } void MainWindow::PWS_set_controls_enabled(bool enabled) const { ui->PWS_EditSlotName->setText(""); ui->PWS_EditLoginName->setText(""); ui->PWS_EditPassword->setText(""); ui->PWS_EditSlotName->setEnabled(enabled); ui->PWS_EditLoginName->setEnabled(enabled); ui->PWS_EditPassword->setEnabled(enabled); ui->PWS_ButtonSaveSlot->setEnabled(enabled); ui->PWS_ButtonClearSlot->setEnabled(enabled); ui->PWS_CheckBoxHideSecret->setEnabled(enabled); ui->PWS_ButtonCreatePW->setEnabled(enabled); } void MainWindow::on_PWS_CheckBoxHideSecret_toggled(bool checked) { ui->PWS_EditPassword->setEchoMode(checked ? QLineEdit::Password : QLineEdit::Normal); } void MainWindow::on_PWS_ButtonSaveSlot_clicked() { const auto item_number = ui->PWS_ComboBoxSelectSlot->currentIndex(); int slot_number = item_number - 1; if(slot_number<0) return; if(ui->PWS_EditSlotName->text().isEmpty()){ csApplet()->warningBox(tr("Please enter a slotname.")); return; } if(ui->PWS_EditPassword->text().isEmpty()){ csApplet()->warningBox(tr("Please enter a password.")); return; } try{ nm::instance()->write_password_safe_slot(slot_number, ui->PWS_EditSlotName->text().toUtf8().constData(), ui->PWS_EditLoginName->text().toUtf8().constData(), ui->PWS_EditPassword->text().toUtf8().constData()); emit PWS_slot_saved(slot_number); auto item_name = tr("Slot ") .append(QString::number(item_number)) .append(QString(" [") .append(ui->PWS_EditSlotName->text()) .append(QString("]"))); ui->PWS_ComboBoxSelectSlot->setItemText( item_number, item_name); csApplet()->messageBox(tr("Slot successfully written.")); } catch (CommandFailedException &e){ csApplet()->messageBox(tr("Can't save slot. %1").arg(e.last_command_status)); } catch (DeviceCommunicationException &e){ csApplet()->messageBox(tr("Can't save slot. %1").arg(tr(Communication_error_message))); } } void MainWindow::on_PWS_ButtonClose_pressed() { hide(); } void MainWindow::PWS_Clicked_EnablePWSAccess() { do{ try{ auto user_password = auth_user.getPassword(); if(user_password.empty()) return; nm::instance()->enable_password_safe(user_password.c_str()); tray.showTrayMessage(tr("Password safe unlocked")); PWS_Access = true; emit PWS_unlocked(); return; } catch (DeviceCommunicationException &e){ csApplet()->warningBox(tr(Communication_error_message)); } catch (CommandFailedException &e){ //TODO emit pw safe not available when not available // cryptostick->passwordSafeAvailable = FALSE; // UnlockPasswordSafeAction->setEnabled(false); // csApplet()->warningBox(tr("Password safe is not supported by this device.")); // ui->tabWidget->setTabEnabled(3, 0); if(e.reason_wrong_password()){ //show message if wrong password csApplet()->warningBox(tr("Wrong user password.")); } else if (e.reason_AES_not_initialized()){ //generate keys if not generated try{ csApplet()->warningBox(tr("AES keys not initialized. Please provide Admin PIN.")); nm::instance()->build_aes_key(auth_admin.getPassword().c_str()); csApplet()->messageBox(tr("Keys generated. Please unlock Password Safe again.")); } catch (CommandFailedException &e){ if (e.reason_wrong_password()) csApplet()->warningBox(tr("Wrong admin password.")); else { csApplet()->warningBox(tr("Can't unlock password safe.")); } } } else { //otherwise csApplet()->warningBox(tr("Can't unlock password safe.")); } } } while (true); } void MainWindow::PWS_ExceClickedSlot(int Slot) { try { auto slot_password = nm::instance()->get_password_safe_slot_password((uint8_t) Slot); clipboard.copyPWS(slot_password); clear_free_cstr(const_cast(slot_password)); QString password_safe_slot_info = QString(tr("Password safe [%1]").arg(QString::fromStdString(libada::i()->getPWSSlotName(Slot)))); QString title = QString("Password has been copied to clipboard"); tray.showTrayMessage(title, password_safe_slot_info); } catch(DeviceCommunicationException &e){ tray.showTrayMessage(tr(Communication_error_message)); } } #include "GUI/Authentication.h" std::string MainWindow::getNextCode(uint8_t slotNumber) { const auto status = nm::instance()->get_status(); QByteArray tempPassword; if(status.enable_user_password){ if(!auth_user.authenticate()){ csApplet()->messageBox(tr("User not authenticated")); return ""; } tempPassword = auth_user.getTempPassword(); } bool isTOTP = slotNumber >= 0x20; auto temp_password_byte_array = tempPassword; if (isTOTP){ //run only once before first TOTP request static bool time_synchronized = libada::i()->is_time_synchronized(); if (!time_synchronized) { bool user_wants_time_reset = csApplet()->detailedYesOrNoBox(tr("Time is out-of-sync") + " - " + tr(Reset_nitrokeys_time), tr(Warning_devices_clock_not_desynchronized), false); if (user_wants_time_reset){ if(libada::i()->set_current_time()){ tray.showTrayMessage(tr("Time reset!")); time_synchronized = true; } } } return libada::i()->getTOTPCode(slotNumber - 0x20, (const char *) temp_password_byte_array.constData()); } else { return libada::i()->getHOTPCode(slotNumber - 0x10, (const char *) temp_password_byte_array.constData()); } return 0; } #define PWS_RANDOM_PASSWORD_CHAR_SPACE \ "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"$%&/" \ "()=?[]{}~*+#_'-`,.;:><^|@\\" void MainWindow::on_PWS_ButtonCreatePW_clicked() { //FIXME generate in separate class int n; const QString PasswordCharSpace = PWS_RANDOM_PASSWORD_CHAR_SPACE; QString generated_password(20, 0); for (int i = 0; i < PWS_CreatePWSize; i++) { n = qrand(); n = n % PasswordCharSpace.length(); generated_password[i] = PasswordCharSpace[n]; } ui->PWS_EditPassword->setText(generated_password.toLocal8Bit()); } void MainWindow::on_PWS_ButtonEnable_clicked() { PWS_Clicked_EnablePWSAccess(); } void MainWindow::on_counterEdit_editingFinished() { bool conversionSuccess = false; ui->counterEdit->text().toLatin1().toULongLong(&conversionSuccess); if (!libada::i()->isStorageDeviceConnected()) { quint64 counterMaxValue = ULLONG_MAX; if (!conversionSuccess) { ui->counterEdit->setText(QString("%1").arg(0)); csApplet()->warningBox(tr("Counter must be a value between 0 and %1").arg(counterMaxValue)); } } else { // for nitrokey storage if (!conversionSuccess || ui->counterEdit->text().toLatin1().length() > 7) { ui->counterEdit->setText(QString("%1").arg(0)); csApplet()->warningBox(tr("For Nitrokey Storage counter must be a value between 0 and 9999999")); } } } int MainWindow::factoryResetAction() { while (true){ const std::string &password = auth_admin.getPassword(); if (password.empty()) return 0; try{ nm::instance()->factory_reset(password.c_str()); } catch (InvalidCRCReceived &e) { //FIXME WORKAROUND to remove on later firmwares //We are expecting this exception due to bug in Storage stick firmware, v0.45, with CRC set to "0" in response } catch (CommandFailedException &e){ if(!e.reason_wrong_password()) throw; csApplet()->messageBox(tr("Wrong Pin. Please try again.")); continue; } csApplet()->messageBox(tr("Factory reset was successful.")); emit FactoryReset(); return 1; } return 0; } void MainWindow::on_radioButton_2_toggled(bool checked) { if (checked) ui->slotComboBox->setCurrentIndex(0); } void MainWindow::on_radioButton_toggled(bool checked) { if (checked) ui->slotComboBox->setCurrentIndex(TOTP_SlotCount + 1); } void setCounter(int size, const QString &arg1, QLabel *counter) { int chars_left = size - arg1.toUtf8().size(); QString t = QString::number(chars_left); counter->setText(t); } void MainWindow::on_PWS_EditSlotName_textChanged(const QString &arg1) { setCounter(PWS_SLOTNAME_LENGTH, arg1, ui->l_c_name); } void MainWindow::on_PWS_EditLoginName_textChanged(const QString &arg1) { setCounter(PWS_LOGINNAME_LENGTH, arg1, ui->l_c_login); } void MainWindow::on_PWS_EditPassword_textChanged(const QString &arg1) { setCounter(PWS_PASSWORD_LENGTH, arg1, ui->l_c_password); } void MainWindow::on_enableUserPasswordCheckBox_clicked(bool checked) { if (checked && libada::i()->is_nkpro_07_rtm1()) { bool answer = csApplet()->yesOrNoBox(tr("To handle this functionality " "application will keep your user PIN in memory. " "Do you want to continue?"), false); ui->enableUserPasswordCheckBox->setChecked(answer); //TODO save choice in APP's configuration } } void MainWindow::startLockDeviceAction(bool ask_for_confirmation) { if(libada::i()->isStorageDeviceConnected()){ PWS_Access = false; storage.startLockDeviceAction(ask_for_confirmation); return; } emit ShortOperationBegins(tr("Locking device")); PWS_Access = false; nm::instance()->lock_device(); tray.showTrayMessage("Nitrokey App", tr("Device has been locked"), INFORMATION, TRAY_MSG_TIMEOUT); emit DeviceLocked(); emit ShortOperationEnds(); } void MainWindow::updateProgressBar(int i) { ui->progressBar->setValue(i); if(i == 100){ QTimer::singleShot(1000, [&](){ ui->progressBar->hide(); }); } } void MainWindow::on_DeviceDisconnected() { if (debug_mode) qDebug("on_DeviceDisconnected"); emit ShortOperationEnds(); QSettings settings; if(settings.value("main/connection_message", true).toBool()){ tray.showTrayMessage(tr("Nitrokey disconnected")); } ui->statusBar->showMessage(tr("Nitrokey disconnected")); if(this->isVisible() && settings.value("main/close_main_on_connection", false).toBool()){ this->hide(); } make_UI_enabled(false); } void MainWindow::on_DeviceConnected() { if (debug_mode) qDebug("on_DeviceConnected"); if (debug_mode) emit ShortOperationBegins(tr("Connecting device")); ui->statusBar->showMessage(tr("Device connected. Waiting for initialization...")); auto result = QtConcurrent::run(libada::i().get(), &libada::get_status_no_except); result.waitForFinished(); if (result.result() == 2){ long_operation_in_progress = true; } if (result.result() !=0){ return; } initialTimeReset(); new ThreadWorker( []() -> Data { Data data; data["error"] = false; try{ auto storageDeviceConnected = libada::i()->isStorageDeviceConnected(); data["storage_connected"] = storageDeviceConnected; if (storageDeviceConnected){ auto s = nm::instance()->get_status_storage(); data["initiated"] = !s.StickKeysNotInitiated; data["initiated_ask"] = !false; //FIXME select proper variable s.NewSDCardFound_u8 data["erased"] = !s.NewSDCardFound_u8; data["erased_ask"] = !s.SDFillWithRandomChars_u8; data["old_firmware"] = s.versionInfo.major == 0 && s.versionInfo.minor <= 49; } data["PWS_Access"] = libada::i()->isPasswordSafeUnlocked(); } catch(DeviceCommunicationException &e){ data["error"] = true; } return data; }, [this](Data data) { emit ShortOperationEnds(); PWS_Access = data["PWS_Access"].toBool(); if(data["error"].toBool()) return; if(!data["storage_connected"].toBool()) return; if (!data["initiated"].toBool()) { if (data["initiated_ask"].toBool()){ csApplet()->warningBox(tr(Warning_ev_not_secure_initialize) + " " + "\n" + tr(Tray_location_msg)); ui->statusBar->showMessage(tr(Warning_ev_not_secure_initialize)); make_UI_enabled(false); } } if (data["initiated"].toBool() && !data["erased"].toBool()) { if (data["erased_ask"].toBool()) csApplet()->warningBox(tr("Warning: Encrypted volume is not secure,\nSelect \"Initialize " "storage with random data\"") + ". " + "\n" + tr(Tray_location_msg)); } #if defined(Q_OS_MAC) || defined(Q_OS_DARWIN) if(data["old_firmware"].toBool()){ csApplet()->warningBox(tr( "WARNING: This Storage firmware version is old. Application may be unresponsive and unlocking encrypted volume may not work. Please update the firmware to the latest version." " " "Guide should be available at:
www.nitrokey.com/en/doc/firmware-update-storage." )); } #endif }, this); QSettings settings; if (settings.value("main/show_main_on_connection", true).toBool()){ startConfiguration(false); } auto connected_device_model = libada::i()->isStorageDeviceConnected() ? tr("Nitrokey Storage connected") : tr("Nitrokey Pro connected"); if(settings.value("main/connection_message", true).toBool()){ tray.showTrayMessage(tr("Nitrokey connected"), connected_device_model); } ui->statusBar->showMessage(connected_device_model); } void MainWindow::on_KeepDeviceOnline() { if (!check_connection_mutex.tryLock(100)){ if (debug_mode) qDebug("on_KeepDeviceOnline skip"); return; } ScopedGuard mutexGuard([this](){ check_connection_mutex.unlock(); }); try{ nm::instance()->get_status(); //if long operation in progress jump to catch, // clear the flag otherwise if (long_operation_in_progress) { long_operation_in_progress = false; keepDeviceOnlineTimer->setInterval(30*1000); emit OperationInProgress(100); startLockDeviceAction(false); } } catch (DeviceCommunicationException &e){ if(connectionState != ConnectionState::disconnected){ emit DeviceDisconnected(); } } catch (LongOperationInProgressException &e){ if(!long_operation_in_progress){ long_operation_in_progress = true; keepDeviceOnlineTimer->setInterval(10*1000); } emit OperationInProgress(e.progress_bar_value); } } void MainWindow::show_progress_window() { progress_window->show(); progress_window->setFocus(); progress_window->raise(); QApplication::setActiveWindow(progress_window.get()); } void MainWindow::set_commands_delay(int delay_in_ms) { nm::instance()->set_default_commands_delay(delay_in_ms); } void MainWindow::enable_admin_commands() { tray.setAdmin_mode(true); } void MainWindow::set_debug_file(QString log_file_name) { nm::instance()->set_log_function( [log_file_name, debug_mode=this->debug_mode](std::string data){ static std::shared_ptr log_file; if(!log_file){ log_file = std::make_shared(log_file_name); if (!log_file->open(QIODevice::WriteOnly | QIODevice::Text)){ if (debug_mode) qDebug() << "Could not open " << log_file_name; log_file = nullptr; } } if(log_file) { log_file->write(data.c_str()); log_file->flush(); } } ); LOGD(QSysInfo::prettyProductName().toStdString()); } void MainWindow::set_debug_window() { tray.setDebug_mode(true); nm::instance()->set_log_function( [this](std::string data) { emit DebugData(QString::fromStdString(data)); }); LOGD(QSysInfo::prettyProductName().toStdString()); } void MainWindow::set_debug_mode() { tray.setDebug_mode(true); debug_mode = true; } void MainWindow::set_debug_level(int debug_level) { nm::instance()->set_loglevel(debug_level); } void MainWindow::on_btn_writeSettings_clicked() { QSettings settings; // see if restart is required bool restart_required = false; if (settings.value("main/language").toString() != ui->combo_languages->currentData().toString() || settings.value("debug/enabled").toBool() != ui->cb_debug_enabled->isChecked() || settings.value("debug/file").toString() != ui->edit_debug_file_path->text() ){ restart_required = true; } // save the settings settings.setValue("main/first_run", ui->cb_first_run_message->isChecked()); settings.setValue("main/language", ui->combo_languages->currentData()); settings.setValue("debug/file", ui->edit_debug_file_path->text()); settings.setValue("debug/level", ui->spin_debug_verbosity->text().toInt()); settings.setValue("debug/enabled", ui->cb_debug_enabled->isChecked()); settings.setValue("clipboard/PWS_time", ui->spin_PWS_time->value()); settings.setValue("clipboard/OTP_time", ui->spin_OTP_time->value()); settings.setValue("main/connection_message", ui->cb_device_connection_message->isChecked()); settings.setValue("main/show_main_on_connection", ui->cb_show_main_window_on_connection->isChecked()); settings.setValue("main/close_main_on_connection", ui->cb_hide_main_window_on_connection->isChecked()); settings.setValue("main/hide_on_close", ui->cb_hide_main_window_on_close->isChecked()); settings.setValue("storage/check_symlink", ui->cb_check_symlink->isChecked()); // inform user and quit if asked if (!restart_required){ csApplet()->messageBox(tr("Configuration successfully written.")); } else { auto user_wants_quit = csApplet()->yesOrNoBox( tr("Configuration successfully written.") + " "+ tr("Please run the application again to apply new settings.") + " "+ tr("Would you like to quit now?"), true); if (user_wants_quit) { QApplication::exit(); } } load_settings_page(); } void MainWindow::on_btn_select_debug_file_path_clicked() { auto filename = QFileDialog::getSaveFileName(this, tr("Debug file location (will be overwritten)")); ui->edit_debug_file_path->setText(filename); } void MainWindow::on_PWS_Lock_clicked() { startLockDeviceAction(true); } void MainWindow::on_btn_copyToClipboard_clicked() { clipboard.copyOTP(ui->secretEdit->text()); showNotificationLabel(); } void MainWindow::ready() { } void MainWindow::on_btn_select_debug_console_clicked() { ui->edit_debug_file_path->setText("console"); } nitrokey-app-1.3.2/src/ui/mainwindow.h0000644000175000017500000001560013314460010017224 0ustar janjan00000000000000/* * Author: Copyright (C) Andrzej Surowiec 2012 * Parts Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2012-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include #include "hotpslot.h" #include "GUI/Tray.h" #include "GUI/Clipboard.h" #include "GUI/Authentication.h" #include "stick20responsedialog.h" #include "stick20debugdialog.h" #include namespace Ui { class MainWindow; } class Tray; enum class ConnectionState{ disconnected, connected, long_operation }; class MainWindow : public QMainWindow { Q_OBJECT public : explicit MainWindow(QWidget *parent = 0); ~MainWindow(); protected: void closeEvent(QCloseEvent *event) override; private: Q_DISABLE_COPY(MainWindow); Ui::MainWindow *ui; Clipboard clipboard; Authentication auth_admin; Authentication auth_user; StorageActions storage; Tray tray; const unsigned char HOTP_SlotCount; const unsigned char TOTP_SlotCount; DebugDialog *debug; void keyPressEvent(QKeyEvent *keyevent) override; bool validate_raw_secret(const char *secret) const; void initialTimeReset(); QMutex check_connection_mutex; QString nkpro_user_PIN; void startDebug(); QTimer *keepDeviceOnlineTimer; bool PWS_Access = false; const int PWS_CreatePWSize = 20; bool set_initial_time; QString DebugText; int ExecStickCmd(const char *Cmdline_); std::string getNextCode(uint8_t slotNumber); void generateHOTPConfig(OTPSlot *slot); void generateTOTPConfig(OTPSlot *slot); void generateAllConfigs(); // void refreshStick20StatusData(); void translateDeviceStatusToUserMessage(const int getStatus); public slots: void startAboutDialog(); void startHelpAction(); void startConfiguration(bool changeTab = true); void startConfigurationMain(); void PWS_Clicked_EnablePWSAccess(); int factoryResetAction(); void getTOTPDialog(int slot); void getHOTPDialog(int slot); void PWS_ExceClickedSlot(int Slot); void startStick20ActionChangeUserPIN(); void startStick20ActionChangeAdminPIN(); void startStick20ActionChangeUpdatePIN(); void startResetUserPassword(); void startLockDeviceAction(bool ask_for_confirmation = true); void updateProgressBar(int i); void show_progress_window(); signals: void DeviceConnected(); void DeviceDisconnected(); void PWS_unlocked(); void PWS_slot_saved(int slot_no); void DeviceLocked(); void FactoryReset(); void PWS_progress(int p); void OperationInProgress(int p); void ShortOperationBegins(QString msg); void ShortOperationEnds(); void OTP_slot_write(int slot_no, bool isHOTP); void DebugData(QString msg); void LongOperationStart(); private slots: void manageStartPage(); void on_longOperationStart(); void on_KeepDeviceOnline(); void on_DeviceConnected(); void on_DeviceDisconnected(); void generateComboBoxEntrys(); void on_enableUserPasswordCheckBox_clicked(bool checked); void resizeMin(); void ready(); void checkConnection(); void storage_check_symlink(); void on_writeButton_clicked(); void displayCurrentTotpSlotConfig(uint8_t slotNo); void displayCurrentHotpSlotConfig(uint8_t slotNo); void displayCurrentSlotConfig(); void displayCurrentGeneralConfig(); void on_slotComboBox_currentIndexChanged(int index); void on_hexRadioButton_toggled(bool checked); void on_base32RadioButton_toggled(bool checked); void on_setToZeroButton_clicked(); void on_setToRandomButton_clicked(); void on_tokenIDCheckBox_toggled(bool checked); void on_enableUserPasswordCheckBox_toggled(bool checked); void on_writeGeneralConfigButton_clicked(); void checkTextEdited(); // Functions for password safe void SetupPasswordSafeConfig(void); void on_eraseButton_clicked(); void on_randomSecretButton_clicked(); void on_checkBox_toggled(bool checked); void startStickDebug(); void load_settings_page(); void on_PWS_ButtonClearSlot_clicked(); void on_PWS_ComboBoxSelectSlot_currentIndexChanged(int index); void on_PWS_CheckBoxHideSecret_toggled(bool checked); void on_PWS_ButtonClose_pressed(); void on_PWS_ButtonCreatePW_clicked(); void on_PWS_ButtonSaveSlot_clicked(); void on_PWS_ButtonEnable_clicked(); void on_counterEdit_editingFinished(); void on_radioButton_2_toggled(bool checked); void on_radioButton_toggled(bool checked); void on_PWS_EditSlotName_textChanged(const QString &arg1); void on_PWS_EditLoginName_textChanged(const QString &arg1); void on_PWS_EditPassword_textChanged(const QString &arg1); void on_btn_writeSettings_clicked(); void on_btn_select_debug_file_path_clicked(); void on_PWS_Lock_clicked(); void on_btn_copyToClipboard_clicked(); void on_btn_select_debug_console_clicked(); public: void generateOTPConfig(OTPSlot *slot); unsigned int get_supported_secret_length_base32() const; unsigned int get_supported_secret_length_hex() const; std::atomic_bool long_operation_in_progress {false}; std::shared_ptr progress_window; void PWS_set_controls_enabled(bool enabled) const; ConnectionState connectionState = ConnectionState::disconnected; void set_commands_delay(int delay_in_ms); void first_run(); void enable_admin_commands(); void set_debug_file(QString log_file_name); void set_debug_window(); void set_debug_mode(); void set_debug_level(int debug_level); private: bool debug_mode = false; void showNotificationLabel(); unsigned int roundToNextMultiple(const int number, const int multipleOf) const; QString getOTPSecretCleaned(QString secret_input); void make_UI_enabled(bool enabled); }; class utf8FieldLengthValidator : public QValidator { Q_OBJECT private: int field_max_length; Q_DISABLE_COPY(utf8FieldLengthValidator); public: explicit utf8FieldLengthValidator(QObject *parent = 0); explicit utf8FieldLengthValidator(int _field_max_length, QObject *parent = 0) : QValidator(parent), field_max_length(_field_max_length) {} virtual State validate(QString &input, int &) const { int chars_left = field_max_length - input.toUtf8().size(); if (chars_left >= 0) { return Acceptable; } return Invalid; } }; #endif // MAINWINDOW_H nitrokey-app-1.3.2/src/ui/mainwindow.ui0000644000175000017500000021673613275777051017455 0ustar janjan00000000000000 MainWindow 0 0 932 717 0 0 Nitrokey App :/images/new/icon_NK.svg:/images/new/icon_NK.svg true 0 0 QTabWidget::North QTabWidget::Rounded 0 Qt::ElideNone false false false Overview 0 0 561 211 Qt::AlignCenter false false true 0 0 Unlock Password Safe :/images/new/icon_safe.svg:/images/new/icon_safe.svg 0 0 #upLeft { background-color: transparent; border-image: url(:/images/new/icon_safe.svg); background: none; border: none; background-repeat: none; } Unlock Encrypted Volume :/images/new/icon_harddrive.svg:/images/new/icon_harddrive.svg 0 0 #upLeft { background-color: transparent; border-image: url(:/images/new/icon_safe.svg); background: none; border: none; background-repeat: none; } Unlock Hidden Volume :/images/new/icon_harddrive.svg:/images/new/icon_harddrive.svg 0 0 #upLeft { background-color: transparent; border-image: url(:/images/new/icon_safe.svg); background: none; border: none; background-repeat: none; } Lock Device 0 0 #upLeft { background-color: transparent; border-image: url(:/images/new/icon_safe.svg); background: none; border: none; background-repeat: none; } Help :/images/new/icon_fragezeichen.svg:/images/new/icon_fragezeichen.svg 0 0 #upLeft { background-color: transparent; border-image: url(:/images/new/icon_safe.svg); background: none; border: none; background-repeat: none; } Quit :/images/new/icon_quit.svg:/images/new/icon_quit.svg OTP Slot Configuration false QFrame::StyledPanel QFrame::Sunken 75 true Manage slots Select slot type: TOTP (Recommendation: Use TOTP for web applications and HOTP for local applications) TOTP true Select slot type: HOTP (Recommendation: Use TOTP for web applications and HOTP for local applications) HOTP true (Recommendation: Use TOTP for web applications and HOTP for local applications) Qt::Horizontal 40 20 Slot: Select OTP slot number HOTP slot 0 HOTP slot Erase Slot Name: Slot name 15 false QFrame::StyledPanel QFrame::Sunken 75 true Secret key QFormLayout::AllNonFixedFieldsGrow Input format: Example: "ZR3M5I..." Secret input format: base32 Base32 true true Example: "A3911C05..." (remove any 0x prefix) Secret input format: hex Hex false Qt::Horizontal 40 20 11 Entered OTP 'Secret Key' string is longer than supported by this device Label shown when the OTP secret key is too long <html><head/><body><p><span style=" font-weight:600; color:#a40000;">Entered OTP 'Secret Key' string is longer than supported by this device</span></p></body></html> <html><head/><body><p>The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to.</p></body></html> Secret Key: The secret is provided by your service provider you may want to login or can be configured in your local application which you may want to login to. OTP secret key Note: 2nd factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. 200 QLineEdit::PasswordEchoOnEdit ******************************** false 9 75 true true Secret copied to clipboard true <html><head/><body><p>Hide or show the secret.</p></body></html> Hide secret true Qt::Horizontal 40 20 Copy secret to clipboard Copy to clipboard After generating a random secret, you would need to copy it into your application or service where you want to login to. Generate random secret 11 true Note: 2<sup>nd</sup> factors aren't protected against physical attacks. Change all OTP secrets in case you loose the Nitrokey. true false QFrame::StyledPanel QFrame::Sunken 75 true Parameters Send 'enter' as the last keystroke QFormLayout::AllNonFixedFieldsGrow HOTP moving factor seed 00000000000000000000 20 Set HOTP counter to zero Set to zero Set HOTP counter to random value Set to random Qt::Vertical 20 0 OTP code length: 6 digits 6 digits true OTP code length: 8 digits 8 digits Qt::Horizontal 40 20 TOTP interval value 1 65536 30 Qt::Horizontal 40 0 Moving factor seed: HOTP length: TOTP interval: false QFrame::StyledPanel QFrame::Sunken 75 true Token ID true Send token ID OMP: false OMP part of Token ID 2 TT: false TT part of Token ID 2 MUI: false MUI part of Token ID 8 Qt::Vertical QSizePolicy::MinimumExpanding 20 1 Qt::Horizontal 24 Qt::Horizontal 40 20 Cancel Save OTP General false QFrame::StyledPanel QFrame::Sunken 75 true OTP Password settings Protect OTP by user PIN (will be requested on first use each session) Forget user PIN after 10 minutes (if unchecked user PIN will remain in memory until application exits) false QFrame::StyledPanel QFrame::Sunken 75 true Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Double press NumLock: Double press CapsLock: Double press ScrollLock: Double press NumLock: Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Do nothing Send HOTP1 Send HOTP2 Double press CapsLock: Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Do nothing Send HOTP1 Send HOTP2 Double press ScrollLock: Settings for inserting HOTP code through special key shortcut (USB-Keyboard only) Do nothing Send HOTP1 Send HOTP2 Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 Qt::Horizontal Qt::Horizontal 40 20 Cancel Save Password Safe 0 0 false QFrame::StyledPanel QFrame::Sunken Password: Login name: Password: Slot name: Login name: Erase Password Safe slot Erase Slot Slot name: Password Safe slot number Static password 0 0 Static password 0 Generate random password Slot: true Hide secret true Characters left: ... Qt::AlignCenter ... Qt::AlignCenter ... Qt::AlignCenter Qt::StrongFocus <html><head/><body><p>Password Safe fields support UTF8 data. It means that you can use your national characters here. Please remember however that non-English characters could take more space (up to 4 characters). The counters next to each field are to inform how much more standard English characters can given field accept.</p></body></html> true Qt::Vertical QSizePolicy::MinimumExpanding 20 0 Qt::Horizontal Unlock Password Safe Lock Device 42 Qt::Horizontal 40 20 Cancel Save true true Settings QFrame::StyledPanel QFrame::Raised General Show first-run message Show warning when no partitions could be detected on Encrypted Volume (Linux only) true Show message about device's connection / disconnection true Show main window when device connects true Hide main window when device disconnects true Do not quit when the main window is closed true <html><head/><body><p>Translation file (needs restart)</p></body></html> Translation file (needs restart) Debug log settings Path for debug log file: edit_debug_file_path Verbosity level: spin_debug_verbosity Path for debug log file: Verbosity level: 6 2 Select path Logging enabled Log to console Clipboard settings Time to store OTP secrets in clipboard (in seconds): 10 600 120 Time to store Password Safe secrets in clipboard (in seconds): spin_debug_verbosity TIme to store Password Safe secrets in clipboard (in seconds): 10 600 60 Time to store OTP secrets in clipboard (in seconds): spin_debug_verbosity Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::MinimumExpanding 20 78 Qt::Horizontal Qt::Horizontal 40 20 Cancel Save false 0 0 932 20 tabWidget btn_dial_PWS btn_dial_EV btn_dial_HV btn_dial_lock btn_dial_help btn_dial_quit radioButton_2 radioButton slotComboBox eraseButton nameEdit base32RadioButton hexRadioButton secretEdit checkBox btn_copyToClipboard randomSecretButton enterCheckBox intervalSpinBox digits6radioButton digits8radioButton counterEdit setToZeroButton setToRandomButton tokenIDCheckBox ompEdit ttEdit muiEdit cancelButton writeButton enableUserPasswordCheckBox deleteUserPasswordCheckBox numLockComboBox capsLockComboBox scrollLockComboBox PWS_ComboBoxSelectSlot PWS_ButtonClearSlot PWS_EditSlotName PWS_EditLoginName PWS_EditPassword PWS_ButtonCreatePW PWS_CheckBoxHideSecret l_utf8_info PWS_ButtonEnable PWS_Lock PWS_ButtonClose PWS_ButtonSaveSlot cb_first_run_message cb_check_symlink cb_device_connection_message cb_show_main_window_on_connection cb_hide_main_window_on_connection cb_hide_main_window_on_close combo_languages cb_debug_enabled edit_debug_file_path btn_select_debug_console btn_select_debug_file_path spin_debug_verbosity spin_PWS_time spin_OTP_time btn_cancelSettings btn_writeSettings writeGeneralConfigButton generalCancelButton generalCancelButton clicked() MainWindow hide() 824 675 300 368 cancelButton clicked() MainWindow hide() 824 675 262 366 btn_cancelSettings clicked() MainWindow hide() 823 674 6 670 cb_debug_enabled toggled(bool) edit_debug_file_path setEnabled(bool) 154 355 374 384 cb_debug_enabled toggled(bool) spin_debug_verbosity setEnabled(bool) 130 355 350 414 cb_debug_enabled toggled(bool) btn_select_debug_file_path setEnabled(bool) 103 355 897 384 cb_debug_enabled toggled(bool) btn_select_debug_console setEnabled(bool) 79 350 763 376 nitrokey-app-1.3.2/src/ui/nitrokey-applet.cpp0000644000175000017500000000631013275777051020556 0ustar janjan00000000000000/* * Copyright (c) 2014-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include #include #include #include #include "nitrokey-applet.h" #include "src/GUI/ManageWindow.h" QMutex AppMessageBox::mutex; AppMessageBox *csApplet(){ return AppMessageBox::instance(); } void AppMessageBox::warningBox(const QString msg) { QMessageBox *msgbox = new QMessageBox( QMessageBox::Warning, getBrand(), msg, QMessageBox::Ok, _parent); // msgbox->setAttribute( Qt::WA_DeleteOnClose ); //makes sure the msgbox is deleted automatically when closed msgbox->setModal( true ); ManageWindow::moveToCenter(msgbox); ManageWindow::bringToFocus(msgbox); msgbox->exec(); } void AppMessageBox::messageBox(const QString msg) { QMessageBox *msgbox = new QMessageBox( QMessageBox::Information, getBrand(), msg, QMessageBox::Ok, _parent); // msgbox->setAttribute( Qt::WA_DeleteOnClose ); //makes sure the msgbox is deleted automatically when closed msgbox->setModal( true ); ManageWindow::moveToCenter(msgbox); ManageWindow::bringToFocus(msgbox); msgbox->exec(); } bool AppMessageBox::yesOrNoBox(const QString msg, bool default_val) { QMessageBox::StandardButton default_btn = default_val ? QMessageBox::Yes : QMessageBox::No; auto buttons = QMessageBox::Yes | QMessageBox::No; bool b = QMessageBox::question(_parent, getBrand(), msg, buttons, default_btn) == QMessageBox::Yes; //TODO make on heap return b; } bool AppMessageBox::detailedYesOrNoBox(const QString msg, const QString detailed_text, bool default_val) { QMessageBox *msgBox = new QMessageBox(QMessageBox::Question, getBrand(), msg, QMessageBox::Yes | QMessageBox::No, _parent); msgBox->setDetailedText(detailed_text); // Turns out the layout box in the QMessageBox is a grid // You can force the resize using a spacer this way: QSpacerItem *horizontalSpacer = new QSpacerItem(400, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); QGridLayout *layout = (QGridLayout *)msgBox->layout(); layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount()); msgBox->setDefaultButton(default_val ? QMessageBox::Yes : QMessageBox::No); // msgBox->setAttribute( Qt::WA_DeleteOnClose ); //makes sure the msgbox is deleted automatically when closed ManageWindow::moveToCenter(msgBox); ManageWindow::bringToFocus(msgBox); bool b = msgBox->exec() == QMessageBox::Yes; return b; } QString getBrand() { return QStringLiteral(CRYPTOSTICK_APP_BRAND); } nitrokey-app-1.3.2/src/ui/nitrokey-applet.h0000644000175000017500000000331013275777051020220 0ustar janjan00000000000000/* * Copyright (c) 2014-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef CRYPTOSTICK_APPLET_H #define CRYPTOSTICK_APPLET_H #include #include #include #include #include #define CRYPTOSTICK_APP_BRAND "Nitrokey App" QString getBrand(); class AppMessageBox { public: void messageBox(const QString msg); void warningBox(const QString msg); bool yesOrNoBox(const QString msg, bool default_val); bool detailedYesOrNoBox(const QString msg, const QString detailed_text, bool default_val); static AppMessageBox* instance(){ //C++11 static initialization is thread safe //In Visual Studio supported since 2015 hence mutex QMutexLocker locker(&mutex); static AppMessageBox applet; return &applet; } private: AppMessageBox() :_parent(Q_NULLPTR) {} static QMutex mutex; public: void setParent(QWidget *parent) { _parent = parent; } private: QWidget *_parent; }; AppMessageBox *csApplet(); #endif /* CRYPTOSTICK_APPLET_H */ nitrokey-app-1.3.2/src/ui/pindialog.cpp0000644000175000017500000001511413275777051017377 0ustar janjan00000000000000/* * Author: Copyright (C) Andrzej Surowiec 2012 * Copyright (c) 2012-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include "src/GUI/ManageWindow.h" #include "mcvs-wrapper.h" #include "pindialog.h" #include "nitrokey-applet.h" #include "stick20changepassworddialog.h" int PinDialog::instances = 0; PinDialog* PinDialog::current_instance = nullptr; PinDialog::PinDialog(PinType pinType, QWidget *parent): QDialog(parent), _pinType(pinType), worker(pinType) { ++instances; if (PinDialog::current_instance == nullptr) PinDialog::current_instance = this; ui = std::make_shared(); ui->setupUi(this); ui->status->setText(tr("Tries left: %1").arg("...")); QString title, label; switch (pinType){ case USER_PIN: title = tr("Enter user PIN"); label = tr("User PIN:"); break; case ADMIN_PIN: title = tr("Enter admin PIN"); label = tr("Admin PIN:"); break; case FIRMWARE_PIN: title = tr("Enter Firmware Password"); label = tr("Enter Firmware Password:"); ui->status->setVisible(false); break; case OTHER: break; case HIDDEN_VOLUME: title = tr("Enter password for hidden volume"); label = tr("Enter password for hidden volume:"); ui->status->setVisible(false); break; } // worker.pin_type = _pinType; connect(&worker_thread, SIGNAL(started()), &worker, SLOT(fetch_device_data())); connect(&worker, SIGNAL(finished()), this, SLOT(updateTryCounter())); worker.moveToThread(&worker_thread); worker_thread.start(); connect(ui->okButton, SIGNAL(clicked()), this, SLOT(onOkButtonClicked())); // Setup title and label this->setWindowTitle(title); ui->label->setText(label); ui->lineEdit->setAccessibleName(label); ui->lineEdit->setMaxLength(UI_PASSWORD_LENGTH_MAXIMUM); // ui->status->setVisible(false); ui->lineEdit->setFocus(); this->setModal(true); } PinDialog::~PinDialog() { worker_thread.quit(); worker_thread.wait(); --instances; if (PinDialog::current_instance == this) PinDialog::current_instance = nullptr; } void PinDialog::getPassword(QString &pin) { pin = ui->lineEdit->text(); clearBuffers(); } std::string PinDialog::getPassword() { std::string pin = ui->lineEdit->text().toStdString(); clearBuffers(); return pin; } void PinDialog::on_checkBox_toggled(bool checked) { ui->lineEdit->setEchoMode(checked ? QLineEdit::Normal : QLineEdit::Password); } PasswordKind translate_type(PinType type){ switch (type){ case PinType::USER_PIN: return PasswordKind::USER; case PinType::ADMIN_PIN: return PasswordKind::ADMIN; case PinType::HIDDEN_VOLUME:break; case PinType::FIRMWARE_PIN: return PasswordKind::UPDATE; case PinType::OTHER:break; } throw std::runtime_error("Wrong password kind selected"); } void PinDialog::onOkButtonClicked() { int n; // Check the password length auto passwordString = ui->lineEdit->text().toLatin1(); n = passwordString.size(); if (PIN_LENGTH_MAXIMUM <= n) { csApplet()->warningBox(tr("Your PIN is too long! Use not more than 30 characters.")); //FIXME use %1 instead of constant in translation ui->lineEdit->clear(); return; } if (PIN_LENGTH_MINIMUM > n) { csApplet()->warningBox(tr("Your PIN is too short. Use at least 6 characters.")); //FIXME use %1 instead of constant in translation ui->lineEdit->clear(); return; } // Check for default pin and ask for change if set default if (passwordString == DEFAULT_PIN_USER || passwordString == DEFAULT_PIN_ADMIN) { auto warning_message = tr("Warning: Default PIN is used.\nPlease change the PIN."); if (_pinType == USER_PIN || _pinType == ADMIN_PIN || _pinType == FIRMWARE_PIN) { auto yesOrNoBox = csApplet()->yesOrNoBox(warning_message +" "+ tr("Would you like to so now?"), true); if (yesOrNoBox) { auto dialog = new DialogChangePassword(this, translate_type(_pinType)); dialog->InitData(); const auto password_changed = dialog->exec(); if (password_changed){ ui->lineEdit->clear(); csApplet()->messageBox(tr("Please enter the new PIN/password")); } return; } } } done(Accepted); } int PinDialog::exec() { if (PinDialog::instances > 1){ done(Rejected); if (PinDialog::current_instance != nullptr){ ManageWindow::bringToFocus(PinDialog::current_instance); } return QDialog::Rejected; } if (!libada::i()->isDeviceInitialized()) { UI_deviceNotInitialized(); done(Rejected); return QDialog::Rejected; } QTimer::singleShot(500, [this](){ ManageWindow::bringToFocus(this); }); return QDialog::exec(); } void PinDialog::updateTryCounter() { int triesLeft = 0; switch (_pinType) { case ADMIN_PIN: triesLeft = worker.devdata.retry_admin_count; break; case USER_PIN: triesLeft = worker.devdata.retry_user_count; break; case HIDDEN_VOLUME: case FIRMWARE_PIN: case OTHER: // Hide tries left field ui->status->setVisible(false); break; } // Update 'tries-left' field ui->status->setText(tr("Tries left: %1").arg(triesLeft)); } void PinDialog::UI_deviceNotInitialized() const { csApplet()->warningBox(tr("Device is not yet initialized. Please try again later.")); } void PinDialog::clearBuffers() { //FIXME securely delete string in UI //FIXME make sure compiler will not ignore this ui->lineEdit->clear(); ui->lineEdit->setText(ui->lineEdit->placeholderText()); } void PinDialogUI::Worker::fetch_device_data() { try { if (pin_type == PinType::ADMIN_PIN){ devdata.retry_admin_count = libada::i()->getAdminPasswordRetryCount(); } else if (pin_type == PinType::USER_PIN) { devdata.retry_user_count = libada::i()->getUserPasswordRetryCount(); } emit finished(); } catch (...){ //ignore } } PinDialogUI::Worker::Worker(const PinType _pin_type) { pin_type = _pin_type; } nitrokey-app-1.3.2/src/ui/pindialog.h0000644000175000017500000000456213275777051017051 0ustar janjan00000000000000/* * Author: Copyright (C) Andrzej Surowiec 2012 * Copyright (c) 2012-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef PINDIALOG_H #define PINDIALOG_H #include static const int PIN_LENGTH_MAXIMUM = 30; static const int PIN_LENGTH_MINIMUM = 6; static const char *const DEFAULT_PIN_USER = "123456"; static const char *const DEFAULT_PIN_ADMIN = "12345678"; static const int UI_PASSWORD_LENGTH_MAXIMUM = STICK20_PASSOWRD_LEN; #include #include #include #include "ui_pindialog.h" #include enum PinType { USER_PIN, ADMIN_PIN, HIDDEN_VOLUME, FIRMWARE_PIN, OTHER }; namespace Ui { class PinDialog; } namespace PinDialogUI{ class Worker : public QObject { Q_OBJECT public: Worker(PinType _pin_type); struct { int retry_user_count; int retry_admin_count; } devdata; private: PinType pin_type; public slots: void fetch_device_data(); signals: void finished(); }; } class PinDialog : public QDialog { Q_OBJECT public : explicit PinDialog(PinType pinType, QWidget *parent = nullptr); ~PinDialog(); void getPassword(char *text); void getPassword(QString &pin); std::string getPassword(); virtual int exec() override; private slots: void on_checkBox_toggled(bool checked); void onOkButtonClicked(); void updateTryCounter(); private: Q_DISABLE_COPY(PinDialog); std::shared_ptr ui; const PinType _pinType; PinDialogUI::Worker worker; QThread worker_thread; static int instances; static PinDialog* current_instance; void clearBuffers(); void UI_deviceNotInitialized() const; }; #endif // PINDIALOG_H nitrokey-app-1.3.2/src/ui/pindialog.ui0000644000175000017500000001310413275777051017227 0ustar janjan00000000000000 PinDialog 0 0 358 155 0 0 Password dialog :/images/new/icon_NK.svg:/images/new/icon_NK.svg 0 0 false QFrame::NoFrame QFrame::Plain 0 0 Enter card password: Enter card PIN 39 QLineEdit::Password 0 0 Show password Qt::Horizontal 0 20 Qt::Vertical QSizePolicy::MinimumExpanding 0 0 Qt::Horizontal Qt::StrongFocus TextLabel Qt::Horizontal 40 20 Qt::TabFocus &Cancel false false Qt::TabFocus &OK true true lineEdit checkBox cancelButton clicked() PinDialog reject() 214 142 178 82 nitrokey-app-1.3.2/src/ui/securitydialog.cpp0000644000175000017500000000236513275777051020464 0ustar janjan00000000000000/* * Copyright (c) 2014-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include "securitydialog.h" #include "ui_securitydialog.h" securitydialog::securitydialog(QWidget *parent) : QDialog(parent), ui(new Ui::securitydialog) { ui->setupUi(this); ui->ST_OkButton->setDisabled(true); } securitydialog::~securitydialog() { delete ui; } void securitydialog::on_ST_CheckBox_toggled(bool checked) { if (true == checked) { ui->ST_OkButton->setEnabled(true); } else { ui->ST_OkButton->setDisabled(true); } } void securitydialog::on_ST_OkButton_clicked() { done(true); } nitrokey-app-1.3.2/src/ui/securitydialog.h0000644000175000017500000000220513275777051020122 0ustar janjan00000000000000/* * Copyright (c) 2014-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef SECURITYDIALOG_H #define SECURITYDIALOG_H #include namespace Ui { class securitydialog; } class securitydialog : public QDialog { Q_OBJECT public : explicit securitydialog(QWidget *parent = 0); ~securitydialog(); private slots: void on_ST_CheckBox_toggled(bool checked); void on_ST_OkButton_clicked(); private: Ui::securitydialog *ui; }; #endif // SECURITYDIALOG_H nitrokey-app-1.3.2/src/ui/securitydialog.ui0000644000175000017500000000706113221173116020274 0ustar janjan00000000000000 securitydialog 0 0 551 669 Dialog 30 20 491 601 <html><head/><body><p align="center"><span style=" font-size:12pt; font-weight:600;">Security Information</span></p><p>Please read the following carefully.</p><p><span style=" font-weight:600;">PIN Protection</span></p><p>Nitrokey is protected by both a user PIN and an admin PIN. Your user PIN can unlock the encrypted storage, password safe, smart card and (if enabled) One-Time Passwords (OTP). OTPs aren't PIN-protected by default because they are only used as a secondary factor. The smart card is unlocked whenever the user PIN is entered, regardless of the function for which the PIN is entered. The admin PIN can be used to configure settings and to add or change entries. You must change the default PINs and keep them confidential. If the user PIN and admin PIN are entered incorrectly three times each, or if the smart card has been reset to factory settings, all your sensitive data will be permanently lost.</p><p><span style=" font-weight:600;">Physical Protection</span></p><p>All sensitive data is encrypted and secured against physical attacks. This does not apply to One-Time Passwords (OTP) because they are only used as a secondary factor.</p><p><span style=" font-weight:600;">Hidden Volumes</span></p><p>Hidden volumes require that the mass storage be initialised with random data. Hidden volumes are protected by both a user PIN and a separate password which can be different for each hidden volume. Without knowing both the user PIN and password, the hidden volume cannot be found and its existence can therefore neither be proven nor disproven. The password for the hidden volume must be strong and long enough to withstand a brute force attack. The hidden volumes are however stored on a flash storage with integrated wear levelling, meaning that information could potentially be leaked to a sophisticated attacker, thereby revealing the existence of hidden volumes.</p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 390 630 75 27 OK true 51 633 331 20 I read and understood this security warning nitrokey-app-1.3.2/src/ui/stick20changepassworddialog.cpp0000644000175000017500000002523413314460010022777 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include "stick20changepassworddialog.h" #include "nitrokey-applet.h" #include "stick20responsedialog.h" #include "ui_stick20changepassworddialog.h" #include "libada.h" #include #include "src/core/ThreadWorker.h" #include using nm = nitrokey::NitrokeyManager; DialogChangePassword::DialogChangePassword(QWidget *parent, PasswordKind _kind): QDialog(parent), ui(new Ui::DialogChangePassword), kind(_kind) { ui->setupUi(this); ui->lineEdit_OldPW->setEchoMode(QLineEdit::Password); ui->lineEdit_OldPW->setMaxLength(STICK20_PASSOWRD_LEN); // TODO change define to constant ui->lineEdit_NewPW_1->setEchoMode(QLineEdit::Password); ui->lineEdit_NewPW_1->setMaxLength(STICK20_PASSOWRD_LEN); // TODO change to // UI_PASSWORD_LEN // this and other // occurences ui->lineEdit_NewPW_2->setEchoMode(QLineEdit::Password); ui->lineEdit_NewPW_2->setMaxLength(STICK20_PASSOWRD_LEN); fixWindowGeometry(); ui->lineEdit_OldPW->setFocus(); setModal(true); connect(parent, SIGNAL(LongOperationStart()), this, SLOT(reject())); } DialogChangePassword::~DialogChangePassword() { delete ui; } void DialogChangePassword::fixWindowGeometry() { resize(0, 0); adjustSize(); updateGeometry(); moveWindowToCenter(); } void DialogChangePassword::UpdatePasswordRetry() { QString noTrialsLeft; // update password retry values switch (kind) { case PasswordKind::USER: noTrialsLeft = tr("Unfortunately you have no more trials left. Please use 'Reset User PIN' " "option from menu to reset password"); break; case PasswordKind::ADMIN: case PasswordKind::RESET_USER: noTrialsLeft = tr("Unfortunately you have no more trials left. Please check instruction how to " "reset Admin password."); break; case PasswordKind::UPDATE: ui->retryCount->hide(); ui->retryCountLabel->hide(); break; } PasswordKind k = kind; ui->retryCount->setText("..."); new ThreadWorker( [k]() -> Data { Data data; switch (k) { case PasswordKind::USER: data["counter"] = libada::i()->getUserPasswordRetryCount(); break; case PasswordKind::ADMIN: case PasswordKind::RESET_USER: data["counter"] = libada::i()->getAdminPasswordRetryCount(); break; case PasswordKind::UPDATE: data["counter"] = 99; break; } return data; }, [this, noTrialsLeft](Data data){ int retryCount_local = data["counter"].toInt(); ui->retryCount->setText(QString::number(retryCount_local)); ui->retryCount->repaint(); fixWindowGeometry(); if (retryCount_local == 0) { QString cssRed = "QLabel {color: red; font-weight: bold}"; ui->retryCount->setStyleSheet(cssRed); ui->retryCountLabel->setStyleSheet(cssRed); csApplet()->warningBox(noTrialsLeft); done(true); emit UserPinLocked(); } }, this); } void DialogChangePassword::UI_deviceNotInitialized() const { csApplet()->warningBox(tr("Device is not yet initialized. Please try again later.")); } int DialogChangePassword::exec() { if (!libada::i()->isDeviceInitialized()) { UI_deviceNotInitialized(); done(Rejected); return QDialog::Rejected; } return QDialog::exec(); } #include void DialogChangePassword::InitData(void) { moveWindowToCenter(); this->UpdatePasswordRetry(); minimumPasswordLength = minimumPasswordLengthUser; switch (kind) { case PasswordKind::USER: this->setWindowTitle(tr("Set User PIN")); ui->label_2->setText(tr("Current User PIN:")); ui->label_3->setText(tr("New PIN:")); ui->label_4->setText(tr("Confirm New PIN:")); minimumPasswordLength = minimumPasswordLengthUser; break; case PasswordKind::ADMIN: this->setWindowTitle(tr("Set Admin PIN")); ui->label_2->setText(tr("Current Admin PIN:")); ui->label_3->setText(tr("New PIN:")); ui->label_4->setText(tr("Confirm New PIN:")); minimumPasswordLength = minimumPasswordLengthAdmin; break; case PasswordKind::RESET_USER: this->setWindowTitle(tr("Reset User PIN")); ui->label_2->setText(tr("Current Admin PIN:")); ui->label_3->setText(tr("New User PIN:")); ui->label_4->setText(tr("Confirm New User PIN:")); minimumPasswordLength = minimumPasswordLengthUser; break; case PasswordKind::UPDATE: this->setWindowTitle(tr("Change Firmware Password")); ui->label_2->setText(tr("Current Firmware Password:")); ui->label_3->setText(tr("New Password:")); ui->label_4->setText(tr("Confirm New Password:")); ui->checkBox->setText(tr("Show password")); minimumPasswordLength = minimumPasswordLengthFirmware; break; } ui->lineEdit_OldPW->setAccessibleName(ui->label_2->text()); ui->lineEdit_NewPW_1->setAccessibleName(ui->label_3->text()); ui->lineEdit_NewPW_2->setAccessibleName(ui->label_4->text()); // replace %1 and %2 from text with proper values //(min and max of password length) QString text = ui->label_additional_information->text(); text = text.arg(minimumPasswordLength).arg(STICK20_PASSOWRD_LEN); if (kind == PasswordKind::UPDATE) { text = " " + tr("The Firmware password doesn’t have a retry counter, and therefore doesn’t prevent against password guessing attacks. " "A secure and complex password should be created with the use of: " "lower and upper case letters, numbers and special characters; with a length between %2 and %3 characters." "
Default firmware password is: '%1'.").arg(defaultFirmwarePassword).arg(minimumPasswordLengthFirmware).arg(maximumPasswordLengthFirmware) + "
"; text += QString("

") + tr("WARNING! If you lose your Firmware password, Nitrokey can’t be updated or reset!") + QString("

"); } ui->label_additional_information->setText(text); fixWindowGeometry(); } void DialogChangePassword::moveWindowToCenter() {// center the password window QDesktopWidget *desktop = QApplication::desktop(); setGeometry( QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), desktop->availableGeometry())); } void DialogChangePassword::_changePassword(void) { QByteArray PasswordString, PasswordStringNew; PasswordString = ui->lineEdit_OldPW->text().toLatin1(); PasswordStringNew = ui->lineEdit_NewPW_1->text().toLatin1(); PasswordKind k = kind; new ThreadWorker( [k, PasswordString, PasswordStringNew]() -> Data { Data data; try { switch (k) { case PasswordKind::USER: nm::instance()->change_user_PIN(PasswordString.constData(), PasswordStringNew.constData()); break; case PasswordKind::ADMIN: nm::instance()->change_admin_PIN(PasswordString.constData(), PasswordStringNew.constData()); break; case PasswordKind::UPDATE: nm::instance()->change_update_password(PasswordString.constData(), PasswordStringNew.constData()); break; case PasswordKind::RESET_USER: nm::instance()->unlock_user_password(PasswordString.constData(), PasswordStringNew.constData()); break; } data["result"] = true; } catch (CommandFailedException &e){ if(!e.reason_wrong_password()){ data["err"] = e.last_command_status; // emit this->error(e.last_command_status); } data["result"] = false; } return data; }, [this](Data data){ bool result = data["result"].toBool(); if (!result){ csApplet()->warningBox(tr("Current password is not correct. Please retry.")); this->UpdatePasswordRetry(); this->clearFields(); } else{ csApplet()->messageBox(tr("New password is set")); done(true); } }, this); } void DialogChangePassword::accept() { // Check the length of the old password QString OutputText; if (minimumPasswordLength > ui->lineEdit_OldPW->text().toLatin1().length()) { clearFields(); OutputText = tr("The minimum length of the old password is ") + QString("%1").arg(minimumPasswordLength) + tr(" chars"); csApplet()->warningBox(OutputText); return; } // Check for correct new password entries if (ui->lineEdit_NewPW_1->text() != ui->lineEdit_NewPW_2->text()) { clearFields(); csApplet()->warningBox(tr("The new password entries are not the same")); return; } // Check the new length of password - max // obsolete since input field max length is set if (STICK20_PASSOWRD_LEN < ui->lineEdit_NewPW_1->text().toLatin1().length()) { clearFields(); OutputText = tr("The maximum length of a password is ") + QString("%1").arg(STICK20_PASSOWRD_LEN) + tr(" chars"); csApplet()->warningBox(OutputText); return; } // Check the new length of password - min if (minimumPasswordLength > ui->lineEdit_NewPW_1->text().toLatin1().length()) { clearFields(); OutputText = tr("The minimum length of a password is ") + QString("%1").arg(minimumPasswordLength) + tr(" chars"); csApplet()->warningBox(OutputText); return; } _changePassword(); } void DialogChangePassword::on_checkBox_clicked(bool checked) { auto mode = checked ? QLineEdit::Normal : QLineEdit::Password; ui->lineEdit_OldPW->setEchoMode(mode); ui->lineEdit_NewPW_1->setEchoMode(mode); ui->lineEdit_NewPW_2->setEchoMode(mode); } void DialogChangePassword::clearFields() { ui->lineEdit_OldPW->clear(); ui->lineEdit_NewPW_1->clear(); ui->lineEdit_NewPW_2->clear(); ui->lineEdit_OldPW->setFocus(); } nitrokey-app-1.3.2/src/ui/stick20changepassworddialog.h0000644000175000017500000000401313275777051022462 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef DIALOGCHANGEPASSWORD_H #define DIALOGCHANGEPASSWORD_H enum class PasswordKind { USER, ADMIN, RESET_USER, UPDATE }; #include namespace Ui { class DialogChangePassword; } class DialogChangePassword : public QDialog { Q_OBJECT public : // FIXME extract constant to global config const static int minimumPasswordLengthUser = 6; const static int minimumPasswordLengthAdmin = 8; const static int minimumPasswordLengthFirmware = 8; const static int maximumPasswordLengthFirmware = 20; static constexpr auto defaultFirmwarePassword = "12345678"; int minimumPasswordLength = {}; explicit DialogChangePassword(QWidget *parent, PasswordKind _kind); ~DialogChangePassword(); void InitData(void); virtual int exec() override; // signals: void UserPinLocked(); // void error(int errcode); private slots: void on_checkBox_clicked(bool checked); private: Ui::DialogChangePassword *ui; PasswordKind kind; void _changePassword(); void accept(void) override; void UpdatePasswordRetry(void); void clearFields(); void fixWindowGeometry(); void UI_deviceNotInitialized() const; void moveWindowToCenter(); }; #endif // DIALOGCHANGEPASSWORD_H nitrokey-app-1.3.2/src/ui/stick20changepassworddialog.ui0000644000175000017500000002117113275777051022654 0ustar janjan00000000000000 DialogChangePassword 0 0 420 369 0 0 420 300 Change user PIN :/images/new/icon_NK.svg:/images/new/icon_NK.svg 0 0 false QFrame::NoFrame QFrame::Plain QFormLayout::AllNonFixedFieldsGrow Old PIN Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Current PIN or password New PIN Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 New PIN or password New PIN Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 New PIN or password 0 0 Show PIN 0 0 true Qt::StrongFocus <html><head/><body><p><span style=" font-style:italic;">Nitrokey prevents against brute force password guessing attacks by allowing a maximum of 3 incorrect PIN attempts. Therefore a PIN of %1 digits is sufficient. The PIN must be between %1 and %2 characters.</span></p></body></html> false true Retry count left: Qt::StrongFocus Retry count left: 3 Qt::Vertical 20 40 Qt::Horizontal Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok lineEdit_OldPW lineEdit_NewPW_1 lineEdit_NewPW_2 checkBox label_additional_information retryCount buttonBox accepted() DialogChangePassword accept() 248 254 157 274 buttonBox rejected() DialogChangePassword reject() 316 260 286 274 nitrokey-app-1.3.2/src/ui/stick20debugdialog.cpp0000644000175000017500000000234213275777051021076 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include "stick20debugdialog.h" #include "ui_stick20debugdialog.h" DebugDialog::DebugDialog(QWidget *parent) : QDialog(parent), ui(new Ui::DebugDialog) { ui->setupUi(this); ui->TextGUI->clear(); } DebugDialog::~DebugDialog() { delete ui; } void DebugDialog::on_DebugData(QString message) { message[message.size()-1] = ' '; ui->TextGUI->appendPlainText(message); // ui->TextGUI->appendPlainText(message.trimmed()); } nitrokey-app-1.3.2/src/ui/stick20debugdialog.h0000644000175000017500000000220513275777051020541 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef DEBUGDIALOG_H #define DEBUGDIALOG_H #include namespace Ui { class DebugDialog; } class DebugDialog : public QDialog { Q_OBJECT public : explicit DebugDialog(QWidget *parent = 0); ~DebugDialog(); public slots: void on_DebugData(QString message); private: Ui::DebugDialog *ui; }; #endif // DEBUGDIALOG_H nitrokey-app-1.3.2/src/ui/stick20debugdialog.ui0000644000175000017500000000441313275777051020732 0ustar janjan00000000000000 DebugDialog 0 0 793 789 Debug Log :/images/new/icon_NK.svg:/images/new/icon_NK.svg Courier New QPlainTextEdit::NoWrap true Debug Log Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() DebugDialog accept() 248 254 157 274 buttonBox rejected() DebugDialog reject() 316 260 286 274 nitrokey-app-1.3.2/src/ui/stick20hiddenvolumedialog.cpp0000644000175000017500000003076613275777051022506 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include #include #include "stick20hiddenvolumedialog.h" #include "math.h" #include "mcvs-wrapper.h" #include "nitrokey-applet.h" #include "ui_stick20hiddenvolumedialog.h" #include "src/utils/bool_values.h" stick20HiddenVolumeDialog::stick20HiddenVolumeDialog(QWidget *parent) : QDialog(parent), ui(new Ui::stick20HiddenVolumeDialog) { ui->setupUi(this); ui->comboBox->setCurrentIndex(HV_Setup_st.SlotNr_u8); ui->StartBlockSpin->setValue(HV_Setup_st.StartBlockPercent_u8); ui->EndBlockSpin->setValue(HV_Setup_st.EndBlockPercent_u8); ui->HVPasswordEdit->setMaxLength(MAX_HIDDEN_VOLUME_PASSOWORD_SIZE); ui->HVPasswordEdit->setText(""); ui->HVPasswordEdit_2->setMaxLength(MAX_HIDDEN_VOLUME_PASSOWORD_SIZE); ui->HVPasswordEdit_2->setText(""); ui->HVPasswordEdit->setFocus(); ui->HV_settings_groupBox->setEnabled(false); new ThreadWorker( []() -> Data { Data data; auto m = nitrokey::NitrokeyManager::instance(); auto p = m->get_SD_usage_data(); data["min"] = p.first; data["max"] = p.second; data["size"] = libada::i()->getStorageSDCardSizeGB(); return data; }, [this](Data data){ HighWatermarkMin = (uint8_t) data["min"].toInt(); HighWatermarkMax = (uint8_t) data["max"].toInt(); sd_size_GB = data["size"].toInt(); setHighWaterMarkText(); on_rd_percent_clicked(); ui->rd_percent->setChecked(true); ui->HV_settings_groupBox->setEnabled(true); }, this); } stick20HiddenVolumeDialog::~stick20HiddenVolumeDialog() { delete ui; } void stick20HiddenVolumeDialog::on_ShowPasswordCheckBox_toggled(bool checked) { if (checked) { ui->HVPasswordEdit_2->setEchoMode(QLineEdit::Normal); ui->HVPasswordEdit->setEchoMode(QLineEdit::Normal); } else { ui->HVPasswordEdit_2->setEchoMode(QLineEdit::Password); ui->HVPasswordEdit->setEchoMode(QLineEdit::Password); } } void stick20HiddenVolumeDialog::on_buttonBox_clicked(QAbstractButton *button) { if (button == (QAbstractButton *) ui->buttonBox->button(QDialogButtonBox::Ok)) { on_rd_percent_clicked(); ui->rd_percent->setChecked(true); auto password_byte_array = ui->HVPasswordEdit->text().toLatin1(); if (8 > strlen(password_byte_array.constData())) { csApplet()->warningBox(tr("Your password is too short. Use at least 8 characters.")); return; } if (ui->HVPasswordEdit->text() != ui->HVPasswordEdit_2->text()) { csApplet()->warningBox(tr("The passwords are not identical")); return; } HV_Setup_st.SlotNr_u8 = ui->comboBox->currentIndex(); HV_Setup_st.StartBlockPercent_u8 = ui->StartBlockSpin->value(); HV_Setup_st.EndBlockPercent_u8 = ui->EndBlockSpin->value(); if (HV_Setup_st.StartBlockPercent_u8 >= HV_Setup_st.EndBlockPercent_u8) { csApplet()->warningBox(tr("Wrong size of hidden volume")); return; } if (HV_Setup_st.StartBlockPercent_u8 < HighWatermarkMin || HV_Setup_st.EndBlockPercent_u8 > HighWatermarkMax) { csApplet()->warningBox(tr("Hidden volume not positioned in unwritten space. Please set your " "volume between %1% and %2% of total SD card size.") .arg(HighWatermarkMin) .arg(HighWatermarkMax)); return; } auto p = password_byte_array.constData(); //FIXME use proper copy strncpy((char *) HV_Setup_st.HiddenVolumePassword_au8, p, password_byte_array.length()); HV_Setup_st.HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSOWORD_SIZE] = 0; done(true); } else if (button == (QAbstractButton *) ui->buttonBox->button(QDialogButtonBox::Cancel)) { done(false); } } // Based on // http://www.emoticode.net/c/optimized-f-the-shannf-the-shannon-entropy-algorithm.html // (site not working as of 2016.08) struct charset_space { int CharSpace; int HasLowerAlpha : 1; int HasUpperAlpha : 1; int HasGermanChars : 1; int HasNumber : 1; int HasSpecialChars1 : 1; int HasSpecialChars2 : 1; int HasSpecialChars3 : 1; void clear() { memset(this, 0, sizeof(*this)); } } c; int stick20HiddenVolumeDialog::GetCharsetSpace(unsigned char *Password, size_t size) { size_t i; c.clear(); for (i = 0; i < size; i++) { if ((FALSE == c.HasLowerAlpha) && (0 != strchr("abcdefghijklmnopqrstuvwxyz", Password[i]))) { c.CharSpace += 26; c.HasLowerAlpha = TRUE; } if ((FALSE == c.HasUpperAlpha) && (0 != strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", Password[i]))) { c.CharSpace += 26; c.HasUpperAlpha = TRUE; } if ((FALSE == c.HasGermanChars) && (0 != strchr("öäüÖÄÜß", Password[i]))) { c.CharSpace += 7; c.HasGermanChars = TRUE; } if ((FALSE == c.HasNumber) && (0 != strchr("0123456789", Password[i]))) { c.CharSpace += 10; c.HasNumber = TRUE; } if ((FALSE == c.HasSpecialChars1) && (0 != strchr("!\"§$%&/()=?'", Password[i]))) { c.CharSpace += 11; c.HasSpecialChars1 = TRUE; } if ((FALSE == c.HasSpecialChars2) && (0 != strchr("',.-#+´;:_*<>^°`", Password[i]))) { c.CharSpace += 16; c.HasSpecialChars2 = TRUE; } if ((FALSE == c.HasSpecialChars3) && (0 != strchr("~[{]}\\|€@", Password[i]))) { c.CharSpace += 9; c.HasSpecialChars3 = TRUE; } } return (c.CharSpace); } double stick20HiddenVolumeDialog::GetEntropy(unsigned char *Password, size_t size) { double Entropy = 0.0; int CharsetSpace; CharsetSpace = GetCharsetSpace(Password, size); if (CharsetSpace == 0) return 0; // Entropy by CharsetSpace * size Entropy = (double)size * (log((double)CharsetSpace) / log(2.0)); return (Entropy); } int password_human_strength(double entropy) { if (entropy < 28) return 0; if (entropy < 36) return 1; if (entropy < 60) return 2; if (entropy < 128) return 3; return 4; } void stick20HiddenVolumeDialog::on_HVPasswordEdit_textChanged(const QString &arg1) { int Len; double Entropy; QString labels[] = {tr("Very Weak"), tr("Weak"), tr("Medium"), tr("Strong"), tr("Very Strong")}; Len = arg1.length(); auto byteArray = arg1.toLatin1(); Entropy = GetEntropy((unsigned char *) byteArray.data(), Len); if (Entropy < 0) { Entropy = 0; } // == using human readable symbols, 127 bits // ui->HVEntropieRealWords->setText( // QString("%1").sprintf("using human readable symbols: %3.1lf", Entropy / 2.0)); int strength = password_human_strength(Entropy); ui->password_strength_progressBar->setFormat(labels[strength]); ui->password_strength_progressBar->setValue(100.0 * Entropy / 64.0 / 2.0); // ui->password_strength_progressBar->setValue(100*strength/4); ui->cb_lower_case->setChecked(c.HasLowerAlpha); ui->cb_upper_case->setChecked(c.HasUpperAlpha); ui->cb_numbers->setChecked(c.HasNumber); ui->cb_symbols->setChecked(c.HasSpecialChars1 || c.HasSpecialChars2 || c.HasSpecialChars3 || c.HasGermanChars); ui->cb_length->setChecked(Len > 12); } void stick20HiddenVolumeDialog::setHighWaterMarkText(void) { if (5 > HighWatermarkMin) // Set lower limit { HighWatermarkMin = 10; } if (90 < HighWatermarkMax) // Set higher limit { HighWatermarkMax = 90; } ui->HVSdCardHighWaterMark->setText( tr("The unwritten area available for hidden volume\nis between " "%1 % and %2 % of the storage size") .arg(HighWatermarkMin) .arg(HighWatermarkMax)); ui->StartBlockSpin->setValue(HV_Setup_st.StartBlockPercent_u8); ui->EndBlockSpin->setValue(HV_Setup_st.EndBlockPercent_u8); ui->l_sd_size->setText(tr("Storage capacity: %1GB").arg(sd_size_GB)); auto rounding_info = ui->l_rounding_info->text().arg((sd_size_GB * 1024 / 100)); ui->l_rounding_info->setText(rounding_info); ui->StartBlockSpin->setAccessibleDescription(rounding_info); ui->EndBlockSpin->setAccessibleDescription(rounding_info); } void stick20HiddenVolumeDialog::on_rd_unit_clicked(QString text) { const size_t sd_size_MB = sd_size_GB * 1024u; double current_block_start = ui->StartBlockSpin->value(); double current_block_end = ui->EndBlockSpin->value(); if (i_start_MB == 0) { i_start_MB = sd_size_MB * current_block_start / 100.0; i_end_MB = sd_size_MB * current_block_end / 100.0; } QString start = tr("Start hidden volume at %1 of the encrypted storage:"); QString end = tr("End hidden volume at %1 of the encrypted storage:"); ui->l_sd_start->setText(start.arg(text)); ui->l_sd_end->setText(end.arg(text)); ui->StartBlockSpin->setAccessibleName(start.arg(text)); ui->EndBlockSpin->setAccessibleName(end.arg(text)); switch (last) { case 'M': i_start_MB = current_block_start; i_end_MB = current_block_end; break; case 'G': i_start_MB = current_block_start * 1024; i_end_MB = current_block_end * 1024; break; case '%': i_start_MB = current_block_start * sd_size_MB / 100.0; i_end_MB = current_block_end * sd_size_MB / 100.0; break; default: break; } cancel_BlockSpin_event_propagation = true; char current = text.data()[0].toLatin1(); switch (current) { case 'M': current_min = HighWatermarkMin * sd_size_MB / 100.; current_max = HighWatermarkMax * sd_size_MB / 100.; current_step = sd_size_MB/100.; set_spins_min_max(current_min, current_max, current_step); ui->StartBlockSpin->setValue(i_start_MB); ui->EndBlockSpin->setValue(i_end_MB); break; case 'G': current_min = HighWatermarkMin * sd_size_GB / 100.; current_max = HighWatermarkMax * sd_size_GB / 100.; current_step = sd_size_GB/100.; set_spins_min_max(current_min, current_max, current_step); ui->StartBlockSpin->setValue(i_start_MB / 1024.0); ui->EndBlockSpin->setValue(i_end_MB / 1024.0); break; case '%': current_min = HighWatermarkMin; current_max = HighWatermarkMax; current_step = 1; set_spins_min_max(current_min, current_max, current_step); ui->StartBlockSpin->setValue(100.0 * i_start_MB / sd_size_MB); ui->EndBlockSpin->setValue(100.0 * i_end_MB / sd_size_MB); break; default: break; } cancel_BlockSpin_event_propagation = false; last = current; } void stick20HiddenVolumeDialog::set_spins_min_max(const double min, const double max, const double step) { ui->StartBlockSpin->setSingleStep(step); ui->StartBlockSpin->setRange(min,max); ui->EndBlockSpin->setSingleStep(step); ui->EndBlockSpin->setRange(min,max); } void stick20HiddenVolumeDialog::on_EndBlockSpin_valueChanged(double i){ Q_UNUSED(i) if (cancel_BlockSpin_event_propagation) return; cancel_BlockSpin_event_propagation = true; auto start_val = ui->StartBlockSpin->value(); auto current_val = ui->EndBlockSpin->value(); if(current_val < start_val || current_val - start_val < current_step){ ui->EndBlockSpin->setValue(start_val + current_step); } else if(current_val > current_max){ ui->EndBlockSpin->setValue(current_max); } cancel_BlockSpin_event_propagation = false; } void stick20HiddenVolumeDialog::on_StartBlockSpin_valueChanged(double i){ Q_UNUSED(i) if (cancel_BlockSpin_event_propagation) return; cancel_BlockSpin_event_propagation = true; auto end_val = ui->EndBlockSpin->value(); auto current_val = ui->StartBlockSpin->value(); if(current_val > end_val || end_val - current_val < current_step){ ui->StartBlockSpin->setValue(end_val - current_step); } else if(current_val < current_min){ ui->StartBlockSpin->setValue(current_min); } cancel_BlockSpin_event_propagation = false; } void stick20HiddenVolumeDialog::on_rd_MB_clicked() { on_rd_unit_clicked("MB"); } void stick20HiddenVolumeDialog::on_rd_GB_clicked() { on_rd_unit_clicked("GB"); } void stick20HiddenVolumeDialog::on_rd_percent_clicked() { on_rd_unit_clicked("%"); } nitrokey-app-1.3.2/src/ui/stick20hiddenvolumedialog.h0000644000175000017500000000471513275777051022146 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef STICK20HIDDENVOLUMEDIALOG_H #define STICK20HIDDENVOLUMEDIALOG_H #include #include #include "libada.h" #include namespace Ui { class stick20HiddenVolumeDialog; } typedef struct { unsigned char SlotNr_u8 = 0; unsigned char StartBlockPercent_u8 = 70; unsigned char EndBlockPercent_u8 = 90; unsigned char HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSOWORD_SIZE + 1] = {}; } HiddenVolumeSetup_tst; class stick20HiddenVolumeDialog : public QDialog { Q_OBJECT public : explicit stick20HiddenVolumeDialog(QWidget *parent = 0); ~stick20HiddenVolumeDialog(); HiddenVolumeSetup_tst HV_Setup_st; private: int GetCharsetSpace(unsigned char *Password, size_t size); double GetEntropy(unsigned char *Password, size_t size); uint8_t HighWatermarkMin; uint8_t HighWatermarkMax; int sd_size_GB; void setHighWaterMarkText(void); void on_rd_unit_clicked(QString text); private slots: void on_ShowPasswordCheckBox_toggled(bool checked); void on_buttonBox_clicked(QAbstractButton *button); void on_HVPasswordEdit_textChanged(const QString &arg1); void on_rd_percent_clicked(); void on_rd_MB_clicked(); void on_rd_GB_clicked(); void on_StartBlockSpin_valueChanged(double i); void on_EndBlockSpin_valueChanged(double i); private: Ui::stick20HiddenVolumeDialog *ui; void set_spins_min_max(const double min, const double max, const double step); char last = '%'; double i_start_MB = 0; double i_end_MB = 0; double current_min = 0; double current_max = 100; double current_step = 1; std::atomic_bool cancel_BlockSpin_event_propagation {false}; }; #endif // STICK20HIDDENVOLUMEDIALOG_H nitrokey-app-1.3.2/src/ui/stick20hiddenvolumedialog.ui0000644000175000017500000005067313275777051022340 0ustar janjan00000000000000 stick20HiddenVolumeDialog 0 0 525 668 0 0 Setup hidden volume :/images/new/icon_NK.svg:/images/new/icon_NK.svg 0 0 false QFrame::NoFrame QFrame::Plain 0 0 66 58 66 58 66 58 :/images/warning.png 0 0 Qt::StrongFocus <html><head/><body><p><span style=" font-weight:600;">You should understand the properties of hidden volumes before proceeding. It can destroy your encrypted data! <br/>Please read </span><a href="https://www.nitrokey.com/documentation/hidden-volumes"><span style=" font-weight:600; text-decoration: underline; color:#0000ff;">these instructions</span></a><span style=" font-weight:600;"> first.</span></p></body></html> false true true 0 0 Qt::StrongFocus <html><head/><body><p>1. You may want to copy some innocuous files to the encrypted data.<br/>2. Configure hidden volumes in this dialogue. <br/>3. Once you configured a hidden volume you must not use/write to the encryption volume anymore. Otherwise it may destroy the data in your hidden volume.</p></body></html> true Password settings Password: Hidden volume password Please use shift+tab key shortcut for instructions 12345678901234567890 20 QLineEdit::Password Password: Qt::StrongFocus Hidden volume password (repeated) 12345678901234567890 20 QLineEdit::Password Show password Password strength: Password strength: 42 false Qt::NoFocus length false Qt::NoFocus lower case false Qt::NoFocus upper case true false Qt::NoFocus numbers false Qt::NoFocus symbols 0 0 100 101 Hidden Volume settings false 0 0 Slot under which hidden volume information will be stored Hidden volume slot 1 Hidden volume slot 2 Hidden volume slot 3 Hidden volume slot 4 SD card information Qt::AlignCenter QFrame::Box Qt::StrongFocus Storage capacity: %1GB Qt::Horizontal 40 20 Unit: Use this as hidden volume size unit % Use this as hidden volume size unit MB Use this as hidden volume size unit GB Start at %1 of SD size: Qt::Horizontal 40 20 0 0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 999999999999999983222784.000000000000000 End at %1 of SD size: Qt::Horizontal 40 20 0 0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 99999999999999997748809823456034029568.000000000000000 0 0 0 0 Size will be rounded down to integral percent of total storage size (%1MB) Qt::Horizontal Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok l_top_instructions l_instructions HVPasswordEdit HVPasswordEdit_2 ShowPasswordCheckBox comboBox l_sd_size rd_percent rd_MB rd_GB StartBlockSpin EndBlockSpin nitrokey-app-1.3.2/src/ui/stick20lockfirmwaredialog.cpp0000644000175000017500000000335613275777051022503 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2014-06-02 * Copyright (c) 2014-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include "stick20lockfirmwaredialog.h" #include "ui_stick20lockfirmwaredialog.h" /******************************************************************************* Local defines *******************************************************************************/ /******************************************************************************* External declarations *******************************************************************************/ /******************************************************************************* stick20LockFirmwareDialog Constructor stick20LockFirmwareDialog Reviews Date Reviewer Info *******************************************************************************/ stick20LockFirmwareDialog::stick20LockFirmwareDialog(QWidget *parent) : QDialog(parent), ui(new Ui::stick20LockFirmwareDialog) { ui->setupUi(this); } stick20LockFirmwareDialog::~stick20LockFirmwareDialog() { delete ui; } nitrokey-app-1.3.2/src/ui/stick20lockfirmwaredialog.h0000644000175000017500000000217613275777051022147 0ustar janjan00000000000000/* * Copyright (c) 2014-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef STICK20LOCKFIRMWAREDIALOG_H #define STICK20LOCKFIRMWAREDIALOG_H #include namespace Ui { class stick20LockFirmwareDialog; } class stick20LockFirmwareDialog : public QDialog { Q_OBJECT public : explicit stick20LockFirmwareDialog(QWidget *parent = 0); ~stick20LockFirmwareDialog(); private: Ui::stick20LockFirmwareDialog *ui; }; #endif // STICK20LOCKFIRMWAREDIALOG_H nitrokey-app-1.3.2/src/ui/stick20lockfirmwaredialog.ui0000644000175000017500000000771313275777051022337 0ustar janjan00000000000000 stick20LockFirmwareDialog 0 0 315 229 0 0 Lock Firmware :/images/new/icon_NK.svg:/images/new/icon_NK.svg false QFrame::StyledPanel QFrame::Sunken 16 75 true Lock Firmware Qt::AlignCenter 0 0 <html><head/><body><p>When you select &quot;OK&quot; the stick lock the firmware and close the hardware debug port.This disables any external hardware access to the data in the device (processor).</p><p>There is no way back! </p><p>After this you can't update the firmware.</p></body></html> true Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() stick20LockFirmwareDialog accept() 248 254 157 274 buttonBox rejected() stick20LockFirmwareDialog reject() 316 260 286 274 nitrokey-app-1.3.2/src/ui/stick20responsedialog.cpp0000644000175000017500000002066513314460010021630 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include #include #include #include #include #include "nitrokey-applet.h" //#include "stick20-response-task.h" #include "stick20responsedialog.h" #include "ui_stick20responsedialog.h" #include "libada.h" Stick20ResponseDialog::Stick20ResponseDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Stick20ResponseDialog) { ui->setupUi(this); ui->LabelProgressWheel->setAttribute(Qt::WA_TranslucentBackground, true); center_window(); // bool should_show_progress_wheel = false; //STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS != Stick20Task->ActiveCommand; // bool no_debug = true; // todo FALSE == DebugingActive; // set_window_type(Type::wheel, false); // pollStick20Timer = new QTimer(this); // Start timer for polling stick response // connect(pollStick20Timer, SIGNAL(timeout()), this, SLOT(checkStick20StatusDialog())); // pollStick20Timer->start(100); this->layout()->setSizeConstraint(QLayout::SetFixedSize); ProgressMovie = std::make_shared(":/images/progressWheel2.gif"); } void Stick20ResponseDialog::center_window() { setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), QApplication::desktop()->availableGeometry())); } void Stick20ResponseDialog::set_window_type(Type type, bool no_debug, QString text) { ui->HeaderText->setText(text); ui->label->setText(text); if (current_type == type) return; if (type == Type::wheel) { setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); ui->HeaderText->hide(); } else if (type == Type::progress_bar){ setWindowFlags(Qt::Window); ui->HeaderText->show(); } if (no_debug) // Resize the dialog when debugging is inactive { ui->OutputText->hide(); ui->OutputText->setText(""); ui->LabelProgressWheel->setVisible(type == Type::wheel && no_debug); ui->label->setVisible(type == Type::wheel); ui->progressBar->setVisible(type == Type::progress_bar && no_debug); // Start progress wheel if (type == Type::wheel) { QSize SceneSize; SceneSize.setHeight(60); SceneSize.setWidth(60); ProgressMovie->setScaledSize(SceneSize); ui->LabelProgressWheel->setMovie(ProgressMovie.get()); ProgressMovie->start(); } } else { ui->HeaderText->show(); ui->progressBar->hide(); } current_type = type; this->show(); } Stick20ResponseDialog::~Stick20ResponseDialog() { delete ui; // Kill timer // pollStick20Timer->stop(); // delete pollStick20Timer; } #include void Stick20ResponseDialog::checkStick20StatusDialog(void) { // QString OutputText; // // if (STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS == Stick20Task->ActiveCommand) { // ui->HeaderText->show(); // } // // Stick20Task->checkStick20Status(); // // if (TRUE == DebugingActive) { // checkStick20StatusDebug(Stick20Task->stick20Response, Stick20Task->retStick20Respone); // } // // if (0 == Stick20Task->retStick20Respone) { // switch (Stick20Task->stick20Response->HID_Stick20Status_st.LastCommand_u8) { // case STICK20_CMD_ENABLE_CRYPTED_PARI: // OutputText.append(QString("Enabling encrypted volume")); // break; // case STICK20_CMD_DISABLE_CRYPTED_PARI: // OutputText.append(QString("Disabling encrypted volume")); // break; // case STICK20_CMD_ENABLE_HIDDEN_CRYPTED_PARI: // OutputText.append(QString("Enabling encrypted volume")); // break; // case STICK20_CMD_DISABLE_HIDDEN_CRYPTED_PARI: // OutputText.append(QString("Disabling encrypted volume")); // break; // case STICK20_CMD_SEND_NEW_PASSWORD: // OutputText.append(QString("Changing PIN")); // break; // case STICK20_CMD_ENABLE_FIRMWARE_UPDATE: // OutputText.append(QString("Enabling firmeware update")); // break; // case STICK20_CMD_EXPORT_FIRMWARE_TO_FILE: // OutputText.append(QString("Exporting firmware to file")); // break; // case STICK20_CMD_GENERATE_NEW_KEYS: // OutputText.append(QString("Generating new keys")); // break; // case STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS: // OutputText.append(QString("Initializing storage with random data")); // break; // case STICK20_CMD_GET_DEVICE_STATUS: // OutputText.append(QString("Getting device configuration")); // break; // case STICK20_CMD_ENABLE_READONLY_UNCRYPTED_LUN: // OutputText.append(QString("Enabling read-only configuration for the unencrypted volume")); // break; // case STICK20_CMD_ENABLE_READWRITE_UNCRYPTED_LUN: // OutputText.append(QString("Enabling read-write configuration for the unencrypted volume")); // break; // case STICK20_CMD_CLEAR_NEW_SD_CARD_FOUND: // OutputText.append(QString("Disabling 'initialize storage with random data' warning")); // break; // case STICK20_CMD_PRODUCTION_TEST: // OutputText.append(QString("Production test")); // break; // case STICK20_CMD_SEND_STARTUP: // OutputText.append(QString("Startup infos")); // break; // case STICK20_CMD_SEND_LOCK_STICK_HARDWARE: // OutputText.append(QString("Locking")); // break; // // default: // break; // } // // OutputText.append(QString(" (")); // // switch (Stick20Task->stick20Response->HID_Stick20Status_st.Status_u8) { // case OUTPUT_CMD_STICK20_STATUS_IDLE: // OutputText.append(QString("IDLE")); // break; // case OUTPUT_CMD_STICK20_STATUS_OK: // OutputText.append(QString("OK")); // pollStick20Timer->stop(); // done(TRUE); // break; // case OUTPUT_CMD_STICK20_STATUS_BUSY: // OutputText.append(QString("BUSY")); // break; // case OUTPUT_CMD_STICK20_STATUS_WRONG_PASSWORD: // OutputText.append(QString("WRONG PASSWORD")); // pollStick20Timer->stop(); // done(TRUE); // break; // case OUTPUT_CMD_STICK20_STATUS_BUSY_PROGRESSBAR: // OutputText.append(QString("BUSY")); // ui->progressBar->show(); // ui->LabelProgressWheel->hide(); // ui->progressBar->setValue( // Stick20Task->stick20Response->HID_Stick20Status_st.ProgressBarValue_u8); // break; // case OUTPUT_CMD_STICK20_STATUS_PASSWORD_MATRIX_READY: // OutputText.append(QString("PASSWORD MATRIX READY")); // pollStick20Timer->stop(); // done(TRUE); // break; // case OUTPUT_CMD_STICK20_STATUS_NO_USER_PASSWORD_UNLOCK: // OutputText.append(QString("NO USER PASSWORD UNLOCK")); // pollStick20Timer->stop(); // done(TRUE); // break; // case OUTPUT_CMD_STICK20_STATUS_SMARTCARD_ERROR: // OutputText.append(QString("SMARTCARD ERROR")); // pollStick20Timer->stop(); // done(TRUE); // break; // case OUTPUT_CMD_STICK20_STATUS_SECURITY_BIT_ACTIVE: // OutputText.append(QString("SECURITY BIT ACTIVE")); // pollStick20Timer->stop(); // done(TRUE); // break; // default: // break; // } // OutputText.append(QString(")")); // ui->HeaderText->setText(OutputText); // ui->label->setText(OutputText); // } } void Stick20ResponseDialog::updateOperationInProgressBar(int p) { init_long_operation(); ui->progressBar->setValue(p); if(p==100){ QTimer::singleShot(3*1000, [this](){ this->hide(); }); } } void Stick20ResponseDialog::init_long_operation() { QString description_string; description_string.append("Initializing storage with random data"); description_string.append(" (BUSY)"); set_window_type(Type::progress_bar, true, description_string); } void Stick20ResponseDialog::on_ShortOperationBegins(QString msg) { set_window_type(Type::wheel, true, msg); this->show(); } void Stick20ResponseDialog::on_ShortOperationEnds() { this->hide(); } nitrokey-app-1.3.2/src/ui/stick20responsedialog.h0000644000175000017500000000325013275777051021312 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef STICK20RESPONSEDIALOG_H #define STICK20RESPONSEDIALOG_H //#include "stick20-response-task.h" #include #include #include namespace Ui { class Stick20ResponseDialog; } class Stick20ResponseDialog : public QDialog { Q_OBJECT public : explicit Stick20ResponseDialog(QWidget *parent = 0); ~Stick20ResponseDialog(); enum class Type{ none, wheel, progress_bar }; public slots: void updateOperationInProgressBar(int p); void on_ShortOperationBegins(QString msg); void on_ShortOperationEnds(); private: Ui::Stick20ResponseDialog *ui; std::shared_ptr ProgressMovie; bool initialized = false; void init_long_operation(); void checkStick20StatusDialog(); void set_window_type(Type type, bool no_debug, QString text); void center_window(); Type current_type = Type::none; }; #endif // STICK20RESPONSEDIALOG_H nitrokey-app-1.3.2/src/ui/stick20responsedialog.ui0000644000175000017500000001021713275777051021501 0ustar janjan00000000000000 Stick20ResponseDialog Qt::ApplicationModal 0 0 342 123 0 0 Progress :/images/new/icon_NK.svg :/images/new/icon_NK.svg:/images/new/icon_NK.svg QLayout::SetFixedSize 11 50 false HeaderLabel Qt::PlainText Qt::AlignCenter LabelProgressWheel Qt::AlignCenter 13 Qt::Horizontal 0 0 24 Courier 10 Pitch 10 50 false false TextLabel Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true Qt::Vertical 0 0 HeaderText customContextMenuRequested(QPoint) Stick20ResponseDialog open() 195 29 190 103 nitrokey-app-1.3.2/src/ui/stick20updatedialog.cpp0000644000175000017500000000371713275777051021301 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #include "stick20updatedialog.h" #include "ui_stick20updatedialog.h" /******************************************************************************* Local defines *******************************************************************************/ /******************************************************************************* External declarations *******************************************************************************/ /******************************************************************************* UpdateDialog Constructor UpdateDialog Reviews Date Reviewer Info 13.08.13 RB First review *******************************************************************************/ UpdateDialog::UpdateDialog(QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) { ui->setupUi(this); } /******************************************************************************* UpdateDialog Destructor UpdateDialog Reviews Date Reviewer Info 13.08.13 RB First review *******************************************************************************/ UpdateDialog::~UpdateDialog() { delete ui; } nitrokey-app-1.3.2/src/ui/stick20updatedialog.h0000644000175000017500000000212213275777051020733 0ustar janjan00000000000000/* * Author: Copyright (C) Rudolf Boeddeker Date: 2013-08-13 * Copyright (c) 2013-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef UPDATEDIALOG_H #define UPDATEDIALOG_H #include namespace Ui { class UpdateDialog; } class UpdateDialog : public QDialog { Q_OBJECT public : explicit UpdateDialog(QWidget *parent = 0); ~UpdateDialog(); private: Ui::UpdateDialog *ui; }; #endif // UPDATEDIALOG_H nitrokey-app-1.3.2/src/ui/stick20updatedialog.ui0000644000175000017500000001101113275777051021116 0ustar janjan00000000000000 UpdateDialog 0 0 354 252 Firmware update :/images/new/icon_NK.svg:/images/new/icon_NK.svg 0 0 false QFrame::StyledPanel QFrame::Sunken 16 75 true Firmware update Qt::AlignCenter 0 0 <html><head/><body><p>When you select &quot;OK&quot; the device enters the <br/>firmware update mode. There is no way back!<br/>Please read the <a href="https://www.nitrokey.com/en/doc/firmware-update-storage"><span style=" text-decoration: underline; color:#0000ff;">documentation </span></a>how to <br/>update the firmware.</p><p>Continue entering the firmware update mode?</p><p><br/></p></body></html> true true Qt::Vertical 20 0 Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() UpdateDialog accept() 248 254 157 274 buttonBox rejected() UpdateDialog reject() 316 260 286 274 nitrokey-app-1.3.2/src/utils/bool_values.h0000644000175000017500000000157513275777051020141 0ustar janjan00000000000000/* * Copyright (c) 2017-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef NITROKEYAPP_BOOL_VALUES_H #define NITROKEYAPP_BOOL_VALUES_H #define TRUE 1 #define FALSE 0 #endif //NITROKEYAPP_BOOL_VALUES_H nitrokey-app-1.3.2/src/utils/sleep.h0000644000175000017500000000214413275777051016730 0ustar janjan00000000000000/* * Author: Copyright (C) Andrzej Surowiec 2012 * Copyright (c) 2012-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef SLEEP_H #define SLEEP_H #include class Sleep : public QThread { public: static void sleep(unsigned long secs) { QThread::sleep(secs); } static void msleep(unsigned long msecs) { QThread::msleep(msecs); } static void usleep(unsigned long usecs) { QThread::usleep(usecs); } }; #endif // SLEEP_H nitrokey-app-1.3.2/src/version.h0000644000175000017500000000214113275777051016142 0ustar janjan00000000000000/* * Copyright (c) 2017-2018 Nitrokey UG * * This file is part of Nitrokey App. * * Nitrokey App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Nitrokey App is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nitrokey App. If not, see . * * SPDX-License-Identifier: GPL-3.0 */ #ifndef NITROKEYAPP_VERSION_H #define NITROKEYAPP_VERSION_H #ifndef CMAKE_BUILD_TYPE #define CMAKE_BUILD_TYPE "" #define CMAKE_CXX_COMPILER "" #define CMAKE_CXX_FLAGS "" #endif #ifndef GUI_VERSION #define GUI_VERSION "1.3-unspecified" #endif #ifndef GIT_VERSION #define GIT_VERSION "" #endif #define COPYRIGHT_YEARS "2012-2018" #endif //NITROKEYAPP_VERSION_H nitrokey-app-1.3.2/libnitrokey/.gitignore0000644000175000017500000000011313221174520020014 0ustar janjan00000000000000*.sw* *.log *.o unittest/build/ *.pyc core .cache/ .idea/ CMakeFiles/ /.vs nitrokey-app-1.3.2/libnitrokey/.gitmodules0000644000175000017500000000000013275777325020221 0ustar janjan00000000000000nitrokey-app-1.3.2/libnitrokey/.idea/codeStyleSettings.xml0000644000175000017500000000422513221174520023212 0ustar janjan00000000000000 nitrokey-app-1.3.2/libnitrokey/.idea/dictionaries/sz.xml0000644000175000017500000000026613221174520022650 0ustar janjan00000000000000 loglevel nitrokey totp nitrokey-app-1.3.2/libnitrokey/.idea/vcs.xml0000644000175000017500000000026413275777076020360 0ustar janjan00000000000000 nitrokey-app-1.3.2/libnitrokey/.travis.yml0000644000175000017500000000302413221174520020141 0ustar janjan00000000000000language: generic sudo: false os: osx env: global: - CF="-DCOMPILE_OFFLINE_TESTS=1 -DERROR_ON_WARNING=ON" matrix: include: # - osx_image: xcode7.3 #default # before_install: &brew # - brew update # - brew install hidapi - osx_image: xcode9.1 - osx_image: xcode8.2 - os: linux dist: trusty env: COMPILER_NAME=gcc CXX=g++-5 CC=gcc-5 addons: apt: packages: - cmake - libhidapi-dev - g++-5 sources: &sources - ubuntu-toolchain-r-test - os: linux dist: trusty env: COMPILER_NAME=gcc CXX=g++-6 CC=gcc-6 addons: apt: packages: - cmake - libhidapi-dev - g++-6 sources: *sources - os: linux dist: trusty env: COMPILER_NAME=gcc CXX=g++-7 CC=gcc-7 addons: apt: packages: - cmake - libhidapi-dev - g++-7 sources: *sources - os: linux dist: trusty env: COMPILER_NAME=clang CXX=clang++-3.8 CC=clang-3.8 addons: apt: packages: - cmake - libhidapi-dev - g++-5 - clang-3.8 sources: *sources install: - mkdir -p build - cd build # - export CXXFLAGS="${CXX_FLAGS} -Wall -Wextra -Werror" # TODO enable when fixed - ${CXX} --version || true - cmake --version - cmake .. ${CF} script: - make -j2 - ctest -VV - mkdir install && make install DESTDIR=installnitrokey-app-1.3.2/libnitrokey/CHANGELOG.md0000644000175000017500000001421413232102355017643 0ustar janjan00000000000000# Change Log ## [v3.2](https://github.com/Nitrokey/libnitrokey/tree/v3.2) (2018-01-16) [Full Changelog](https://github.com/Nitrokey/libnitrokey/compare/v3.1...v3.2) **Closed issues:** - Communication exceptions are not catched in C API [\#89](https://github.com/Nitrokey/libnitrokey/issues/89) - Devices are not detected under Windows [\#88](https://github.com/Nitrokey/libnitrokey/issues/88) - Python bindings example is not working [\#82](https://github.com/Nitrokey/libnitrokey/issues/82) - Missing NK\_C\_API.h in install includes [\#77](https://github.com/Nitrokey/libnitrokey/issues/77) - Handle time-taking commands [\#67](https://github.com/Nitrokey/libnitrokey/issues/67) ## [v3.1](https://github.com/Nitrokey/libnitrokey/tree/v3.1) (2017-10-11) [Full Changelog](https://github.com/Nitrokey/libnitrokey/compare/v3.0...v3.1) ## [v3.0](https://github.com/Nitrokey/libnitrokey/tree/v3.0) (2017-10-07) [Full Changelog](https://github.com/Nitrokey/libnitrokey/compare/v2.0...v3.0) **Implemented enhancements:** - Support for NK Pro 0.8 [\#51](https://github.com/Nitrokey/libnitrokey/issues/51) **Closed issues:** - tests are failing [\#71](https://github.com/Nitrokey/libnitrokey/issues/71) - cmake doesn't install any headers [\#70](https://github.com/Nitrokey/libnitrokey/issues/70) - SONAME versioning [\#69](https://github.com/Nitrokey/libnitrokey/issues/69) - Read slot returns invalid counter value for Storage [\#59](https://github.com/Nitrokey/libnitrokey/issues/59) - Return OTP codes as strings [\#57](https://github.com/Nitrokey/libnitrokey/issues/57) - Fix compilation warnings [\#56](https://github.com/Nitrokey/libnitrokey/issues/56) - Add Travis support [\#48](https://github.com/Nitrokey/libnitrokey/issues/48) - Correct get\_time [\#27](https://github.com/Nitrokey/libnitrokey/issues/27) - Move from Makefile to CMake [\#18](https://github.com/Nitrokey/libnitrokey/issues/18) ## [v2.0](https://github.com/Nitrokey/libnitrokey/tree/v2.0) (2016-12-12) [Full Changelog](https://github.com/Nitrokey/libnitrokey/compare/v1.0...v2.0) **Implemented enhancements:** - Support for Nitrokey Storage - Nitrokey Storage commands [\#14](https://github.com/Nitrokey/libnitrokey/issues/14) - Support for Nitrokey Storage - Nitrokey Pro commands [\#13](https://github.com/Nitrokey/libnitrokey/issues/13) **Fixed bugs:** - Fails to compile on ubuntu 16.04 [\#46](https://github.com/Nitrokey/libnitrokey/issues/46) - C++ tests do not compile [\#45](https://github.com/Nitrokey/libnitrokey/issues/45) - HOTP counter values limited to 8bit [\#44](https://github.com/Nitrokey/libnitrokey/issues/44) - Device is not released after library function disconnect call [\#43](https://github.com/Nitrokey/libnitrokey/issues/43) **Closed issues:** - Compilation error on G++6 \(flexible array member\) [\#49](https://github.com/Nitrokey/libnitrokey/issues/49) - No library function for getting device's serial number [\#33](https://github.com/Nitrokey/libnitrokey/issues/33) - Pass binary data \(OTP secrets\) coded as hex values [\#31](https://github.com/Nitrokey/libnitrokey/issues/31) - set\_time not always work [\#29](https://github.com/Nitrokey/libnitrokey/issues/29) **Merged pull requests:** - Support for Nitrokey Pro 0.8 [\#53](https://github.com/Nitrokey/libnitrokey/pull/53) ([szszszsz](https://github.com/szszszsz)) - Support Nitrokey Storage [\#52](https://github.com/Nitrokey/libnitrokey/pull/52) ([szszszsz](https://github.com/szszszsz)) - Fix compilation G++6 error [\#50](https://github.com/Nitrokey/libnitrokey/pull/50) ([szszszsz](https://github.com/szszszsz)) - Fix compilation warning and error under G++ [\#47](https://github.com/Nitrokey/libnitrokey/pull/47) ([szszszsz](https://github.com/szszszsz)) - Support Pro stick commands on Storage device [\#42](https://github.com/Nitrokey/libnitrokey/pull/42) ([szszszsz](https://github.com/szszszsz)) - Readme update - dependencies, compilers, format [\#40](https://github.com/Nitrokey/libnitrokey/pull/40) ([szszszsz](https://github.com/szszszsz)) - Issue 31 secret as hex [\#36](https://github.com/Nitrokey/libnitrokey/pull/36) ([szszszsz](https://github.com/szszszsz)) - Function for getting device's serial number in hex. Fixes \#33 [\#34](https://github.com/Nitrokey/libnitrokey/pull/34) ([szszszsz](https://github.com/szszszsz)) ## [v1.0](https://github.com/Nitrokey/libnitrokey/tree/v1.0) (2016-08-09) [Full Changelog](https://github.com/Nitrokey/libnitrokey/compare/v0.9...v1.0) **Closed issues:** - Automatically detect any connected stick [\#22](https://github.com/Nitrokey/libnitrokey/issues/22) - Security check [\#20](https://github.com/Nitrokey/libnitrokey/issues/20) - Show friendly message when no device is connected and do not abort [\#17](https://github.com/Nitrokey/libnitrokey/issues/17) - Fix PIN protected OTP for Pro [\#15](https://github.com/Nitrokey/libnitrokey/issues/15) ## [v0.9](https://github.com/Nitrokey/libnitrokey/tree/v0.9) (2016-08-05) [Full Changelog](https://github.com/Nitrokey/libnitrokey/compare/v0.8...v0.9) **Closed issues:** - Add README [\#6](https://github.com/Nitrokey/libnitrokey/issues/6) - Support configs for OTP slots [\#19](https://github.com/Nitrokey/libnitrokey/issues/19) - Cover remaining Nitrokey Pro commands in lib and tests [\#16](https://github.com/Nitrokey/libnitrokey/issues/16) **Merged pull requests:** - waffle.io Badge [\#21](https://github.com/Nitrokey/libnitrokey/pull/21) ([waffle-iron](https://github.com/waffle-iron)) ## [v0.8](https://github.com/Nitrokey/libnitrokey/tree/v0.8) (2016-08-02) **Implemented enhancements:** - Change license to LGPLv3 [\#1](https://github.com/Nitrokey/libnitrokey/issues/1) **Closed issues:** - Python wrapper for OTP and PINs [\#12](https://github.com/Nitrokey/libnitrokey/issues/12) - Fails to built with default setting on ubuntu 14.04 [\#11](https://github.com/Nitrokey/libnitrokey/issues/11) - Check why packet buffers are not zeroed [\#8](https://github.com/Nitrokey/libnitrokey/issues/8) **Merged pull requests:** - Reset the HOTP counter [\#9](https://github.com/Nitrokey/libnitrokey/pull/9) ([cornelinux](https://github.com/cornelinux)) \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*nitrokey-app-1.3.2/libnitrokey/CMakeLists.txt0000644000175000017500000001622413275777076020626 0ustar janjan00000000000000# https://cmake.org/pipermail/cmake/2011-May/044166.html IF(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS) SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON) ENDIF() cmake_minimum_required(VERSION 3.1) IF (UNIX) OPTION(ADD_ASAN "Use ASAN to show memory issues" FALSE) OPTION(ADD_TSAN "Use TSAN to show thread issues" FALSE) IF(ADD_ASAN) SET(EXTRA_LIBS ${EXTRA_LIBS} asan ) ADD_COMPILE_OPTIONS(-fsanitize=address -fno-omit-frame-pointer) ENDIF() IF(ADD_TSAN) SET(EXTRA_LIBS ${EXTRA_LIBS} tsan ) SET(USE_CLANG TRUE) ADD_COMPILE_OPTIONS(-fsanitize=thread -fno-omit-frame-pointer -fPIC -g) #use with clang ENDIF() IF(ADD_TSAN AND ADD_ASAN) message(FATAL_ERROR "TSAN and ASAN cannot be used at the same time") ENDIF() ENDIF() project(libnitrokey LANGUAGES C CXX VERSION 3.3.0) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) include(GNUInstallDirs) IF (NOT CMAKE_BUILD_TYPE) IF(APPLE) # Issues occur when build with enabled optimizations set(CMAKE_BUILD_TYPE Debug) ELSE() set(CMAKE_BUILD_TYPE RelWithDebInfo) ENDIF() ENDIF() MESSAGE("${PROJECT_NAME}: Build type: ${CMAKE_BUILD_TYPE}") include_directories(hidapi) include_directories(libnitrokey) set(SOURCE_FILES libnitrokey/command.h libnitrokey/command_id.h libnitrokey/cxx_semantics.h libnitrokey/device.h libnitrokey/device_proto.h libnitrokey/dissect.h libnitrokey/log.h libnitrokey/misc.h libnitrokey/NitrokeyManager.h libnitrokey/stick10_commands.h libnitrokey/stick20_commands.h libnitrokey/CommandFailedException.h libnitrokey/LibraryException.h libnitrokey/LongOperationInProgressException.h libnitrokey/stick10_commands_0.8.h command_id.cc device.cc log.cc misc.cc NitrokeyManager.cc NK_C_API.h NK_C_API.cc DeviceCommunicationExceptions.cpp) set(BUILD_SHARED_LIBS ON CACHE BOOL "Build all libraries as shared") add_library(nitrokey ${SOURCE_FILES}) IF(APPLE) include_directories(hidapi/hidapi) add_library(hidapi-libusb STATIC hidapi/mac/hid.c ) target_link_libraries(hidapi-libusb "-framework CoreFoundation" "-framework IOKit") target_link_libraries(nitrokey hidapi-libusb) ELSEIF(UNIX) # add_library(hidapi-libusb STATIC hidapi/libusb/hid.c ) find_package(PkgConfig) pkg_search_module(HIDAPI_LIBUSB REQUIRED hidapi-libusb) target_compile_options(nitrokey PRIVATE ${HIDAPI_LIBUSB_CFLAGS}) target_link_libraries(nitrokey ${HIDAPI_LIBUSB_LDFLAGS}) ELSEIF(WIN32) include_directories(hidapi/hidapi) add_library(hidapi-libusb STATIC hidapi/windows/hid.c ) target_link_libraries(hidapi-libusb setupapi) target_link_libraries(nitrokey hidapi-libusb) ENDIF() set_target_properties(nitrokey PROPERTIES VERSION ${libnitrokey_VERSION} SOVERSION ${libnitrokey_VERSION_MAJOR}) OPTION(ERROR_ON_WARNING "Stop compilation on warning found (not supported for MSVC)" OFF) if (NOT MSVC) set(COMPILE_FLAGS "-Wall -Wno-unused-function -Wcast-qual -Woverloaded-virtual") IF(NOT APPLE) if (ERROR_ON_WARNING) set(COMPILE_FLAGS "${COMPILE_FLAGS} -Werror") endif() ENDIF() SET_TARGET_PROPERTIES(nitrokey PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS} ) endif() OPTION(NO_LOG "Compile without logging functionality and its strings (decreases size)" OFF) IF (NO_LOG) SET_TARGET_PROPERTIES(nitrokey PROPERTIES COMPILE_DEFINITIONS "NO_LOG") ENDIF() OPTION(LOG_VOLATILE_DATA "Log volatile data (debug)" OFF) IF (LOG_VOLATILE_DATA) SET_TARGET_PROPERTIES(nitrokey PROPERTIES COMPILE_DEFINITIONS "LOG_VOLATILE_DATA") ENDIF() file(GLOB LIB_INCLUDES "libnitrokey/*.h" "NK_C_API.h") install (FILES ${LIB_INCLUDES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) install (TARGETS nitrokey DESTINATION ${CMAKE_INSTALL_LIBDIR}) IF(NOT WIN32) # Install Nitrokey udev rules IF(NOT DEFINED CMAKE_INSTALL_UDEVRULESDIR) set(PKG_GET_UDEV_DIR ${PKG_CONFIG_EXECUTABLE} --variable=udevdir udev) execute_process(COMMAND ${PKG_GET_UDEV_DIR} RESULT_VARIABLE ERR OUTPUT_VARIABLE CMAKE_INSTALL_UDEVRULESDIR OUTPUT_STRIP_TRAILING_WHITESPACE) IF(${ERR}) set(CMAKE_INSTALL_UDEVRULESDIR "lib/udev/rules.d") ELSE() set(CMAKE_INSTALL_UDEVRULESDIR "${CMAKE_INSTALL_UDEVRULESDIR}/rules.d") ENDIF() string(REGEX REPLACE "^/" "" CMAKE_INSTALL_UDEVRULESDIR "${CMAKE_INSTALL_UDEVRULESDIR}") string(REGEX REPLACE "^usr/" "" CMAKE_INSTALL_UDEVRULESDIR "${CMAKE_INSTALL_UDEVRULESDIR}") # usual prefix is usr/local message(STATUS "Setting udev rules dir to ${CMAKE_INSTALL_UDEVRULESDIR}") ENDIF() install(FILES ${CMAKE_SOURCE_DIR}/data/41-nitrokey.rules DESTINATION ${CMAKE_INSTALL_UDEVRULESDIR} ) ENDIF() # configure and install pkg-config file configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libnitrokey.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libnitrokey-1.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnitrokey-1.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) OPTION(COMPILE_TESTS "Compile tests" FALSE) OPTION(COMPILE_OFFLINE_TESTS "Compile offline tests" FALSE) IF(COMPILE_OFFLINE_TESTS OR COMPILE_TESTS) find_package(PkgConfig) IF(PKG_CONFIG_FOUND) pkg_check_modules(CATCH2 catch) ENDIF() if (CATCH2_FOUND) message(STATUS "Found system Catch2, not using bundled version") add_compile_options(${CATCH2_CFLAGS}) ELSE() message(STATUS "Did NOT find system Catch2, instead using bundled version") include_directories(unittest/Catch/single_include) ENDIF() add_library(catch STATIC unittest/catch_main.cpp ) ENDIF() IF(COMPILE_OFFLINE_TESTS) add_executable (test_offline unittest/test_offline.cc) target_link_libraries (test_offline ${EXTRA_LIBS} nitrokey catch) #run with 'make test' or 'ctest' include (CTest) add_test (runs test_offline) ENDIF() IF (COMPILE_TESTS) #needs connected PRO device for success #warning: it may delete data on the device add_executable (test_C_API unittest/test_C_API.cpp) target_link_libraries (test_C_API ${EXTRA_LIBS} nitrokey catch) add_executable (test2 unittest/test2.cc) target_link_libraries (test2 ${EXTRA_LIBS} nitrokey catch) add_executable (test3 unittest/test3.cc) target_link_libraries (test3 ${EXTRA_LIBS} nitrokey catch) add_executable (test_HOTP unittest/test_HOTP.cc) target_link_libraries (test_HOTP ${EXTRA_LIBS} nitrokey catch) add_executable (test1 unittest/test.cc) target_link_libraries (test1 ${EXTRA_LIBS} nitrokey catch) add_executable (test_issues unittest/test_issues.cc) target_link_libraries (test_issues ${EXTRA_LIBS} nitrokey catch) add_executable (test_multiple_devices unittest/test_multiple_devices.cc) target_link_libraries (test_multiple_devices ${EXTRA_LIBS} nitrokey catch) ENDIF() #SET(CPACK_GENERATOR # "DEB;RPM") # build a CPack driven installer package include (InstallRequiredSystemLibraries) set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set (CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") include (CPack) nitrokey-app-1.3.2/libnitrokey/CMakeSettings.json0000644000175000017500000000252213221174520021426 0ustar janjan00000000000000{ // See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file. "configurations": [ { "name": "x86-Debug", "generator": "Visual Studio 15 2017", "configurationType" : "Debug", "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-m -v:minimal" }, { "name": "x86-Release", "generator": "Visual Studio 15 2017", "configurationType" : "Release", "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-m -v:minimal" }, { "name": "x64-Debug", "generator": "Visual Studio 15 2017 Win64", "configurationType" : "Debug", "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-m -v:minimal" }, { "name": "x64-Release", "generator": "Visual Studio 15 2017 Win64", "configurationType" : "Release", "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}", "cmakeCommandArgs": "", "buildCommandArgs": "-m -v:minimal" } ] }nitrokey-app-1.3.2/libnitrokey/DeviceCommunicationExceptions.cpp0000644000175000017500000000155013232102355024524 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include "DeviceCommunicationExceptions.h" std::atomic_int DeviceCommunicationException::occurred {0}; nitrokey-app-1.3.2/libnitrokey/LICENSE0000644000175000017500000001674413221174520017052 0ustar janjan00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. nitrokey-app-1.3.2/libnitrokey/NK_C_API.cc0000644000175000017500000004600513275777076017640 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include "NK_C_API.h" #include #include "libnitrokey/NitrokeyManager.h" #include #include "libnitrokey/LibraryException.h" #include "libnitrokey/cxx_semantics.h" #ifdef _MSC_VER #ifdef _WIN32 #pragma message "Using own strndup" char * strndup(const char* str, size_t maxlen) { size_t len = strnlen(str, maxlen); char* dup = (char *)malloc(len + 1); memcpy(dup, str, len); dup[len] = 0; return dup; } #endif #endif using namespace nitrokey; static uint8_t NK_last_command_status = 0; static const int max_string_field_length = 100; template T* duplicate_vector_and_clear(std::vector &v){ auto d = new T[v.size()]; std::copy(v.begin(), v.end(), d); std::fill(v.begin(), v.end(), 0); return d; } template uint8_t * get_with_array_result(T func){ NK_last_command_status = 0; try { return func(); } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } catch (LibraryException & libraryException){ NK_last_command_status = libraryException.exception_id(); } catch (const DeviceCommunicationException &deviceException){ NK_last_command_status = 256-deviceException.getType(); } return nullptr; } template const char* get_with_string_result(T func){ NK_last_command_status = 0; try { return func(); } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } catch (LibraryException & libraryException){ NK_last_command_status = libraryException.exception_id(); } catch (const DeviceCommunicationException &deviceException){ NK_last_command_status = 256-deviceException.getType(); } return ""; } template auto get_with_result(T func){ NK_last_command_status = 0; try { return func(); } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } catch (LibraryException & libraryException){ NK_last_command_status = libraryException.exception_id(); } catch (const DeviceCommunicationException &deviceException){ NK_last_command_status = 256-deviceException.getType(); } return static_cast(0); } template uint8_t get_without_result(T func){ NK_last_command_status = 0; try { func(); return 0; } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; } catch (LibraryException & libraryException){ NK_last_command_status = libraryException.exception_id(); } catch (const InvalidCRCReceived &invalidCRCException){ ; } catch (const DeviceCommunicationException &deviceException){ NK_last_command_status = 256-deviceException.getType(); } return NK_last_command_status; } #ifdef __cplusplus extern "C" { #endif NK_C_API uint8_t NK_get_last_command_status() { auto _copy = NK_last_command_status; NK_last_command_status = 0; return _copy; } NK_C_API int NK_login(const char *device_model) { auto m = NitrokeyManager::instance(); try { NK_last_command_status = 0; return m->connect(device_model); } catch (CommandFailedException & commandFailedException) { NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } catch (const DeviceCommunicationException &deviceException){ NK_last_command_status = 256-deviceException.getType(); cerr << deviceException.what() << endl; return 0; } catch (std::runtime_error &e) { cerr << e.what() << endl; return 0; } return 0; } NK_C_API int NK_login_enum(NK_device_model device_model) { const char *model_string; switch (device_model) { case NK_PRO: model_string = "P"; break; case NK_STORAGE: model_string = "S"; break; default: /* no such enum value -- return error code */ return 0; } return NK_login(model_string); } NK_C_API int NK_logout() { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->disconnect(); }); } NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { return m->first_authenticate(admin_password, admin_temporary_password); }); } NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->user_authenticate(user_password, user_temporary_password); }); } NK_C_API int NK_factory_reset(const char* admin_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->factory_reset(admin_password); }); } NK_C_API int NK_build_aes_key(const char* admin_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->build_aes_key(admin_password); }); } NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->unlock_user_password(admin_password, new_user_password); }); } NK_C_API int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { return m->write_config(numlock, capslock, scrolllock, enable_user_password, delete_user_password, admin_temporary_password); }); } NK_C_API uint8_t* NK_read_config() { auto m = NitrokeyManager::instance(); return get_with_array_result([&]() { auto v = m->read_config(); return duplicate_vector_and_clear(v); }); } void clear_string(std::string &s) { std::fill(s.begin(), s.end(), ' '); } NK_C_API const char * NK_status() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_status_as_string(); char * rs = strndup(s.c_str(), max_string_field_length); clear_string(s); return rs; }); } NK_C_API const char * NK_device_serial_number() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_serial_number(); char * rs = strndup(s.c_str(), max_string_field_length); clear_string(s); return rs; }); } NK_C_API const char * NK_get_hotp_code(uint8_t slot_number) { return NK_get_hotp_code_PIN(slot_number, ""); } NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_HOTP_code(slot_number, user_temporary_password); char * rs = strndup(s.c_str(), max_string_field_length); clear_string(s); return rs; }); } NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval) { return NK_get_totp_code_PIN(slot_number, challenge, last_totp_time, last_interval, ""); } NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_TOTP_code(slot_number, challenge, last_totp_time, last_interval, user_temporary_password); char * rs = strndup(s.c_str(), max_string_field_length); clear_string(s); return rs; }); } NK_C_API int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&] { m->erase_hotp_slot(slot_number, temporary_password); }); } NK_C_API int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&] { m->erase_totp_slot(slot_number, temporary_password); }); } NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&] { m->write_HOTP_slot(slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); }); } NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result([&] { m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); }); } NK_C_API const char* NK_get_totp_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { const auto slot_name = m->get_totp_slot_name(slot_number); return slot_name; }); } NK_C_API const char* NK_get_hotp_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { const auto slot_name = m->get_hotp_slot_name(slot_number); return slot_name; }); } NK_C_API void NK_set_debug(bool state) { auto m = NitrokeyManager::instance(); m->set_debug(state); } NK_C_API void NK_set_debug_level(const int level) { auto m = NitrokeyManager::instance(); m->set_loglevel(level); } NK_C_API int NK_totp_set_time(uint64_t time) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_time(time); }); } NK_C_API int NK_totp_get_time() { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->get_time(0); // FIXME check how that should work }); } NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->change_admin_PIN(current_PIN, new_PIN); }); } NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->change_user_PIN(current_PIN, new_PIN); }); } NK_C_API int NK_enable_password_safe(const char *user_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->enable_password_safe(user_pin); }); } NK_C_API uint8_t * NK_get_password_safe_slot_status() { auto m = NitrokeyManager::instance(); return get_with_array_result([&]() { auto slot_status = m->get_password_safe_slot_status(); return duplicate_vector_and_clear(slot_status); }); } NK_C_API uint8_t NK_get_user_retry_count() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->get_user_retry_count(); }); } NK_C_API uint8_t NK_get_admin_retry_count() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->get_admin_retry_count(); }); } NK_C_API int NK_lock_device() { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->lock_device(); }); } NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_password_safe_slot_name(slot_number); }); } NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_password_safe_slot_login(slot_number); }); } NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_password_safe_slot_password(slot_number); }); } NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, const char *slot_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->write_password_safe_slot(slot_number, slot_name, slot_login, slot_password); }); } NK_C_API int NK_erase_password_safe_slot(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->erase_password_safe_slot(slot_number); }); } NK_C_API int NK_is_AES_supported(const char *user_password) { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return (uint8_t)m->is_AES_supported(user_password); }); } NK_C_API int NK_login_auto() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return (uint8_t)m->connect(); }); } // storage commands NK_C_API int NK_send_startup(uint64_t seconds_from_epoch) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->send_startup(seconds_from_epoch); }); } NK_C_API int NK_unlock_encrypted_volume(const char* user_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->unlock_encrypted_volume(user_pin); }); } NK_C_API int NK_lock_encrypted_volume() { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->lock_encrypted_volume(); }); } NK_C_API int NK_unlock_hidden_volume(const char* hidden_volume_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->unlock_hidden_volume(hidden_volume_password); }); } NK_C_API int NK_lock_hidden_volume() { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->lock_hidden_volume(); }); } NK_C_API int NK_create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, const char *hidden_volume_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->create_hidden_volume(slot_nr, start_percent, end_percent, hidden_volume_password); }); } NK_C_API int NK_set_unencrypted_read_only(const char *user_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_unencrypted_read_only(user_pin); }); } NK_C_API int NK_set_unencrypted_read_write(const char *user_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_unencrypted_read_write(user_pin); }); } NK_C_API int NK_set_unencrypted_read_only_admin(const char *admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_unencrypted_read_only_admin(admin_pin); }); } NK_C_API int NK_set_unencrypted_read_write_admin(const char *admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_unencrypted_read_write_admin(admin_pin); }); } NK_C_API int NK_set_encrypted_read_only(const char* admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_encrypted_volume_read_only(admin_pin); }); } NK_C_API int NK_set_encrypted_read_write(const char* admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_encrypted_volume_read_write(admin_pin); }); } NK_C_API int NK_export_firmware(const char* admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->export_firmware(admin_pin); }); } NK_C_API int NK_clear_new_sd_card_warning(const char* admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->clear_new_sd_card_warning(admin_pin); }); } NK_C_API int NK_fill_SD_card_with_random_data(const char* admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->fill_SD_card_with_random_data(admin_pin); }); } NK_C_API int NK_change_update_password(const char* current_update_password, const char* new_update_password) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->change_update_password(current_update_password, new_update_password); }); } NK_C_API int NK_enable_firmware_update(const char* update_password){ auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->enable_firmware_update(update_password); }); } NK_C_API const char* NK_get_status_storage_as_string() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_status_storage_as_string(); }); } NK_C_API const char* NK_get_SD_usage_data_as_string() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_SD_usage_data_as_string(); }); } NK_C_API int NK_get_progress_bar_value() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->get_progress_bar_value(); }); } NK_C_API int NK_get_major_firmware_version() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->get_major_firmware_version(); }); } NK_C_API int NK_get_minor_firmware_version() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->get_minor_firmware_version(); }); } NK_C_API int NK_set_unencrypted_volume_rorw_pin_type_user() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->set_unencrypted_volume_rorw_pin_type_user() ? 1 : 0; }); } NK_C_API const char* NK_list_devices_by_cpuID() { auto nm = NitrokeyManager::instance(); return get_with_string_result([&]() { auto v = nm->list_devices_by_cpuID(); std::string res; for (const auto a : v){ res += a+";"; } if (res.size()>0) res.pop_back(); // remove last delimiter char return strndup(res.c_str(), 8192); //this buffer size sets limit to over 200 devices ID's }); } NK_C_API int NK_connect_with_ID(const char* id) { auto m = NitrokeyManager::instance(); return get_with_result([&]() { return m->connect_with_ID(id) ? 1 : 0; }); } #ifdef __cplusplus } #endif nitrokey-app-1.3.2/libnitrokey/NK_C_API.h0000644000175000017500000005322013275777076017477 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_NK_C_API_H #define LIBNITROKEY_NK_C_API_H #include #include #ifdef _MSC_VER #define NK_C_API __declspec(dllexport) #else #define NK_C_API #endif #ifdef __cplusplus extern "C" { #endif /** * The Nitrokey device models supported by the API. */ enum NK_device_model { /** * Nitrokey Pro. */ NK_PRO, /** * Nitrokey Storage. */ NK_STORAGE }; /** * Set debug level of messages written on stderr * @param state state=True - most messages, state=False - only errors level */ NK_C_API void NK_set_debug(bool state); /** * Set debug level of messages written on stderr * @param level (int) 0-lowest verbosity, 5-highest verbosity */ NK_C_API void NK_set_debug_level(const int level); /** * Connect to device of given model. Currently library can be connected only to one device at once. * @param device_model char 'S': Nitrokey Storage, 'P': Nitrokey Pro * @return 1 if connected, 0 if wrong model or cannot connect */ NK_C_API int NK_login(const char *device_model); /** * Connect to device of given model. Currently library can be connected only to one device at once. * @param device_model NK_device_model: NK_PRO: Nitrokey Pro, NK_STORAGE: Nitrokey Storage * @return 1 if connected, 0 if wrong model or cannot connect */ NK_C_API int NK_login_enum(enum NK_device_model device_model); /** * Connect to first available device, starting checking from Pro 1st to Storage 2nd. * @return 1 if connected, 0 if wrong model or cannot connect */ NK_C_API int NK_login_auto(); /** * Disconnect from the device. * @return command processing error code */ NK_C_API int NK_logout(); /** * Return the debug status string. Debug purposes. * @return command processing error code */ NK_C_API const char * NK_status(); /** * Return the device's serial number string in hex. * @return string device's serial number in hex */ NK_C_API const char * NK_device_serial_number(); /** * Get last command processing status. Useful for commands which returns the results of their own and could not return * an error code. * @return previous command processing error code */ NK_C_API uint8_t NK_get_last_command_status(); /** * Lock device - cancel any user device unlocking. * @return command processing error code */ NK_C_API int NK_lock_device(); /** * Authenticates the user on USER privilages with user_password and sets user's temporary password on device to user_temporary_password. * @param user_password char[25](Pro) current user password * @param user_temporary_password char[25](Pro) user temporary password to be set on device for further communication (authentication command) * @return command processing error code */ NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password); /** * Authenticates the user on ADMIN privilages with admin_password and sets user's temporary password on device to admin_temporary_password. * @param admin_password char[25](Pro) current administrator PIN * @param admin_temporary_password char[25](Pro) admin temporary password to be set on device for further communication (authentication command) * @return command processing error code */ NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password); /** * Execute a factory reset. * @param admin_password char[20](Pro) current administrator PIN * @return command processing error code */ NK_C_API int NK_factory_reset(const char* admin_password); /** * Generates AES key on the device * @param admin_password char[20](Pro) current administrator PIN * @return command processing error code */ NK_C_API int NK_build_aes_key(const char* admin_password); /** * Unlock user PIN locked after 3 incorrect codes tries. * @param admin_password char[20](Pro) current administrator PIN * @return command processing error code */ NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password); /** * Write general config to the device * @param numlock set value in range [0-1] to send HOTP code from slot 'numlock' after double pressing numlock * or outside the range to disable this function * @param capslock similar to numlock but with capslock * @param scrolllock similar to numlock but with scrolllock * @param enable_user_password set True to enable OTP PIN protection (require PIN each OTP code request) * @param delete_user_password (unused) * @param admin_temporary_password current admin temporary password * @return command processing error code */ NK_C_API int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); /** * Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and is enabled PIN protected OTP * @see NK_write_config * @return uint8_t general_config[5]: * uint8_t numlock; uint8_t capslock; uint8_t scrolllock; uint8_t enable_user_password; uint8_t delete_user_password; */ NK_C_API uint8_t* NK_read_config(); //OTP /** * Get name of given TOTP slot * @param slot_number TOTP slot number, slot_number<15 * @return char[20](Pro) the name of the slot */ NK_C_API const char * NK_get_totp_slot_name(uint8_t slot_number); /** * * @param slot_number HOTP slot number, slot_number<3 * @return char[20](Pro) the name of the slot */ NK_C_API const char * NK_get_hotp_slot_name(uint8_t slot_number); /** * Erase HOTP slot data from the device * @param slot_number HOTP slot number, slot_number<3 * @param temporary_password admin temporary password * @return command processing error code */ NK_C_API int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password); /** * Erase TOTP slot data from the device * @param slot_number TOTP slot number, slot_number<15 * @param temporary_password admin temporary password * @return command processing error code */ NK_C_API int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password); /** * Write HOTP slot data to the device * @param slot_number HOTP slot number, slot_number<3 * @param slot_name char[15](Pro) desired slot name * @param secret char[20](Pro) 160-bit secret * @param hotp_counter uint32_t starting value of HOTP counter * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock * @param use_tokenID @see token_ID * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section * @param temporary_password char[25](Pro) admin temporary password * @return command processing error code */ NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password); /** * Write TOTP slot data to the device * @param slot_number TOTP slot number, slot_number<15 * @param slot_name char[15](Pro) desired slot name * @param secret char[20](Pro) 160-bit secret * @param time_window uint16_t time window for this TOTP * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock * @param use_tokenID @see token_ID * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section * @param temporary_password char[20](Pro) admin temporary password * @return command processing error code */ NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password); /** * Get HOTP code from the device * @param slot_number HOTP slot number, slot_number<3 * @return HOTP code */ NK_C_API const char * NK_get_hotp_code(uint8_t slot_number); /** * Get HOTP code from the device (PIN protected) * @param slot_number HOTP slot number, slot_number<3 * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, * otherwise should be set to empty string - '' * @return HOTP code */ NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password); /** * Get TOTP code from the device * @param slot_number TOTP slot number, slot_number<15 * @param challenge TOTP challenge * @param last_totp_time last time * @param last_interval last interval * @return TOTP code */ NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval); /** * Get TOTP code from the device (PIN protected) * @param slot_number TOTP slot number, slot_number<15 * @param challenge TOTP challenge * @param last_totp_time last time * @param last_interval last interval * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, * otherwise should be set to empty string - '' * @return TOTP code */ NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password); /** * Set time on the device (for TOTP requests) * @param time seconds in unix epoch (from 01.01.1970) * @return command processing error code */ NK_C_API int NK_totp_set_time(uint64_t time); NK_C_API int NK_totp_get_time(); //passwords /** * Change administrator PIN * @param current_PIN char[25](Pro) current PIN * @param new_PIN char[25](Pro) new PIN * @return command processing error code */ NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN); /** * Change user PIN * @param current_PIN char[25](Pro) current PIN * @param new_PIN char[25](Pro) new PIN * @return command processing error code */ NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN); /** * Get retry count of user PIN * @return user PIN retry count */ NK_C_API uint8_t NK_get_user_retry_count(); /** * Get retry count of admin PIN * @return admin PIN retry count */ NK_C_API uint8_t NK_get_admin_retry_count(); //password safe /** * Enable password safe access * @param user_pin char[30](Pro) current user PIN * @return command processing error code */ NK_C_API int NK_enable_password_safe(const char *user_pin); /** * Get password safe slots' status * @return uint8_t[16] slot statuses - each byte represents one slot with 0 (not programmed) and 1 (programmed) */ NK_C_API uint8_t * NK_get_password_safe_slot_status(); /** * Get password safe slot name * @param slot_number password safe slot number, slot_number<16 * @return slot name */ NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number); /** * Get password safe slot login * @param slot_number password safe slot number, slot_number<16 * @return login from the PWS slot */ NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number); /** * Get the password safe slot password * @param slot_number password safe slot number, slot_number<16 * @return password from the PWS slot */ NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number); /** * Write password safe data to the slot * @param slot_number password safe slot number, slot_number<16 * @param slot_name char[11](Pro) name of the slot * @param slot_login char[32](Pro) login string * @param slot_password char[20](Pro) password string * @return command processing error code */ NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, const char *slot_password); /** * Erase the password safe slot from the device * @param slot_number password safe slot number, slot_number<16 * @return command processing error code */ NK_C_API int NK_erase_password_safe_slot(uint8_t slot_number); /** * Check whether AES is supported by the device * @return 0 for no and 1 for yes */ NK_C_API int NK_is_AES_supported(const char *user_password); /** * Get device's major firmware version * @return major part of the version number (e.g. 0 from 0.48, 0 from 0.7 etc.) */ NK_C_API int NK_get_major_firmware_version(); /** * Get device's minor firmware version * @return minor part of the version number (e.g. 7 from 0.7, 48 from 0.48 etc.) */ NK_C_API int NK_get_minor_firmware_version(); /** * Function to determine unencrypted volume PIN type * @param minor_firmware_version * @return Returns 1, if set unencrypted volume ro/rw pin type is User, 0 otherwise. */ NK_C_API int NK_set_unencrypted_volume_rorw_pin_type_user(); /** * This command is typically run to initiate * communication with the device (altough not required). * It sets time on device and returns its current status * - a combination of set_time and get_status_storage commands * Storage only * @param seconds_from_epoch date and time expressed in seconds */ NK_C_API int NK_send_startup(uint64_t seconds_from_epoch); /** * Unlock encrypted volume. * Storage only * @param user_pin user pin 20 characters * @return command processing error code */ NK_C_API int NK_unlock_encrypted_volume(const char* user_pin); /** * Locks encrypted volume * @return command processing error code */ NK_C_API int NK_lock_encrypted_volume(); /** * Unlock hidden volume and lock encrypted volume. * Requires encrypted volume to be unlocked. * Storage only * @param hidden_volume_password 20 characters * @return command processing error code */ NK_C_API int NK_unlock_hidden_volume(const char* hidden_volume_password); /** * Locks hidden volume * @return command processing error code */ NK_C_API int NK_lock_hidden_volume(); /** * Create hidden volume. * Requires encrypted volume to be unlocked. * Storage only * @param slot_nr slot number in range 0-3 * @param start_percent volume begin expressed in percent of total available storage, int in range 0-99 * @param end_percent volume end expressed in percent of total available storage, int in range 1-100 * @param hidden_volume_password 20 characters * @return command processing error code */ NK_C_API int NK_create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, const char *hidden_volume_password); /** * Make unencrypted volume read-only. * Device hides unencrypted volume for a second therefore make sure * buffers are flushed before running. * Does nothing if firmware version is not matched * Firmware range: Storage v0.50, v0.48 and below * Storage only * @param user_pin 20 characters User PIN * @return command processing error code */ NK_C_API int NK_set_unencrypted_read_only(const char *user_pin); /** * Make unencrypted volume read-write. * Device hides unencrypted volume for a second therefore make sure * buffers are flushed before running. * Does nothing if firmware version is not matched * Firmware range: Storage v0.50, v0.48 and below * Storage only * @param user_pin 20 characters User PIN * @return command processing error code */ NK_C_API int NK_set_unencrypted_read_write(const char *user_pin); /** * Make unencrypted volume read-only. * Device hides unencrypted volume for a second therefore make sure * buffers are flushed before running. * Does nothing if firmware version is not matched * Firmware range: Storage v0.49, v0.51+ * Storage only * @param admin_pin 20 characters Admin PIN * @return command processing error code */ NK_C_API int NK_set_unencrypted_read_only_admin(const char* admin_pin); /** * Make unencrypted volume read-write. * Device hides unencrypted volume for a second therefore make sure * buffers are flushed before running. * Does nothing if firmware version is not matched * Firmware range: Storage v0.49, v0.51+ * Storage only * @param admin_pin 20 characters Admin PIN * @return command processing error code */ NK_C_API int NK_set_unencrypted_read_write_admin(const char* admin_pin); /** * Make encrypted volume read-only. * Device hides encrypted volume for a second therefore make sure * buffers are flushed before running. * Firmware range: v0.49 only, future (see firmware release notes) * Storage only * @param admin_pin 20 characters * @return command processing error code */ NK_C_API int NK_set_encrypted_read_only(const char* admin_pin); /** * Make encrypted volume read-write. * Device hides encrypted volume for a second therefore make sure * buffers are flushed before running. * Firmware range: v0.49 only, future (see firmware release notes) * Storage only * @param admin_pin 20 characters * @return command processing error code */ NK_C_API int NK_set_encrypted_read_write(const char* admin_pin); /** * Exports device's firmware to unencrypted volume. * Storage only * @param admin_pin 20 characters * @return command processing error code */ NK_C_API int NK_export_firmware(const char* admin_pin); /** * Clear new SD card notification. It is set after factory reset. * Storage only * @param admin_pin 20 characters * @return command processing error code */ NK_C_API int NK_clear_new_sd_card_warning(const char* admin_pin); /** * Fill SD card with random data. * Should be done on first stick initialization after creating keys. * Storage only * @param admin_pin 20 characters * @return command processing error code */ NK_C_API int NK_fill_SD_card_with_random_data(const char* admin_pin); /** * Change update password. * Update password is used for entering update mode, where firmware * could be uploaded using dfu-programmer or other means. * Storage only * @param current_update_password 20 characters * @param new_update_password 20 characters * @return command processing error code */ NK_C_API int NK_change_update_password(const char* current_update_password, const char* new_update_password); /** * Enter update mode. Needs update password. * When device is in update mode it no longer accepts any HID commands until * firmware is launched (regardless of being updated or not). * Smartcard (through CCID interface) and its all volumes are not visible as well. * Its VID and PID are changed to factory-default (03eb:2ff1 Atmel Corp.) * to be detected by flashing software. Result of this command can be reversed * by using 'launch' command. * For dfu-programmer it would be: 'dfu-programmer at32uc3a3256s launch'. * Storage only * @param update_password 20 characters * @return command processing error code */ NK_C_API int NK_enable_firmware_update(const char* update_password); /** * Get Storage stick status as string. * Storage only * @return string with devices attributes */ NK_C_API const char* NK_get_status_storage_as_string(); /** * Get SD card usage attributes as string. * Usable during hidden volumes creation. * Storage only * @return string with SD card usage attributes */ NK_C_API const char* NK_get_SD_usage_data_as_string(); /** * Get progress value of current long operation. * Storage only * @return int in range 0-100 or -1 if device is not busy */ NK_C_API int NK_get_progress_bar_value(); /** * Returns a list of connected devices' id's, delimited by ';' character. Empty string is returned on no device found. * Each ID could consist of: * 1. SC_id:SD_id_p_path (about 40 bytes) * 2. path (about 10 bytes) * where 'path' is USB path (bus:num), 'SC_id' is smartcard ID, 'SD_id' is storage card ID and * '_p_' and ':' are field delimiters. * Case 2 (USB path only) is used, when the device cannot be asked about its status data (e.g. during a long operation, * like clearing SD card. * Internally connects to all available devices and creates a map between ids and connection objects. * Side effects: changes active device to last detected Storage device. * Storage only * @example Example of returned data: '00005d19:dacc2cb4_p_0001:0010:02;000037c7:4cf12445_p_0001:000f:02;0001:000c:02' * @return string delimited id's of connected devices */ NK_C_API const char* NK_list_devices_by_cpuID(); /** * Connects to the device with given ID. ID's list could be created with NK_list_devices_by_cpuID. * Requires calling to NK_list_devices_by_cpuID first. Connecting to arbitrary ID/USB path is not handled. * On connection requests status from device and disconnects it / removes from map on connection failure. * Storage only * @param id Target device ID (example: '00005d19:dacc2cb4_p_0001:0010:02') * @return 1 on successful connection, 0 otherwise */ NK_C_API int NK_connect_with_ID(const char* id); #ifdef __cplusplus } #endif #endif //LIBNITROKEY_NK_C_API_H nitrokey-app-1.3.2/libnitrokey/NitrokeyManager.cc0000644000175000017500000013363313275777076021500 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include #include #include "libnitrokey/NitrokeyManager.h" #include "libnitrokey/LibraryException.h" #include #include #include #include "libnitrokey/misc.h" #include #include "libnitrokey/cxx_semantics.h" #include #include std::mutex nitrokey::proto::send_receive_mtx; namespace nitrokey{ std::mutex mex_dev_com_manager; #ifndef strndup #ifdef _WIN32 #pragma message "Using own strndup" char * strndup(const char* str, size_t maxlen){ size_t len = strnlen(str, maxlen); char* dup = (char *) malloc(len + 1); memcpy(dup, str, len); dup[len] = 0; return dup; } #endif #endif using nitrokey::misc::strcpyT; template typename T::CommandPayload get_payload(){ //Create, initialize and return by value command payload typename T::CommandPayload st; bzero(&st, sizeof(st)); return st; } // package type to auth, auth type [Authorize,UserAuthorize] template void NitrokeyManager::authorize_packet(T &package, const char *admin_temporary_password, shared_ptr device){ if (!is_authorization_command_supported()){ LOG("Authorization command not supported, skipping", Loglevel::WARNING); } auto auth = get_payload(); strcpyT(auth.temporary_password, admin_temporary_password); auth.crc_to_authorize = S::CommandTransaction::getCRC(package); A::CommandTransaction::run(device, auth); } shared_ptr NitrokeyManager::_instance = nullptr; NitrokeyManager::NitrokeyManager() : device(nullptr) { set_debug(false); } NitrokeyManager::~NitrokeyManager() { std::lock_guard lock(mex_dev_com_manager); for (auto d : connected_devices){ if (d.second == nullptr) continue; d.second->disconnect(); connected_devices[d.first] = nullptr; } } bool NitrokeyManager::set_current_device_speed(int retry_delay, int send_receive_delay){ if (retry_delay < 20 || send_receive_delay < 20){ LOG("Delay set too low: " + to_string(retry_delay) +" "+ to_string(send_receive_delay), Loglevel::WARNING); return false; } std::lock_guard lock(mex_dev_com_manager); if(device == nullptr) { return false; } device->set_receiving_delay(std::chrono::duration(send_receive_delay)); device->set_retry_delay(std::chrono::duration(retry_delay)); return true; } std::vector NitrokeyManager::list_devices(){ std::lock_guard lock(mex_dev_com_manager); auto p = make_shared(); return p->enumerate(); // make static } std::vector NitrokeyManager::list_devices_by_cpuID(){ using misc::toHex; //disconnect default device disconnect(); std::lock_guard lock(mex_dev_com_manager); LOGD1("Disconnecting registered devices"); for (auto & kv : connected_devices_byID){ if (kv.second != nullptr) kv.second->disconnect(); } connected_devices_byID.clear(); LOGD1("Enumerating devices"); std::vector res; auto d = make_shared(); const auto v = d->enumerate(); LOGD1("Discovering IDs"); for (auto & p: v){ d = make_shared(); LOGD1( std::string("Found: ") + p ); d->set_path(p); try{ if (d->connect()){ device = d; std::string id; try { const auto status = get_status_storage(); const auto sc_id = toHex(status.ActiveSmartCardID_u32); const auto sd_id = toHex(status.ActiveSD_CardID_u32); id += sc_id + ":" + sd_id; id += "_p_" + p; } catch (const LongOperationInProgressException &e) { LOGD1(std::string("Long operation in progress, setting ID to: ") + p); id = p; } connected_devices_byID[id] = d; res.push_back(id); LOGD1( std::string("Found: ") + p + " => " + id); } else{ LOGD1( std::string("Could not connect to: ") + p); } } catch (const DeviceCommunicationException &e){ LOGD1( std::string("Exception encountered: ") + p); } } return res; } bool NitrokeyManager::connect_with_ID(const std::string id) { std::lock_guard lock(mex_dev_com_manager); auto position = connected_devices_byID.find(id); if (position == connected_devices_byID.end()) { LOGD1(std::string("Could not find device ")+id + ". Refresh devices list with list_devices_by_cpuID()."); return false; } auto d = connected_devices_byID[id]; device = d; current_device_id = id; //validate connection try{ get_status(); } catch (const LongOperationInProgressException &){ //ignore } catch (const DeviceCommunicationException &){ d->disconnect(); current_device_id = ""; connected_devices_byID[id] = nullptr; connected_devices_byID.erase(position); return false; } nitrokey::log::Log::setPrefix(id); LOGD1("Device successfully changed"); return true; } /** * Connects device to path. * Assumes devices are not being disconnected and caches connections (param cache_connections). * @param path os-dependent device path * @return false, when could not connect, true otherwise */ bool NitrokeyManager::connect_with_path(std::string path) { const bool cache_connections = false; std::lock_guard lock(mex_dev_com_manager); if (cache_connections){ if(connected_devices.find(path) != connected_devices.end() && connected_devices[path] != nullptr) { device = connected_devices[path]; return true; } } auto p = make_shared(); p->set_path(path); if(!p->connect()) return false; if(cache_connections){ connected_devices [path] = p; } device = p; //previous device will be disconnected automatically current_device_id = path; nitrokey::log::Log::setPrefix(path); LOGD1("Device successfully changed"); return true; } bool NitrokeyManager::connect() { std::lock_guard lock(mex_dev_com_manager); vector< shared_ptr > devices = { make_shared(), make_shared() }; for( auto & d : devices ){ if (d->connect()){ device = std::shared_ptr(d); } } return device != nullptr; } void NitrokeyManager::set_log_function(std::function log_function){ static nitrokey::log::FunctionalLogHandler handler(log_function); nitrokey::log::Log::instance().set_handler(&handler); } bool NitrokeyManager::set_default_commands_delay(int delay){ if (delay < 20){ LOG("Delay set too low: " + to_string(delay), Loglevel::WARNING); return false; } Device::set_default_device_speed(delay); return true; } bool NitrokeyManager::connect(const char *device_model) { std::lock_guard lock(mex_dev_com_manager); LOG(__FUNCTION__, nitrokey::log::Loglevel::DEBUG_L2); switch (device_model[0]){ case 'P': device = make_shared(); break; case 'S': device = make_shared(); break; default: throw std::runtime_error("Unknown model"); } return device->connect(); } bool NitrokeyManager::connect(device::DeviceModel device_model) { const char *model_string; switch (device_model) { case device::DeviceModel::PRO: model_string = "P"; break; case device::DeviceModel::STORAGE: model_string = "S"; break; default: throw std::runtime_error("Unknown model"); } return connect(model_string); } shared_ptr NitrokeyManager::instance() { static std::mutex mutex; std::lock_guard lock(mutex); if (_instance == nullptr){ _instance = make_shared(); } return _instance; } bool NitrokeyManager::disconnect() { std::lock_guard lock(mex_dev_com_manager); return _disconnect_no_lock(); } bool NitrokeyManager::_disconnect_no_lock() { //do not use directly without locked mutex, //used by could_be_enumerated, disconnect if (device == nullptr){ return false; } const auto res = device->disconnect(); device = nullptr; return res; } bool NitrokeyManager::is_connected() throw(){ std::lock_guard lock(mex_dev_com_manager); if(device != nullptr){ auto connected = device->could_be_enumerated(); if(connected){ return true; } else { _disconnect_no_lock(); return false; } } return false; } bool NitrokeyManager::could_current_device_be_enumerated() { std::lock_guard lock(mex_dev_com_manager); if (device != nullptr) { return device->could_be_enumerated(); } return false; } void NitrokeyManager::set_loglevel(int loglevel) { loglevel = max(loglevel, static_cast(Loglevel::ERROR)); loglevel = min(loglevel, static_cast(Loglevel::DEBUG_L2)); Log::instance().set_loglevel(static_cast(loglevel)); } void NitrokeyManager::set_loglevel(Loglevel loglevel) { Log::instance().set_loglevel(loglevel); } void NitrokeyManager::set_debug(bool state) { if (state){ Log::instance().set_loglevel(Loglevel::DEBUG); } else { Log::instance().set_loglevel(Loglevel::ERROR); } } string NitrokeyManager::get_serial_number() { if (device == nullptr) { return ""; }; switch (device->get_device_model()) { case DeviceModel::PRO: { auto response = GetStatus::CommandTransaction::run(device); return nitrokey::misc::toHex(response.data().card_serial_u32); } break; case DeviceModel::STORAGE: { auto response = stick20::GetDeviceStatus::CommandTransaction::run(device); return nitrokey::misc::toHex(response.data().ActiveSmartCardID_u32); } break; } return "NA"; } stick10::GetStatus::ResponsePayload NitrokeyManager::get_status(){ try{ auto response = GetStatus::CommandTransaction::run(device); return response.data(); } catch (DeviceSendingFailure &e){ // disconnect(); throw; } } string NitrokeyManager::get_status_as_string() { auto response = GetStatus::CommandTransaction::run(device); return response.data().dissect(); } string getFilledOTPCode(uint32_t code, bool use_8_digits){ stringstream s; s << std::right << std::setw(use_8_digits ? 8 : 6) << std::setfill('0') << code; return s.str(); } string NitrokeyManager::get_HOTP_code(uint8_t slot_number, const char *user_temporary_password) { if (!is_valid_hotp_slot_number(slot_number)) throw InvalidSlotException(slot_number); if (is_authorization_command_supported()){ auto gh = get_payload(); gh.slot_number = get_internal_slot_number_for_hotp(slot_number); if(user_temporary_password != nullptr && strlen(user_temporary_password)!=0){ //FIXME use string instead of strlen authorize_packet(gh, user_temporary_password, device); } auto resp = GetHOTP::CommandTransaction::run(device, gh); return getFilledOTPCode(resp.data().code, resp.data().use_8_digits); } else { auto gh = get_payload(); gh.slot_number = get_internal_slot_number_for_hotp(slot_number); if(user_temporary_password != nullptr && strlen(user_temporary_password)!=0) { strcpyT(gh.temporary_user_password, user_temporary_password); } auto resp = stick10_08::GetHOTP::CommandTransaction::run(device, gh); return getFilledOTPCode(resp.data().code, resp.data().use_8_digits); } return ""; } bool NitrokeyManager::is_valid_hotp_slot_number(uint8_t slot_number) const { return slot_number < 3; } bool NitrokeyManager::is_valid_totp_slot_number(uint8_t slot_number) const { return slot_number < 0x10-1; } //15 uint8_t NitrokeyManager::get_internal_slot_number_for_totp(uint8_t slot_number) const { return (uint8_t) (0x20 + slot_number); } uint8_t NitrokeyManager::get_internal_slot_number_for_hotp(uint8_t slot_number) const { return (uint8_t) (0x10 + slot_number); } string NitrokeyManager::get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password) { if(!is_valid_totp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_totp(slot_number); if (is_authorization_command_supported()){ auto gt = get_payload(); gt.slot_number = slot_number; gt.challenge = challenge; gt.last_interval = last_interval; gt.last_totp_time = last_totp_time; if(user_temporary_password != nullptr && strlen(user_temporary_password)!=0){ //FIXME use string instead of strlen authorize_packet(gt, user_temporary_password, device); } auto resp = GetTOTP::CommandTransaction::run(device, gt); return getFilledOTPCode(resp.data().code, resp.data().use_8_digits); } else { auto gt = get_payload(); strcpyT(gt.temporary_user_password, user_temporary_password); gt.slot_number = slot_number; auto resp = stick10_08::GetTOTP::CommandTransaction::run(device, gt); return getFilledOTPCode(resp.data().code, resp.data().use_8_digits); } return ""; } bool NitrokeyManager::erase_slot(uint8_t slot_number, const char *temporary_password) { if (is_authorization_command_supported()){ auto p = get_payload(); p.slot_number = slot_number; authorize_packet(p, temporary_password, device); auto resp = EraseSlot::CommandTransaction::run(device,p); } else { auto p = get_payload(); p.slot_number = slot_number; strcpyT(p.temporary_admin_password, temporary_password); auto resp = stick10_08::EraseSlot::CommandTransaction::run(device,p); } return true; } bool NitrokeyManager::erase_hotp_slot(uint8_t slot_number, const char *temporary_password) { if (!is_valid_hotp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_hotp(slot_number); return erase_slot(slot_number, temporary_password); } bool NitrokeyManager::erase_totp_slot(uint8_t slot_number, const char *temporary_password) { if (!is_valid_totp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_totp(slot_number); return erase_slot(slot_number, temporary_password); } template void vector_copy_ranged(T& dest, std::vector &vec, size_t begin, size_t elements_to_copy){ const size_t d_size = sizeof(dest); if(d_size < elements_to_copy){ throw TargetBufferSmallerThanSource(elements_to_copy, d_size); } std::fill(dest, dest+d_size, 0); std::copy(vec.begin() + begin, vec.begin() +begin + elements_to_copy, dest); } template void vector_copy(T& dest, std::vector &vec){ const size_t d_size = sizeof(dest); if(d_size < vec.size()){ throw TargetBufferSmallerThanSource(vec.size(), d_size); } std::fill(dest, dest+d_size, 0); std::copy(vec.begin(), vec.end(), dest); } bool NitrokeyManager::write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) { if (!is_valid_hotp_slot_number(slot_number)) throw InvalidSlotException(slot_number); int internal_slot_number = get_internal_slot_number_for_hotp(slot_number); if (is_authorization_command_supported()){ write_HOTP_slot_authorize(internal_slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); } else { write_OTP_slot_no_authorize(internal_slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); } return true; } void NitrokeyManager::write_HOTP_slot_authorize(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) { auto payload = get_payload(); payload.slot_number = slot_number; auto secret_bin = misc::hex_string_to_byte(secret); vector_copy(payload.slot_secret, secret_bin); strcpyT(payload.slot_name, slot_name); strcpyT(payload.slot_token_id, token_ID); switch (device->get_device_model() ){ case DeviceModel::PRO: { payload.slot_counter = hotp_counter; break; } case DeviceModel::STORAGE: { string counter = to_string(hotp_counter); strcpyT(payload.slot_counter_s, counter.c_str()); break; } default: LOG(string(__FILE__) + to_string(__LINE__) + string(__FUNCTION__) + string(" Unhandled device model for HOTP") , Loglevel::DEBUG); break; } payload.use_8_digits = use_8_digits; payload.use_enter = use_enter; payload.use_tokenID = use_tokenID; authorize_packet(payload, temporary_password, device); auto resp = WriteToHOTPSlot::CommandTransaction::run(device, payload); } bool NitrokeyManager::write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) { if (!is_valid_totp_slot_number(slot_number)) throw InvalidSlotException(slot_number); int internal_slot_number = get_internal_slot_number_for_totp(slot_number); if (is_authorization_command_supported()){ write_TOTP_slot_authorize(internal_slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); } else { write_OTP_slot_no_authorize(internal_slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); } return true; } void NitrokeyManager::write_OTP_slot_no_authorize(uint8_t internal_slot_number, const char *slot_name, const char *secret, uint64_t counter_or_interval, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) const { auto payload2 = get_payload(); strcpyT(payload2.temporary_admin_password, temporary_password); strcpyT(payload2.data, slot_name); payload2.setTypeName(); stick10_08::SendOTPData::CommandTransaction::run(device, payload2); payload2.setTypeSecret(); payload2.id = 0; auto secret_bin = misc::hex_string_to_byte(secret); auto remaining_secret_length = secret_bin.size(); const auto maximum_OTP_secret_size = 40; if(remaining_secret_length > maximum_OTP_secret_size){ throw TargetBufferSmallerThanSource(remaining_secret_length, maximum_OTP_secret_size); } while (remaining_secret_length>0){ const auto bytesToCopy = std::min(sizeof(payload2.data), remaining_secret_length); const auto start = secret_bin.size() - remaining_secret_length; memset(payload2.data, 0, sizeof(payload2.data)); vector_copy_ranged(payload2.data, secret_bin, start, bytesToCopy); stick10_08::SendOTPData::CommandTransaction::run(device, payload2); remaining_secret_length -= bytesToCopy; payload2.id++; } auto payload = get_payload(); strcpyT(payload.temporary_admin_password, temporary_password); strcpyT(payload.slot_token_id, token_ID); payload.use_8_digits = use_8_digits; payload.use_enter = use_enter; payload.use_tokenID = use_tokenID; payload.slot_counter_or_interval = counter_or_interval; payload.slot_number = internal_slot_number; stick10_08::WriteToOTPSlot::CommandTransaction::run(device, payload); } void NitrokeyManager::write_TOTP_slot_authorize(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) { auto payload = get_payload(); payload.slot_number = slot_number; auto secret_bin = misc::hex_string_to_byte(secret); vector_copy(payload.slot_secret, secret_bin); strcpyT(payload.slot_name, slot_name); strcpyT(payload.slot_token_id, token_ID); payload.slot_interval = time_window; //FIXME naming payload.use_8_digits = use_8_digits; payload.use_enter = use_enter; payload.use_tokenID = use_tokenID; authorize_packet(payload, temporary_password, device); auto resp = WriteToTOTPSlot::CommandTransaction::run(device, payload); } const char * NitrokeyManager::get_totp_slot_name(uint8_t slot_number) { if (!is_valid_totp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_totp(slot_number); return get_slot_name(slot_number); } const char * NitrokeyManager::get_hotp_slot_name(uint8_t slot_number) { if (!is_valid_hotp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_hotp(slot_number); return get_slot_name(slot_number); } static const int max_string_field_length = 2*1024; //storage's status string is ~1k const char * NitrokeyManager::get_slot_name(uint8_t slot_number) { auto payload = get_payload(); payload.slot_number = slot_number; auto resp = GetSlotName::CommandTransaction::run(device, payload); return strndup((const char *) resp.data().slot_name, max_string_field_length); } bool NitrokeyManager::first_authenticate(const char *pin, const char *temporary_password) { auto authreq = get_payload(); strcpyT(authreq.card_password, pin); strcpyT(authreq.temporary_password, temporary_password); FirstAuthenticate::CommandTransaction::run(device, authreq); return true; } bool NitrokeyManager::set_time(uint64_t time) { auto p = get_payload(); p.reset = 1; p.time = time; SetTime::CommandTransaction::run(device, p); return false; } bool NitrokeyManager::get_time(uint64_t time) { auto p = get_payload(); p.reset = 0; p.time = time; SetTime::CommandTransaction::run(device, p); return true; } void NitrokeyManager::change_user_PIN(const char *current_PIN, const char *new_PIN) { change_PIN_general(current_PIN, new_PIN); } void NitrokeyManager::change_admin_PIN(const char *current_PIN, const char *new_PIN) { change_PIN_general(current_PIN, new_PIN); } template void NitrokeyManager::change_PIN_general(const char *current_PIN, const char *new_PIN) { switch (device->get_device_model()){ case DeviceModel::PRO: { auto p = get_payload(); strcpyT(p.old_pin, current_PIN); strcpyT(p.new_pin, new_PIN); ProCommand::CommandTransaction::run(device, p); } break; //in Storage change admin/user pin is divided to two commands with 20 chars field len case DeviceModel::STORAGE: { auto p = get_payload(); strcpyT(p.password, current_PIN); p.set_kind(StoKind); auto p2 = get_payload(); strcpyT(p2.password, new_PIN); p2.set_kind(StoKind); ChangeAdminUserPin20Current::CommandTransaction::run(device, p); ChangeAdminUserPin20New::CommandTransaction::run(device, p2); } break; } } void NitrokeyManager::enable_password_safe(const char *user_pin) { //The following command will cancel enabling PWS if it is not supported auto a = get_payload(); strcpyT(a.user_password, user_pin); IsAESSupported::CommandTransaction::run(device, a); auto p = get_payload(); strcpyT(p.user_password, user_pin); EnablePasswordSafe::CommandTransaction::run(device, p); } vector NitrokeyManager::get_password_safe_slot_status() { auto responsePayload = GetPasswordSafeSlotStatus::CommandTransaction::run(device); vector v = vector(responsePayload.data().password_safe_status, responsePayload.data().password_safe_status + sizeof(responsePayload.data().password_safe_status)); return v; } uint8_t NitrokeyManager::get_user_retry_count() { if(device->get_device_model() == DeviceModel::STORAGE){ stick20::GetDeviceStatus::CommandTransaction::run(device); } auto response = GetUserPasswordRetryCount::CommandTransaction::run(device); return response.data().password_retry_count; } uint8_t NitrokeyManager::get_admin_retry_count() { if(device->get_device_model() == DeviceModel::STORAGE){ stick20::GetDeviceStatus::CommandTransaction::run(device); } auto response = GetPasswordRetryCount::CommandTransaction::run(device); return response.data().password_retry_count; } void NitrokeyManager::lock_device() { LockDevice::CommandTransaction::run(device); } const char *NitrokeyManager::get_password_safe_slot_name(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload(); p.slot_number = slot_number; auto response = GetPasswordSafeSlotName::CommandTransaction::run(device, p); return strndup((const char *) response.data().slot_name, max_string_field_length); } bool NitrokeyManager::is_valid_password_safe_slot_number(uint8_t slot_number) const { return slot_number < 16; } const char *NitrokeyManager::get_password_safe_slot_login(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload(); p.slot_number = slot_number; auto response = GetPasswordSafeSlotLogin::CommandTransaction::run(device, p); return strndup((const char *) response.data().slot_login, max_string_field_length); } const char *NitrokeyManager::get_password_safe_slot_password(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload(); p.slot_number = slot_number; auto response = GetPasswordSafeSlotPassword::CommandTransaction::run(device, p); return strndup((const char *) response.data().slot_password, max_string_field_length); //FIXME use secure way } void NitrokeyManager::write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, const char *slot_password) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload(); p.slot_number = slot_number; strcpyT(p.slot_name, slot_name); strcpyT(p.slot_password, slot_password); SetPasswordSafeSlotData::CommandTransaction::run(device, p); auto p2 = get_payload(); p2.slot_number = slot_number; strcpyT(p2.slot_login_name, slot_login); SetPasswordSafeSlotData2::CommandTransaction::run(device, p2); } void NitrokeyManager::erase_password_safe_slot(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload(); p.slot_number = slot_number; ErasePasswordSafeSlot::CommandTransaction::run(device, p); } void NitrokeyManager::user_authenticate(const char *user_password, const char *temporary_password) { auto p = get_payload(); strcpyT(p.card_password, user_password); strcpyT(p.temporary_password, temporary_password); UserAuthenticate::CommandTransaction::run(device, p); } void NitrokeyManager::build_aes_key(const char *admin_password) { switch (device->get_device_model()) { case DeviceModel::PRO: { auto p = get_payload(); strcpyT(p.admin_password, admin_password); BuildAESKey::CommandTransaction::run(device, p); break; } case DeviceModel::STORAGE : { auto p = get_payload(); strcpyT(p.password, admin_password); p.set_defaults(); stick20::CreateNewKeys::CommandTransaction::run(device, p); break; } } } void NitrokeyManager::factory_reset(const char *admin_password) { auto p = get_payload(); strcpyT(p.admin_password, admin_password); FactoryReset::CommandTransaction::run(device, p); } void NitrokeyManager::unlock_user_password(const char *admin_password, const char *new_user_password) { switch (device->get_device_model()){ case DeviceModel::PRO: { auto p = get_payload(); strcpyT(p.admin_password, admin_password); strcpyT(p.user_new_password, new_user_password); stick10::UnlockUserPassword::CommandTransaction::run(device, p); break; } case DeviceModel::STORAGE : { auto p2 = get_payload(); p2.set_defaults(); strcpyT(p2.password, admin_password); ChangeAdminUserPin20Current::CommandTransaction::run(device, p2); auto p3 = get_payload(); p3.set_defaults(); strcpyT(p3.password, new_user_password); stick20::UnlockUserPin::CommandTransaction::run(device, p3); break; } } } void NitrokeyManager::write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password) { auto p = get_payload(); p.numlock = numlock; p.capslock = capslock; p.scrolllock = scrolllock; p.enable_user_password = static_cast(enable_user_password ? 1 : 0); p.delete_user_password = static_cast(delete_user_password ? 1 : 0); if (is_authorization_command_supported()){ authorize_packet(p, admin_temporary_password, device); } else { strcpyT(p.temporary_admin_password, admin_temporary_password); } stick10_08::WriteGeneralConfig::CommandTransaction::run(device, p); } vector NitrokeyManager::read_config() { auto responsePayload = GetStatus::CommandTransaction::run(device); vector v = vector(responsePayload.data().general_config, responsePayload.data().general_config+sizeof(responsePayload.data().general_config)); return v; } bool NitrokeyManager::is_authorization_command_supported(){ //authorization command is supported for versions equal or below: auto m = std::unordered_map({ {DeviceModel::PRO, 7}, {DeviceModel::STORAGE, 999}, }); return get_minor_firmware_version() <= m[device->get_device_model()]; } bool NitrokeyManager::is_320_OTP_secret_supported(){ //authorization command is supported for versions equal or below: auto m = std::unordered_map({ {DeviceModel::PRO, 8}, {DeviceModel::STORAGE, 999}, }); return get_minor_firmware_version() >= m[device->get_device_model()]; } DeviceModel NitrokeyManager::get_connected_device_model() const{ if (device == nullptr){ throw DeviceNotConnected("device not connected"); } return device->get_device_model(); } bool NitrokeyManager::is_smartcard_in_use(){ try{ stick20::CheckSmartcardUsage::CommandTransaction::run(device); } catch(const CommandFailedException & e){ return e.reason_smartcard_busy(); } return false; } int NitrokeyManager::get_minor_firmware_version(){ switch(device->get_device_model()){ case DeviceModel::PRO:{ auto status_p = GetStatus::CommandTransaction::run(device); return status_p.data().firmware_version_st.minor; //7 or 8 } case DeviceModel::STORAGE:{ auto status = stick20::GetDeviceStatus::CommandTransaction::run(device); auto test_firmware = status.data().versionInfo.build_iteration != 0; if (test_firmware) LOG("Development firmware detected. Increasing minor version number.", nitrokey::log::Loglevel::WARNING); return status.data().versionInfo.minor + (test_firmware? 1 : 0); } } return 0; } int NitrokeyManager::get_major_firmware_version(){ switch(device->get_device_model()){ case DeviceModel::PRO:{ auto status_p = GetStatus::CommandTransaction::run(device); return status_p.data().firmware_version_st.major; //0 } case DeviceModel::STORAGE:{ auto status = stick20::GetDeviceStatus::CommandTransaction::run(device); return status.data().versionInfo.major; } } return 0; } bool NitrokeyManager::is_AES_supported(const char *user_password) { auto a = get_payload(); strcpyT(a.user_password, user_password); IsAESSupported::CommandTransaction::run(device, a); return true; } //storage commands void NitrokeyManager::send_startup(uint64_t seconds_from_epoch){ auto p = get_payload(); // p.set_defaults(); //set current time p.localtime = seconds_from_epoch; stick20::SendStartup::CommandTransaction::run(device, p); } void NitrokeyManager::unlock_encrypted_volume(const char* user_pin){ misc::execute_password_command(device, user_pin); } void NitrokeyManager::unlock_hidden_volume(const char* hidden_volume_password) { misc::execute_password_command(device, hidden_volume_password); } void NitrokeyManager::set_encrypted_volume_read_only(const char* admin_pin) { misc::execute_password_command(device, admin_pin); } void NitrokeyManager::set_encrypted_volume_read_write(const char* admin_pin) { misc::execute_password_command(device, admin_pin); } //TODO check is encrypted volume unlocked before execution //if not return library exception void NitrokeyManager::create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, const char *hidden_volume_password) { auto p = get_payload(); p.SlotNr_u8 = slot_nr; p.StartBlockPercent_u8 = start_percent; p.EndBlockPercent_u8 = end_percent; strcpyT(p.HiddenVolumePassword_au8, hidden_volume_password); stick20::SetupHiddenVolume::CommandTransaction::run(device, p); } void NitrokeyManager::set_unencrypted_read_only_admin(const char* admin_pin) { //from v0.49, v0.52+ it needs Admin PIN if (set_unencrypted_volume_rorw_pin_type_user()){ LOG("set_unencrypted_read_only_admin is not supported for this version of Storage device. " "Please update firmware to v0.52+. Doing nothing.", nitrokey::log::Loglevel::WARNING); return; } misc::execute_password_command(device, admin_pin); } void NitrokeyManager::set_unencrypted_read_only(const char *user_pin) { //until v0.48 (incl. v0.50 and v0.51) User PIN was sufficient LOG("set_unencrypted_read_only is deprecated. Use set_unencrypted_read_only_admin instead.", nitrokey::log::Loglevel::WARNING); if (!set_unencrypted_volume_rorw_pin_type_user()){ LOG("set_unencrypted_read_only is not supported for this version of Storage device. Doing nothing.", nitrokey::log::Loglevel::WARNING); return; } misc::execute_password_command(device, user_pin); } void NitrokeyManager::set_unencrypted_read_write_admin(const char* admin_pin) { //from v0.49, v0.52+ it needs Admin PIN if (set_unencrypted_volume_rorw_pin_type_user()){ LOG("set_unencrypted_read_write_admin is not supported for this version of Storage device. " "Please update firmware to v0.52+. Doing nothing.", nitrokey::log::Loglevel::WARNING); return; } misc::execute_password_command(device, admin_pin); } void NitrokeyManager::set_unencrypted_read_write(const char *user_pin) { //until v0.48 (incl. v0.50 and v0.51) User PIN was sufficient LOG("set_unencrypted_read_write is deprecated. Use set_unencrypted_read_write_admin instead.", nitrokey::log::Loglevel::WARNING); if (!set_unencrypted_volume_rorw_pin_type_user()){ LOG("set_unencrypted_read_write is not supported for this version of Storage device. Doing nothing.", nitrokey::log::Loglevel::WARNING); return; } misc::execute_password_command(device, user_pin); } bool NitrokeyManager::set_unencrypted_volume_rorw_pin_type_user(){ auto minor_firmware_version = get_minor_firmware_version(); return minor_firmware_version <= 48 || minor_firmware_version == 50 || minor_firmware_version == 51; } void NitrokeyManager::export_firmware(const char* admin_pin) { misc::execute_password_command(device, admin_pin); } void NitrokeyManager::enable_firmware_update(const char* firmware_pin) { misc::execute_password_command(device, firmware_pin); } void NitrokeyManager::clear_new_sd_card_warning(const char* admin_pin) { misc::execute_password_command(device, admin_pin); } void NitrokeyManager::fill_SD_card_with_random_data(const char* admin_pin) { auto p = get_payload(); p.set_defaults(); strcpyT(p.admin_pin, admin_pin); stick20::FillSDCardWithRandomChars::CommandTransaction::run(device, p); } void NitrokeyManager::change_update_password(const char* current_update_password, const char* new_update_password) { auto p = get_payload(); strcpyT(p.current_update_password, current_update_password); strcpyT(p.new_update_password, new_update_password); stick20::ChangeUpdatePassword::CommandTransaction::run(device, p); } const char * NitrokeyManager::get_status_storage_as_string(){ auto p = stick20::GetDeviceStatus::CommandTransaction::run(device); return strndup(p.data().dissect().c_str(), max_string_field_length); } stick20::DeviceConfigurationResponsePacket::ResponsePayload NitrokeyManager::get_status_storage(){ auto p = stick20::GetDeviceStatus::CommandTransaction::run(device); return p.data(); } const char * NitrokeyManager::get_SD_usage_data_as_string(){ auto p = stick20::GetSDCardOccupancy::CommandTransaction::run(device); return strndup(p.data().dissect().c_str(), max_string_field_length); } std::pair NitrokeyManager::get_SD_usage_data(){ auto p = stick20::GetSDCardOccupancy::CommandTransaction::run(device); return std::make_pair(p.data().WriteLevelMin, p.data().WriteLevelMax); } int NitrokeyManager::get_progress_bar_value(){ try{ stick20::GetDeviceStatus::CommandTransaction::run(device); return -1; } catch (LongOperationInProgressException &e){ return e.progress_bar_value; } } string NitrokeyManager::get_TOTP_code(uint8_t slot_number, const char *user_temporary_password) { return get_TOTP_code(slot_number, 0, 0, 0, user_temporary_password); } stick10::ReadSlot::ResponsePayload NitrokeyManager::get_OTP_slot_data(const uint8_t slot_number) { auto p = get_payload(); p.slot_number = slot_number; auto data = stick10::ReadSlot::CommandTransaction::run(device, p); return data.data(); } stick10::ReadSlot::ResponsePayload NitrokeyManager::get_TOTP_slot_data(const uint8_t slot_number) { return get_OTP_slot_data(get_internal_slot_number_for_totp(slot_number)); } stick10::ReadSlot::ResponsePayload NitrokeyManager::get_HOTP_slot_data(const uint8_t slot_number) { auto slot_data = get_OTP_slot_data(get_internal_slot_number_for_hotp(slot_number)); if (device->get_device_model() == DeviceModel::STORAGE){ //convert counter from string to ull auto counter_s = std::string(slot_data.slot_counter_s, slot_data.slot_counter_s+sizeof(slot_data.slot_counter_s)); slot_data.slot_counter = std::stoull(counter_s); } return slot_data; } void NitrokeyManager::lock_encrypted_volume() { misc::execute_password_command(device, ""); } void NitrokeyManager::lock_hidden_volume() { misc::execute_password_command(device, ""); } uint8_t NitrokeyManager::get_SD_card_size() { auto data = stick20::ProductionTest::CommandTransaction::run(device); return data.data().SD_Card_Size_u8; } const string NitrokeyManager::get_current_device_id() const { return current_device_id; } } nitrokey-app-1.3.2/libnitrokey/README.md0000644000175000017500000002514313275777076017345 0ustar janjan00000000000000[![Build Status](https://travis-ci.org/Nitrokey/libnitrokey.svg?branch=master)](https://travis-ci.org/Nitrokey/libnitrokey) [![Waffle.io - Columns and their card count](https://badge.waffle.io/Nitrokey/libnitrokey.svg?columns=ready,in%20progress,test,waiting%20for%20feedback)](https://waffle.io/Nitrokey/libnitrokey) # 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](include/stick10_commands.h), [Pro v0.8](include/stick10_commands_0.8.h), [Storage](include/stick20_commands.h). Handling and additional operations are described here: [NitrokeyManager.cc](NitrokeyManager.cc). A C++14 complying compiler is required due to heavy use of variable templates. For feature support tables please check [table 1](https://gcc.gnu.org/projects/cxx-status.html#cxx14) or [table 2](http://en.cppreference.com/w/cpp/compiler_support). libnitrokey is developed and tested with the latest compilers: g++ 6.2, clang 3.8. We use Travis CI to test builds also on g++ 5.4 and under OSX compilers starting up from xcode 8.2 environment. ## Getting sources This repository uses `git submodules`. To clone please use git's `--recursive` option like in: ```bash git clone --recursive https://github.com/Nitrokey/libnitrokey.git ``` or for already cloned repository: ```bash 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): - libhidapi-dev [(HID API)](http://www.signal11.us/oss/hidapi/) - libusb-1.0-0-dev ## Compilation libnitrokey uses CMake as its main build system. As a secondary option it offers building through Qt's qMake. ### 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: ```bash mkdir -p build cd build qmake .. make -j2 ``` ### Windows MS 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: ```bash # assuming current dir is ./libnitrokey/ mkdir -p build cd build cmake .. make -j2 ``` By default (with empty `` 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 `` 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](.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 # Using libnitrokey with Python To use libnitrokey with Python a [CFFI](http://cffi.readthedocs.io/en/latest/overview.html) library is required (either 2.7+ or 3.0+). It can be installed with: ```bash pip install --user cffi # for python 2.x pip3 install cffi # for python 3.x ``` 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)](python_bindings_example.py): ```python #!/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](NK_C_API.h). Please check `Documentation` section below. ## Documentation The documentation of C API is included in the sources (could be generated with doxygen if requested). Please check [NK_C_API.h](NK_C_API.h) (C API) for high level commands and [include/NitrokeyManager.h](include/NitrokeyManager.h) (C++ API). All devices' commands are listed along with packet format in [include/stick10_commands.h](include/stick10_commands.h) and [include/stick20_commands.h](include/stick20_commands.h) respectively for Nitrokey Pro and Nitrokey Storage products. # Tests Warning! Before you run unittests please either 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 and lose your data. If it's too late, you can reset your Nitrokey using instructions from [homepage](https://www.nitrokey.com/de/documentation/how-reset-nitrokey). ## 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: ```bash cd unittest pip install --user -r requirements.txt ``` To run them please execute: ```bash # substitute with either pro or storage py.test -v test_.py # more specific use - run tests containing in name 5 times: py.test -v test_.py -k --count 5 ``` For additional documentation please check the following for [py.test installation](http://doc.pytest.org/en/latest/getting-started.html). For better coverage [randomly plugin](https://pypi.python.org/pypi/pytest-randomly) 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. They are not written as extensively as Python tests and are rather more a C++ low level interface check, often not using C++ API from `NitrokeyManager.cc`. Some of them are: [test_HOTP.cc](https://github.com/Nitrokey/libnitrokey/blob/master/unittest/test_HOTP.cc), [test.cc](https://github.com/Nitrokey/libnitrokey/blob/master/unittest/test.cc). Unit tests were written and tested 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 like in `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](https://github.com/Nitrokey/nitrokey-app/blob/master/README.md#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](https://github.com/Nitrokey/nitrokey-pro-firmware/blob/master/src/keyboard/report_protocol.c) (for Nitrokey Pro, for Storage similarly). # Known issues / tasks * Currently only one device can be connected at a time (experimental work could be found in `wip-multiple_devices` branch), * C++ API needs some reorganization to C++ objects (instead of pointers to arrays). This will be also preparing for integration with Pybind11, * Fix compilation warnings. Other tasks might be listed either in [TODO](TODO) file or on project's issues page. # License This project is licensed under LGPL version 3. License text could be found under [LICENSE](LICENSE) file. # Roadmap To check what issues will be fixed and when please check [milestones](https://github.com/Nitrokey/libnitrokey/milestones) page. nitrokey-app-1.3.2/libnitrokey/TODO0000644000175000017500000000007313221174520016521 0ustar janjan00000000000000use strings instead of char* and vectors instead of others nitrokey-app-1.3.2/libnitrokey/build/.gitignore0000644000175000017500000000000213221174520021110 0ustar janjan00000000000000* nitrokey-app-1.3.2/libnitrokey/command_id.cc0000644000175000017500000001431413275777076020465 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include #include "command_id.h" namespace nitrokey { namespace proto { const char *commandid_to_string(CommandID id) { switch (id) { case CommandID::GET_STATUS: return "GET_STATUS"; case CommandID::WRITE_TO_SLOT: return "WRITE_TO_SLOT"; case CommandID::READ_SLOT_NAME: return "READ_SLOT_NAME"; case CommandID::READ_SLOT: return "READ_SLOT"; case CommandID::GET_CODE: return "GET_CODE"; case CommandID::WRITE_CONFIG: return "WRITE_CONFIG"; case CommandID::ERASE_SLOT: return "ERASE_SLOT"; case CommandID::FIRST_AUTHENTICATE: return "FIRST_AUTHENTICATE"; case CommandID::AUTHORIZE: return "AUTHORIZE"; case CommandID::GET_PASSWORD_RETRY_COUNT: return "GET_PASSWORD_RETRY_COUNT"; case CommandID::CLEAR_WARNING: return "CLEAR_WARNING"; case CommandID::SET_TIME: return "SET_TIME"; case CommandID::TEST_COUNTER: return "TEST_COUNTER"; case CommandID::TEST_TIME: return "TEST_TIME"; case CommandID::USER_AUTHENTICATE: return "USER_AUTHENTICATE"; case CommandID::GET_USER_PASSWORD_RETRY_COUNT: return "GET_USER_PASSWORD_RETRY_COUNT"; case CommandID::USER_AUTHORIZE: return "USER_AUTHORIZE"; case CommandID::UNLOCK_USER_PASSWORD: return "UNLOCK_USER_PASSWORD"; case CommandID::LOCK_DEVICE: return "LOCK_DEVICE"; case CommandID::FACTORY_RESET: return "FACTORY_RESET"; case CommandID::CHANGE_USER_PIN: return "CHANGE_USER_PIN"; case CommandID::CHANGE_ADMIN_PIN: return "CHANGE_ADMIN_PIN"; case CommandID::ENABLE_CRYPTED_PARI: return "ENABLE_CRYPTED_PARI"; case CommandID::DISABLE_CRYPTED_PARI: return "DISABLE_CRYPTED_PARI"; case CommandID::ENABLE_HIDDEN_CRYPTED_PARI: return "ENABLE_HIDDEN_CRYPTED_PARI"; case CommandID::DISABLE_HIDDEN_CRYPTED_PARI: return "DISABLE_HIDDEN_CRYPTED_PARI"; case CommandID::ENABLE_FIRMWARE_UPDATE: return "ENABLE_FIRMWARE_UPDATE"; case CommandID::EXPORT_FIRMWARE_TO_FILE: return "EXPORT_FIRMWARE_TO_FILE"; case CommandID::GENERATE_NEW_KEYS: return "GENERATE_NEW_KEYS"; case CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS: return "FILL_SD_CARD_WITH_RANDOM_CHARS"; case CommandID::WRITE_STATUS_DATA: return "WRITE_STATUS_DATA"; case CommandID::ENABLE_READONLY_UNCRYPTED_LUN: return "ENABLE_READONLY_UNCRYPTED_LUN"; case CommandID::ENABLE_READWRITE_UNCRYPTED_LUN: return "ENABLE_READWRITE_UNCRYPTED_LUN"; case CommandID::SEND_PASSWORD_MATRIX: return "SEND_PASSWORD_MATRIX"; case CommandID::SEND_PASSWORD_MATRIX_PINDATA: return "SEND_PASSWORD_MATRIX_PINDATA"; case CommandID::SEND_PASSWORD_MATRIX_SETUP: return "SEND_PASSWORD_MATRIX_SETUP"; case CommandID::GET_DEVICE_STATUS: return "GET_DEVICE_STATUS"; case CommandID::SEND_DEVICE_STATUS: return "SEND_DEVICE_STATUS"; case CommandID::SEND_HIDDEN_VOLUME_PASSWORD: return "SEND_HIDDEN_VOLUME_PASSWORD"; case CommandID::SEND_HIDDEN_VOLUME_SETUP: return "SEND_HIDDEN_VOLUME_SETUP"; case CommandID::SEND_PASSWORD: return "SEND_PASSWORD"; case CommandID::SEND_NEW_PASSWORD: return "SEND_NEW_PASSWORD"; case CommandID::CLEAR_NEW_SD_CARD_FOUND: return "CLEAR_NEW_SD_CARD_FOUND"; case CommandID::SEND_STARTUP: return "SEND_STARTUP"; case CommandID::SEND_CLEAR_STICK_KEYS_NOT_INITIATED: return "SEND_CLEAR_STICK_KEYS_NOT_INITIATED"; case CommandID::SEND_LOCK_STICK_HARDWARE: return "SEND_LOCK_STICK_HARDWARE"; case CommandID::PRODUCTION_TEST: return "PRODUCTION_TEST"; case CommandID::SEND_DEBUG_DATA: return "SEND_DEBUG_DATA"; case CommandID::CHANGE_UPDATE_PIN: return "CHANGE_UPDATE_PIN"; case CommandID::ENABLE_ADMIN_READONLY_UNCRYPTED_LUN: return "ENABLE_ADMIN_READONLY_UNCRYPTED_LUN"; case CommandID::ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN: return "ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN"; case CommandID::ENABLE_ADMIN_READONLY_ENCRYPTED_LUN: return "ENABLE_ADMIN_READONLY_ENCRYPTED_LUN"; case CommandID::ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN: return "ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN"; case CommandID::CHECK_SMARTCARD_USAGE: return "CHECK_SMARTCARD_USAGE"; case CommandID::GET_PW_SAFE_SLOT_STATUS: return "GET_PW_SAFE_SLOT_STATUS"; case CommandID::GET_PW_SAFE_SLOT_NAME: return "GET_PW_SAFE_SLOT_NAME"; case CommandID::GET_PW_SAFE_SLOT_PASSWORD: return "GET_PW_SAFE_SLOT_PASSWORD"; case CommandID::GET_PW_SAFE_SLOT_LOGINNAME: return "GET_PW_SAFE_SLOT_LOGINNAME"; case CommandID::SET_PW_SAFE_SLOT_DATA_1: return "SET_PW_SAFE_SLOT_DATA_1"; case CommandID::SET_PW_SAFE_SLOT_DATA_2: return "SET_PW_SAFE_SLOT_DATA_2"; case CommandID::PW_SAFE_ERASE_SLOT: return "PW_SAFE_ERASE_SLOT"; case CommandID::PW_SAFE_ENABLE: return "PW_SAFE_ENABLE"; case CommandID::PW_SAFE_INIT_KEY: return "PW_SAFE_INIT_KEY"; case CommandID::PW_SAFE_SEND_DATA: return "PW_SAFE_SEND_DATA"; case CommandID::SD_CARD_HIGH_WATERMARK: return "SD_CARD_HIGH_WATERMARK"; case CommandID::DETECT_SC_AES: return "DETECT_SC_AES"; case CommandID::NEW_AES_KEY: return "NEW_AES_KEY"; case CommandID::WRITE_TO_SLOT_2: return "WRITE_TO_SLOT_2"; break; case CommandID::SEND_OTP_DATA: return "SEND_OTP_DATA"; break; } return "UNKNOWN"; } } } nitrokey-app-1.3.2/libnitrokey/data/41-nitrokey.rules0000644000175000017500000000233013275777076022132 0ustar janjan00000000000000# Nitrokey U2F KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0" SUBSYSTEM!="usb", GOTO="gnupg_rules_end" ACTION!="add", GOTO="gnupg_rules_end" # USB SmartCard Readers ## Crypto Stick 1.2 ATTR{idVendor}=="20a0", ATTR{idProduct}=="4107", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg", GROUP+="plugdev", TAG+="uaccess" ## Nitrokey Pro ATTR{idVendor}=="20a0", ATTR{idProduct}=="4108", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg", GROUP+="plugdev", TAG+="uaccess" ## Nitrokey Storage ATTR{idVendor}=="20a0", ATTR{idProduct}=="4109", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg", GROUP+="plugdev", TAG+="uaccess" ## Nitrokey Start ATTR{idVendor}=="20a0", ATTR{idProduct}=="4211", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg", GROUP+="plugdev", TAG+="uaccess" ## Nitrokey HSM ATTR{idVendor}=="20a0", ATTR{idProduct}=="4230", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg", GROUP+="plugdev", TAG+="uaccess" LABEL="gnupg_rules_end" # Nitrokey Storage dev Entry KERNEL=="sd?1", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="4109", SYMLINK+="nitrospace" nitrokey-app-1.3.2/libnitrokey/device.cc0000644000175000017500000001774013275777076017640 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include #include #include #include #include #include "hidapi/hidapi.h" #include "libnitrokey/misc.h" #include "libnitrokey/device.h" #include "libnitrokey/log.h" #include #include "DeviceCommunicationExceptions.h" #include "device.h" std::mutex mex_dev_com; using namespace nitrokey::device; using namespace nitrokey::log; using namespace std::chrono; std::atomic_int Device::instances_count{0}; std::chrono::milliseconds Device::default_delay {0} ; Device::Device(const uint16_t vid, const uint16_t pid, const DeviceModel model, const milliseconds send_receive_delay, const int retry_receiving_count, const milliseconds retry_timeout) : last_command_status(0), m_vid(vid), m_pid(pid), m_model(model), m_retry_sending_count(1), m_retry_receiving_count(retry_receiving_count), m_retry_timeout(retry_timeout), m_send_receive_delay(send_receive_delay), mp_devhandle(nullptr) { instances_count++; } bool Device::disconnect() { //called in object's destructor LOG(__FUNCTION__, Loglevel::DEBUG_L2); std::lock_guard lock(mex_dev_com); return _disconnect(); } bool Device::_disconnect() { LOG(std::string(__FUNCTION__) + std::string(m_model == DeviceModel::PRO ? "PRO" : "STORAGE"), Loglevel::DEBUG_L2); LOG(std::string(__FUNCTION__) + std::string(" *IN* "), Loglevel::DEBUG_L2); LOG(std::string("Disconnection: handle already freed: ") + std::to_string(mp_devhandle == nullptr) + " ("+m_path+")", Loglevel::DEBUG_L1); if(mp_devhandle == nullptr) return false; hid_close(mp_devhandle); mp_devhandle = nullptr; #ifndef __APPLE__ if (instances_count == 1){ LOG(std::string("Calling hid_exit"), Loglevel::DEBUG_L2); hid_exit(); } #endif return true; } bool Device::connect() { LOG(__FUNCTION__, Loglevel::DEBUG_L2); std::lock_guard lock(mex_dev_com); return _connect(); } bool Device::_connect() { LOG(std::string(__FUNCTION__) + std::string(" *IN* "), Loglevel::DEBUG_L2); // hid_init(); // done automatically on hid_open if (m_path.empty()){ mp_devhandle = hid_open(m_vid, m_pid, nullptr); } else { mp_devhandle = hid_open_path(m_path.c_str()); } const bool success = mp_devhandle != nullptr; LOG(std::string("Connection success: ") + std::to_string(success) + " ("+m_path+")", Loglevel::DEBUG_L1); return success; } void Device::set_path(const std::string path){ m_path = path; } int Device::send(const void *packet) { LOG(__FUNCTION__, Loglevel::DEBUG_L2); std::lock_guard lock(mex_dev_com); LOG(std::string(__FUNCTION__) + std::string(" *IN* "), Loglevel::DEBUG_L2); int send_feature_report = -1; for (int i = 0; i < 3 && send_feature_report < 0; ++i) { if (mp_devhandle == nullptr) { LOG(std::string("Connection fail") , Loglevel::DEBUG_L2); throw DeviceNotConnected("Attempted HID send on an invalid descriptor."); } send_feature_report = hid_send_feature_report( mp_devhandle, (const unsigned char *)(packet), HID_REPORT_SIZE); if (send_feature_report < 0) _reconnect(); //add thread sleep? LOG(std::string("Sending attempt: ")+std::to_string(i+1) + " / 3" , Loglevel::DEBUG_L2); } return send_feature_report; } int Device::recv(void *packet) { LOG(__FUNCTION__, Loglevel::DEBUG_L2); std::lock_guard lock(mex_dev_com); LOG(std::string(__FUNCTION__) + std::string(" *IN* "), Loglevel::DEBUG_L2); int status; int retry_count = 0; for (;;) { if (mp_devhandle == nullptr){ LOG(std::string("Connection fail") , Loglevel::DEBUG_L2); throw DeviceNotConnected("Attempted HID receive on an invalid descriptor."); } status = (hid_get_feature_report(mp_devhandle, (unsigned char *)(packet), HID_REPORT_SIZE)); auto pwherr = hid_error(mp_devhandle); std::wstring wherr = (pwherr != nullptr) ? pwherr : L"No error message"; std::string herr(wherr.begin(), wherr.end()); LOG(std::string("libhid error message: ") + herr, Loglevel::DEBUG_L2); if (status > 0) break; // success if (retry_count++ >= m_retry_receiving_count) { LOG( "Maximum retry count reached: " + std::to_string(retry_count), Loglevel::WARNING); LOG( std::string("Counter stats: ") + m_counters.get_as_string(), Loglevel::DEBUG); break; } _reconnect(); LOG("Retrying... " + std::to_string(retry_count), Loglevel::DEBUG); std::this_thread::sleep_for(m_retry_timeout); } return status; } std::vector Device::enumerate(){ //TODO make static auto pInfo = hid_enumerate(m_vid, m_pid); auto pInfo_ = pInfo; std::vector res; while (pInfo != nullptr){ std::string a (pInfo->path); res.push_back(a); pInfo = pInfo->next; } if (pInfo_ != nullptr){ hid_free_enumeration(pInfo_); } return res; } bool Device::could_be_enumerated() { LOG(__FUNCTION__, Loglevel::DEBUG_L2); std::lock_guard lock(mex_dev_com); if (mp_devhandle==nullptr){ return false; } #ifndef __APPLE__ auto pInfo = hid_enumerate(m_vid, m_pid); if (pInfo != nullptr){ hid_free_enumeration(pInfo); return true; } return false; #else // alternative for OSX unsigned char buf[1]; return hid_read_timeout(mp_devhandle, buf, sizeof(buf), 20) != -1; #endif } void Device::show_stats() { auto s = m_counters.get_as_string(); LOG(s, Loglevel::DEBUG_L2); } void Device::_reconnect() { LOG(__FUNCTION__, Loglevel::DEBUG_L2); ++m_counters.low_level_reconnect; _disconnect(); _connect(); } Device::~Device() { show_stats(); disconnect(); instances_count--; } void Device::set_default_device_speed(int delay) { default_delay = std::chrono::duration(delay); } void Device::set_receiving_delay(const std::chrono::milliseconds delay){ std::lock_guard lock(mex_dev_com); m_send_receive_delay = delay; } void Device::set_retry_delay(const std::chrono::milliseconds delay){ std::lock_guard lock(mex_dev_com); m_retry_timeout = delay; } Stick10::Stick10(): Device(0x20a0, 0x4108, DeviceModel::PRO, 100ms, 5, 100ms) { setDefaultDelay(); } Stick20::Stick20(): Device(0x20a0, 0x4109, DeviceModel::STORAGE, 40ms, 55, 40ms) { setDefaultDelay(); } #include #define p(x) ss << #x << " " << x << ", "; std::string Device::ErrorCounters::get_as_string() { std::stringstream ss; p(total_comm_runs); p(communication_successful); ss << "("; p(command_successful_recv); p(command_result_not_equal_0_recv); ss << "), "; p(sends_executed); p(recv_executed); p(successful_storage_commands); p(total_retries); ss << "("; p(busy); p(busy_progressbar); p(CRC_other_than_awaited); p(wrong_CRC); ss << "), "; p(low_level_reconnect); p(sending_error); p(receiving_error); return ss.str(); } void Device::setDefaultDelay() { LOG(__FUNCTION__, Loglevel::DEBUG_L2); auto count = default_delay.count(); if (count != 0){ LOG("Setting default delay to " + std::to_string(count), Loglevel::DEBUG_L2); m_retry_timeout = default_delay; m_send_receive_delay = default_delay; } } #undef p nitrokey-app-1.3.2/libnitrokey/libnitrokey.pc.in0000644000175000017500000000044613221174520021321 0ustar janjan00000000000000libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: libnitrokey Description: Library for communicating with Nitrokey in a clean and easy manner Version: @libnitrokey_VERSION@ Requires.private: hidapi-libusb Libs: -L${libdir} -lnitrokey Cflags: -I${includedir} nitrokey-app-1.3.2/libnitrokey/libnitrokey.pro0000644000175000017500000000530013275777076021134 0ustar janjan00000000000000# Created by and for Qt Creator. This file was created for editing the project sources only. # You may attempt to use it for building too, by modifying this file here. CONFIG += c++14 shared debug TEMPLATE = lib TARGET = nitrokey VERSION = 3.3 QMAKE_TARGET_COMPANY = Nitrokey QMAKE_TARGET_PRODUCT = libnitrokey QMAKE_TARGET_DESCRIPTION = Communicate with Nitrokey stick devices in a clean and easy manner QMAKE_TARGET_COPYRIGHT = Copyright (c) 2015-2018 Nitrokey UG HEADERS = \ $$PWD/hidapi/hidapi/hidapi.h \ $$PWD/libnitrokey/command.h \ $$PWD/libnitrokey/command_id.h \ $$PWD/libnitrokey/CommandFailedException.h \ $$PWD/libnitrokey/cxx_semantics.h \ $$PWD/libnitrokey/device.h \ $$PWD/libnitrokey/device_proto.h \ $$PWD/libnitrokey/DeviceCommunicationExceptions.h \ $$PWD/libnitrokey/dissect.h \ $$PWD/libnitrokey/LibraryException.h \ $$PWD/libnitrokey/log.h \ $$PWD/libnitrokey/LongOperationInProgressException.h \ $$PWD/libnitrokey/misc.h \ $$PWD/libnitrokey/NitrokeyManager.h \ $$PWD/libnitrokey/stick10_commands.h \ $$PWD/libnitrokey/stick10_commands_0.8.h \ $$PWD/libnitrokey/stick20_commands.h \ $$PWD/NK_C_API.h SOURCES = \ $$PWD/command_id.cc \ $$PWD/device.cc \ $$PWD/DeviceCommunicationExceptions.cpp \ $$PWD/log.cc \ $$PWD/misc.cc \ $$PWD/NitrokeyManager.cc \ $$PWD/NK_C_API.cc tests { SOURCES += \ $$PWD/unittest/catch_main.cpp \ $$PWD/unittest/test.cc \ $$PWD/unittest/test2.cc \ $$PWD/unittest/test3.cc \ $$PWD/unittest/test_C_API.cpp \ $$PWD/unittest/test_HOTP.cc } unix:!macx{ # SOURCES += $$PWD/hidapi/linux/hid.c LIBS += -lhidapi-libusb } macx{ SOURCES += $$PWD/hidapi/mac/hid.c LIBS+= -framework IOKit -framework CoreFoundation } win32 { SOURCES += $$PWD/hidapi/windows/hid.c LIBS += -lsetupapi } INCLUDEPATH = \ $$PWD/. \ $$PWD/hidapi/hidapi \ $$PWD/libnitrokey \ $$PWD/libnitrokey/hidapi \ $$PWD/unittest \ $$PWD/unittest/Catch/single_include #DEFINES = unix:!macx{ # Install rules for QMake (CMake is preffered though) udevrules.path = $$system(pkg-config --variable=udevdir udev) isEmpty(udevrules.path){ udevrules.path = "/lib/udev/" message("Could not detect path for udev rules - setting default: " $$udevrules.path) } udevrules.path = $$udevrules.path"/rules.d" udevrules.files = $$PWD/"data/41-nitrokey.rules" message ($$udevrules.files) INSTALLS +=udevrules headers.files = $$HEADERS headers.path = /usr/local/include/libnitrokey/ INSTALLS += headers libbin.path = /usr/local/lib INSTALLS += libbin } nitrokey-app-1.3.2/libnitrokey/libnitrokey/CommandFailedException.h0000644000175000017500000000466513275777076025142 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_COMMANDFAILEDEXCEPTION_H #define LIBNITROKEY_COMMANDFAILEDEXCEPTION_H #include #include #include "log.h" #include "command_id.h" using cs = nitrokey::proto::stick10::command_status; using cs2 = nitrokey::proto::stick20::device_status; class CommandFailedException : public std::exception { public: const uint8_t last_command_id; const uint8_t last_command_status; CommandFailedException(uint8_t last_command_id, uint8_t last_command_status) : last_command_id(last_command_id), last_command_status(last_command_status){ LOG(std::string("CommandFailedException, status: ")+ std::to_string(last_command_status), nitrokey::log::Loglevel::DEBUG); } virtual const char *what() const throw() { return "Command execution has failed on device"; } bool reason_timestamp_warning() const throw(){ return last_command_status == static_cast(cs::timestamp_warning); } bool reason_AES_not_initialized() const throw(){ return last_command_status == static_cast(cs::AES_dec_failed); } bool reason_not_authorized() const throw(){ return last_command_status == static_cast(cs::not_authorized); } bool reason_slot_not_programmed() const throw(){ return last_command_status == static_cast(cs::slot_not_programmed); } bool reason_wrong_password() const throw(){ return last_command_status == static_cast(cs::wrong_password); } bool reason_smartcard_busy() const throw(){ return last_command_status == static_cast(cs2::smartcard_error); } }; #endif //LIBNITROKEY_COMMANDFAILEDEXCEPTION_H nitrokey-app-1.3.2/libnitrokey/libnitrokey/DeviceCommunicationExceptions.h0000644000175000017500000000432013275777076026553 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_DEVICECOMMUNICATIONEXCEPTIONS_H #define LIBNITROKEY_DEVICECOMMUNICATIONEXCEPTIONS_H #include #include #include #include class DeviceCommunicationException: public std::runtime_error { std::string message; static std::atomic_int occurred; public: DeviceCommunicationException(std::string _msg): std::runtime_error(_msg), message(_msg){ ++occurred; } uint8_t getType() const {return 1;}; // virtual const char* what() const throw() override { // return message.c_str(); // } static bool has_occurred(){ return occurred > 0; }; static void reset_occurred_flag(){ occurred = 0; }; }; class DeviceNotConnected: public DeviceCommunicationException { public: DeviceNotConnected(std::string msg) : DeviceCommunicationException(msg){} uint8_t getType() const {return 2;}; }; class DeviceSendingFailure: public DeviceCommunicationException { public: DeviceSendingFailure(std::string msg) : DeviceCommunicationException(msg){} uint8_t getType() const {return 3;}; }; class DeviceReceivingFailure: public DeviceCommunicationException { public: DeviceReceivingFailure(std::string msg) : DeviceCommunicationException(msg){} uint8_t getType() const {return 4;}; }; class InvalidCRCReceived: public DeviceReceivingFailure { public: InvalidCRCReceived(std::string msg) : DeviceReceivingFailure(msg){} uint8_t getType() const {return 5;}; }; #endif //LIBNITROKEY_DEVICECOMMUNICATIONEXCEPTIONS_H nitrokey-app-1.3.2/libnitrokey/libnitrokey/LibraryException.h0000644000175000017500000000627113275777076024056 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_LIBRARYEXCEPTION_H #define LIBNITROKEY_LIBRARYEXCEPTION_H #include #include #include #include "log.h" class LibraryException: std::exception { public: virtual uint8_t exception_id()= 0; }; class TargetBufferSmallerThanSource: public LibraryException { public: virtual uint8_t exception_id() override { return 203; } public: size_t source_size; size_t target_size; TargetBufferSmallerThanSource( size_t source_size, size_t target_size ) : source_size(source_size), target_size(target_size) {} virtual const char *what() const throw() override { std::string s = " "; auto ts = [](size_t x){ return std::to_string(x); }; std::string msg = std::string("Target buffer size is smaller than source: [source size, buffer size]") +s+ ts(source_size) +s+ ts(target_size); return msg.c_str(); } }; class InvalidHexString : public LibraryException { public: virtual uint8_t exception_id() override { return 202; } public: uint8_t invalid_char; InvalidHexString (uint8_t invalid_char) : invalid_char( invalid_char) {} virtual const char *what() const throw() override { return "Invalid character in hex string"; } }; class InvalidSlotException : public LibraryException { public: virtual uint8_t exception_id() override { return 201; } public: uint8_t slot_selected; InvalidSlotException(uint8_t slot_selected) : slot_selected(slot_selected) {} virtual const char *what() const throw() override { return "Wrong slot selected"; } }; class TooLongStringException : public LibraryException { public: virtual uint8_t exception_id() override { return 200; } std::size_t size_source; std::size_t size_destination; std::string message; TooLongStringException(size_t size_source, size_t size_destination, const std::string &message = "") : size_source( size_source), size_destination(size_destination), message(message) { LOG(std::string("TooLongStringException, size diff: ")+ std::to_string(size_source-size_destination), nitrokey::log::Loglevel::DEBUG); } virtual const char *what() const throw() override { //TODO add sizes and message data to final message return "Too long string has been supplied as an argument"; } }; #endif //LIBNITROKEY_LIBRARYEXCEPTION_H nitrokey-app-1.3.2/libnitrokey/libnitrokey/LongOperationInProgressException.h0000644000175000017500000000316313275777076027243 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H #define LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H #include "CommandFailedException.h" class LongOperationInProgressException : public CommandFailedException { public: unsigned char progress_bar_value; LongOperationInProgressException( unsigned char _command_id, uint8_t last_command_status, unsigned char _progress_bar_value) : CommandFailedException(_command_id, last_command_status), progress_bar_value(_progress_bar_value){ LOG( std::string("LongOperationInProgressException, progress bar status: ")+ std::to_string(progress_bar_value), nitrokey::log::Loglevel::DEBUG); } virtual const char *what() const throw() { return "Device returned busy status with long operation in progress"; } }; #endif //LIBNITROKEY_LONGOPERATIONINPROGRESSEXCEPTION_H nitrokey-app-1.3.2/libnitrokey/libnitrokey/NitrokeyManager.h0000644000175000017500000002607713275777076023700 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_NITROKEYMANAGER_H #define LIBNITROKEY_NITROKEYMANAGER_H #include "device.h" #include "log.h" #include "device_proto.h" #include "stick10_commands.h" #include "stick10_commands_0.8.h" #include "stick20_commands.h" #include #include #include namespace nitrokey { using namespace nitrokey::device; using namespace std; using namespace nitrokey::proto::stick10; using namespace nitrokey::proto::stick20; using namespace nitrokey::proto; using namespace nitrokey::log; #ifdef __WIN32 char * strndup(const char* str, size_t maxlen); #endif class NitrokeyManager { public: static shared_ptr instance(); bool first_authenticate(const char *pin, const char *temporary_password); bool write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password); bool write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password); string get_HOTP_code(uint8_t slot_number, const char *user_temporary_password); string get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password); string get_TOTP_code(uint8_t slot_number, const char *user_temporary_password); stick10::ReadSlot::ResponsePayload get_TOTP_slot_data(const uint8_t slot_number); stick10::ReadSlot::ResponsePayload get_HOTP_slot_data(const uint8_t slot_number); bool set_time(uint64_t time); bool get_time(uint64_t time = 0); bool erase_totp_slot(uint8_t slot_number, const char *temporary_password); bool erase_hotp_slot(uint8_t slot_number, const char *temporary_password); std::vector list_devices(); std::vector list_devices_by_cpuID(); /** * Connect to the device using unique smartcard:datacard id. * Needs list_device_by_cpuID() run first * @param id Current ID of the target device * @return true on success, false on failure */ bool connect_with_ID(const std::string id); bool connect_with_path (std::string path); bool connect(const char *device_model); bool connect(device::DeviceModel device_model); bool connect(); bool disconnect(); bool is_connected() throw() ; bool could_current_device_be_enumerated(); bool set_default_commands_delay(int delay); DeviceModel get_connected_device_model() const; void set_debug(bool state); stick10::GetStatus::ResponsePayload get_status(); string get_status_as_string(); string get_serial_number(); const char * get_totp_slot_name(uint8_t slot_number); const char * get_hotp_slot_name(uint8_t slot_number); void change_user_PIN(const char *current_PIN, const char *new_PIN); void change_admin_PIN(const char *current_PIN, const char *new_PIN); void enable_password_safe(const char *user_pin); vector get_password_safe_slot_status(); uint8_t get_admin_retry_count(); uint8_t get_user_retry_count(); void lock_device(); const char *get_password_safe_slot_name(uint8_t slot_number); const char *get_password_safe_slot_password(uint8_t slot_number); const char *get_password_safe_slot_login(uint8_t slot_number); void write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, const char *slot_password); void erase_password_safe_slot(uint8_t slot_number); void user_authenticate(const char *user_password, const char *temporary_password); void factory_reset(const char *admin_password); void build_aes_key(const char *admin_password); void unlock_user_password(const char *admin_password, const char *new_user_password); void write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); vector read_config(); bool is_AES_supported(const char *user_password); void unlock_encrypted_volume(const char *user_password); void lock_encrypted_volume(); void unlock_hidden_volume(const char *hidden_volume_password); void lock_hidden_volume(); /** * Sets unencrypted volume read-only. * Works until v0.48 (incl. v0.50), where User PIN was sufficient * Does nothing otherwise. * @param user_pin User PIN */ void set_unencrypted_read_only(const char *user_pin); /** * Sets unencrypted volume read-only. * Works from v0.49 (except v0.50) accepts Admin PIN * Does nothing otherwise. * @param admin_pin Admin PIN */ void set_unencrypted_read_only_admin(const char *admin_pin); /** * Sets unencrypted volume read-write. * Works until v0.48 (incl. v0.50), where User PIN was sufficient * Does nothing otherwise. * @param user_pin User PIN */ void set_unencrypted_read_write(const char *user_pin); /** * Sets unencrypted volume read-write. * Works from v0.49 (except v0.50) accepts Admin PIN * Does nothing otherwise. * @param admin_pin Admin PIN */ void set_unencrypted_read_write_admin(const char *admin_pin); void export_firmware(const char *admin_pin); void enable_firmware_update(const char *firmware_pin); void clear_new_sd_card_warning(const char *admin_pin); void fill_SD_card_with_random_data(const char *admin_pin); uint8_t get_SD_card_size(); void change_update_password(const char *current_update_password, const char *new_update_password); void create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, const char *hidden_volume_password); void send_startup(uint64_t seconds_from_epoch); const char * get_status_storage_as_string(); stick20::DeviceConfigurationResponsePacket::ResponsePayload get_status_storage(); const char *get_SD_usage_data_as_string(); std::pair get_SD_usage_data(); int get_progress_bar_value(); ~NitrokeyManager(); bool is_authorization_command_supported(); bool is_320_OTP_secret_supported(); template void authorize_packet(T &package, const char *admin_temporary_password, shared_ptr device); int get_minor_firmware_version(); explicit NitrokeyManager(); void set_log_function(std::function log_function); private: static shared_ptr _instance; std::shared_ptr device; std::string current_device_id; public: const string get_current_device_id() const; private: std::unordered_map > connected_devices; std::unordered_map > connected_devices_byID; stick10::ReadSlot::ResponsePayload get_OTP_slot_data(const uint8_t slot_number); bool is_valid_hotp_slot_number(uint8_t slot_number) const; bool is_valid_totp_slot_number(uint8_t slot_number) const; bool is_valid_password_safe_slot_number(uint8_t slot_number) const; uint8_t get_internal_slot_number_for_hotp(uint8_t slot_number) const; uint8_t get_internal_slot_number_for_totp(uint8_t slot_number) const; bool erase_slot(uint8_t slot_number, const char *temporary_password); const char * get_slot_name(uint8_t slot_number); template void change_PIN_general(const char *current_PIN, const char *new_PIN); void write_HOTP_slot_authorize(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password); void write_TOTP_slot_authorize(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password); void write_OTP_slot_no_authorize(uint8_t internal_slot_number, const char *slot_name, const char *secret, uint64_t counter_or_interval, bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, const char *temporary_password) const; bool _disconnect_no_lock(); public: bool set_current_device_speed(int retry_delay, int send_receive_delay); void set_loglevel(Loglevel loglevel); void set_loglevel(int loglevel); /** * Sets encrypted volume read-only. * Supported from future versions of Storage. * @param admin_pin Admin PIN */ void set_encrypted_volume_read_only(const char *admin_pin); /** * Sets encrypted volume read-write. * Supported from future versions of Storage. * @param admin_pin Admin PIN */ void set_encrypted_volume_read_write(const char *admin_pin); int get_major_firmware_version(); bool is_smartcard_in_use(); /** * Function to determine unencrypted volume PIN type * @param minor_firmware_version * @return Returns true, if set unencrypted volume ro/rw pin type is User, false otherwise. */ bool set_unencrypted_volume_rorw_pin_type_user(); }; } #endif //LIBNITROKEY_NITROKEYMANAGER_H nitrokey-app-1.3.2/libnitrokey/libnitrokey/command.h0000644000175000017500000000714613275777076022213 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef COMMAND_H #define COMMAND_H #include #include "command_id.h" #include "cxx_semantics.h" #define print_to_ss(x) ( ss << " " << (#x) <<":\t" << (x) << std::endl ); #ifdef LOG_VOLATILE_DATA #define print_to_ss_volatile(x) print_to_ss(x); #else #define print_to_ss_volatile(x) ( ss << " " << (#x) <<":\t" << "***********" << std::endl ); #endif #define hexdump_to_ss(x) (ss << #x":\n"\ << ::nitrokey::misc::hexdump((const uint8_t *) (&x), sizeof x, false)); namespace nitrokey { namespace proto { template class Command : semantics::non_constructible { public: constexpr static CommandID command_id() { return cmd_id; } template std::string dissect(const T &) { return std::string("Payload dissection is unavailable"); } }; namespace stick20{ enum class PasswordKind : uint8_t { User = 'P', Admin = 'A', AdminPrefixed }; template class PasswordCommand : public Command { constexpr static CommandID _command_id() { return cmd_id; } public: struct CommandPayload { uint8_t kind; uint8_t password[password_length]; std::string dissect() const { std::stringstream ss; print_to_ss( kind ); print_to_ss_volatile(password); return ss.str(); } void set_kind_admin() { kind = (uint8_t) 'A'; } void set_kind_admin_prefixed() { kind = (uint8_t) 'P'; } void set_kind_user() { kind = (uint8_t) 'P'; } void set_defaults(){ set_kind(Tpassword_kind); } void set_kind(PasswordKind password_kind){ switch (password_kind){ case PasswordKind::Admin: set_kind_admin(); break; case PasswordKind::User: set_kind_user(); break; case PasswordKind::AdminPrefixed: set_kind_admin_prefixed(); break; } }; } __packed; //typedef Transaction::command_id(), struct CommandPayload, struct EmptyPayload> // CommandTransaction; using CommandTransaction = Transaction; //using CommandTransaction = Transaction<_command_id(), CommandPayload, EmptyPayload>; }; } } } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/command_id.h0000644000175000017500000001031513275777076022657 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef COMMAND_ID_H #define COMMAND_ID_H #include namespace nitrokey { namespace proto { namespace stick20 { enum class device_status : uint8_t { idle = 0, ok, busy, wrong_password, busy_progressbar, password_matrix_ready, no_user_password_unlock, // FIXME: translate on receive to command status error (fix in firmware?) smartcard_error, security_bit_active }; const int CMD_START_VALUE = 0x20; const int CMD_END_VALUE = 0x60; } namespace stick10 { enum class command_status : uint8_t { ok = 0, wrong_CRC, wrong_slot, slot_not_programmed, wrong_password = 4, not_authorized, timestamp_warning, no_name_error, not_supported, unknown_command, AES_dec_failed }; enum class device_status : uint8_t { ok = 0, busy = 1, error, received_report, }; } enum class CommandID : uint8_t { GET_STATUS = 0x00, WRITE_TO_SLOT = 0x01, READ_SLOT_NAME = 0x02, READ_SLOT = 0x03, GET_CODE = 0x04, WRITE_CONFIG = 0x05, ERASE_SLOT = 0x06, FIRST_AUTHENTICATE = 0x07, AUTHORIZE = 0x08, GET_PASSWORD_RETRY_COUNT = 0x09, CLEAR_WARNING = 0x0A, SET_TIME = 0x0B, TEST_COUNTER = 0x0C, TEST_TIME = 0x0D, USER_AUTHENTICATE = 0x0E, GET_USER_PASSWORD_RETRY_COUNT = 0x0F, USER_AUTHORIZE = 0x10, UNLOCK_USER_PASSWORD = 0x11, LOCK_DEVICE = 0x12, FACTORY_RESET = 0x13, CHANGE_USER_PIN = 0x14, CHANGE_ADMIN_PIN = 0x15, WRITE_TO_SLOT_2 = 0x16, SEND_OTP_DATA = 0x17, ENABLE_CRYPTED_PARI = 0x20, DISABLE_CRYPTED_PARI = 0x20 + 1, ENABLE_HIDDEN_CRYPTED_PARI = 0x20 + 2, DISABLE_HIDDEN_CRYPTED_PARI = 0x20 + 3, ENABLE_FIRMWARE_UPDATE = 0x20 + 4, //enables update mode EXPORT_FIRMWARE_TO_FILE = 0x20 + 5, GENERATE_NEW_KEYS = 0x20 + 6, FILL_SD_CARD_WITH_RANDOM_CHARS = 0x20 + 7, WRITE_STATUS_DATA = 0x20 + 8, //@unused ENABLE_READONLY_UNCRYPTED_LUN = 0x20 + 9, ENABLE_READWRITE_UNCRYPTED_LUN = 0x20 + 10, SEND_PASSWORD_MATRIX = 0x20 + 11, //@unused SEND_PASSWORD_MATRIX_PINDATA = 0x20 + 12, //@unused SEND_PASSWORD_MATRIX_SETUP = 0x20 + 13, //@unused GET_DEVICE_STATUS = 0x20 + 14, SEND_DEVICE_STATUS = 0x20 + 15, SEND_HIDDEN_VOLUME_PASSWORD = 0x20 + 16, //@unused SEND_HIDDEN_VOLUME_SETUP = 0x20 + 17, SEND_PASSWORD = 0x20 + 18, SEND_NEW_PASSWORD = 0x20 + 19, CLEAR_NEW_SD_CARD_FOUND = 0x20 + 20, SEND_STARTUP = 0x20 + 21, SEND_CLEAR_STICK_KEYS_NOT_INITIATED = 0x20 + 22, SEND_LOCK_STICK_HARDWARE = 0x20 + 23, //locks firmware upgrade PRODUCTION_TEST = 0x20 + 24, SEND_DEBUG_DATA = 0x20 + 25, //@unused CHANGE_UPDATE_PIN = 0x20 + 26, //added in v0.48.5 ENABLE_ADMIN_READONLY_UNCRYPTED_LUN = 0x20 + 28, ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN = 0x20 + 29, ENABLE_ADMIN_READONLY_ENCRYPTED_LUN = 0x20 + 30, ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN = 0x20 + 31, CHECK_SMARTCARD_USAGE = 0x20 + 32, GET_PW_SAFE_SLOT_STATUS = 0x60, GET_PW_SAFE_SLOT_NAME = 0x61, GET_PW_SAFE_SLOT_PASSWORD = 0x62, GET_PW_SAFE_SLOT_LOGINNAME = 0x63, SET_PW_SAFE_SLOT_DATA_1 = 0x64, SET_PW_SAFE_SLOT_DATA_2 = 0x65, PW_SAFE_ERASE_SLOT = 0x66, PW_SAFE_ENABLE = 0x67, PW_SAFE_INIT_KEY = 0x68, //@unused PW_SAFE_SEND_DATA = 0x69, //@unused SD_CARD_HIGH_WATERMARK = 0x70, DETECT_SC_AES = 0x6a, NEW_AES_KEY = 0x6b }; const char *commandid_to_string(CommandID id); } } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/cxx_semantics.h0000644000175000017500000000214713275777076023441 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef CXX_SEMANTICS_H #define CXX_SEMANTICS_H #ifndef _MSC_VER #define __packed __attribute__((__packed__)) #else #define __packed #endif #ifdef _MSC_VER #define strdup _strdup #endif /* * There's no need to include Boost for a simple subset this project needs. */ namespace semantics { class non_constructible { non_constructible() {} }; } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/device.h0000644000175000017500000001056713275777076022035 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef DEVICE_H #define DEVICE_H #include #include "hidapi/hidapi.h" #include #include #include #define HID_REPORT_SIZE 65 #include namespace nitrokey { namespace device { using namespace std::chrono_literals; using std::chrono::milliseconds; struct EnumClassHash { template std::size_t operator()(T t) const { return static_cast(t); } }; enum class DeviceModel{ PRO, STORAGE }; #include class Device { public: struct ErrorCounters{ using cnt = std::atomic_int; cnt wrong_CRC; cnt CRC_other_than_awaited; cnt busy; cnt total_retries; cnt sending_error; cnt receiving_error; cnt total_comm_runs; cnt successful_storage_commands; cnt command_successful_recv; cnt recv_executed; cnt sends_executed; cnt busy_progressbar; cnt command_result_not_equal_0_recv; cnt communication_successful; cnt low_level_reconnect; std::string get_as_string(); } m_counters = {}; Device(const uint16_t vid, const uint16_t pid, const DeviceModel model, const milliseconds send_receive_delay, const int retry_receiving_count, const milliseconds retry_timeout); virtual ~Device(); // lack of device is not actually an error, // so it doesn't throw virtual bool connect(); virtual bool disconnect(); /* * Sends packet of HID_REPORT_SIZE. */ virtual int send(const void *packet); /* * Gets packet of HID_REPORT_SIZE. * Can sleep. See below. */ virtual int recv(void *packet); /*** * Returns true if some device is visible by OS with given VID and PID * whether the device is connected through HID API or not. * @return true if visible by OS */ bool could_be_enumerated(); std::vector enumerate(); void show_stats(); // ErrorCounters get_stats(){ return m_counters; } int get_retry_receiving_count() const { return m_retry_receiving_count; }; int get_retry_sending_count() const { return m_retry_sending_count; }; std::chrono::milliseconds get_retry_timeout() const { return m_retry_timeout; }; std::chrono::milliseconds get_send_receive_delay() const {return m_send_receive_delay;} int get_last_command_status() {int a = std::atomic_exchange(&last_command_status, static_cast(0)); return a;}; void set_last_command_status(uint8_t _err) { last_command_status = _err;} ; bool last_command_sucessfull() const {return last_command_status == 0;}; DeviceModel get_device_model() const {return m_model;} void set_receiving_delay(std::chrono::milliseconds delay); void set_retry_delay(std::chrono::milliseconds delay); static void set_default_device_speed(int delay); void setDefaultDelay(); void set_path(const std::string path); private: std::atomic last_command_status; void _reconnect(); bool _connect(); bool _disconnect(); protected: const uint16_t m_vid; const uint16_t m_pid; const DeviceModel m_model; /* * While the project uses Signal11 portable HIDAPI * library, there's no way of doing it asynchronously, * hence polling. */ const int m_retry_sending_count; const int m_retry_receiving_count; std::chrono::milliseconds m_retry_timeout; std::chrono::milliseconds m_send_receive_delay; std::atomicmp_devhandle; std::string m_path; static std::atomic_int instances_count; static std::chrono::milliseconds default_delay ; }; class Stick10 : public Device { public: Stick10(); }; class Stick20 : public Device { public: Stick20(); }; } } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/device_proto.h0000644000175000017500000005222713275777076023257 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef DEVICE_PROTO_H #define DEVICE_PROTO_H #include #include #include #include #include // a local version for compatibility with Windows #include #include "cxx_semantics.h" #include "device.h" #include "misc.h" #include "log.h" #include "command_id.h" #include "dissect.h" #include "CommandFailedException.h" #include "LongOperationInProgressException.h" #define STICK20_UPDATE_MODE_VID 0x03EB #define STICK20_UPDATE_MODE_PID 0x2FF1 #define PAYLOAD_SIZE 53 #define PWS_SLOT_COUNT 16 #define PWS_SLOTNAME_LENGTH 11 #define PWS_PASSWORD_LENGTH 20 #define PWS_LOGINNAME_LENGTH 32 #define PWS_SEND_PASSWORD 0 #define PWS_SEND_LOGINNAME 1 #define PWS_SEND_TAB 2 #define PWS_SEND_CR 3 #include #include "DeviceCommunicationExceptions.h" #define bzero(b,len) (memset((b), '\0', (len)), (void) 0) namespace nitrokey { namespace proto { extern std::mutex send_receive_mtx; /* * POD types for HID proto commands * Instances are meant to be __packed. * * TODO (future) support for Big Endian */ #pragma pack (push,1) /* * Every packet is a USB HID report (check USB spec) */ template struct HIDReport { uint8_t _zero; CommandID command_id; // uint8_t union { uint8_t _padding[HID_REPORT_SIZE - 6]; Payload payload; } __packed; uint32_t crc; // POD types can't have non-default constructors // used in Transaction<>::run() void initialize() { bzero(this, sizeof *this); command_id = cmd_id; } uint32_t calculate_CRC() const { // w/o leading zero, a part of each HID packet // w/o 4-byte crc return misc::stm_crc32((const uint8_t *) (this) + 1, (size_t) (HID_REPORT_SIZE - 5)); } void update_CRC() { crc = calculate_CRC(); } bool isCRCcorrect() const { return crc == calculate_CRC(); } bool isValid() const { return true; // return !_zero && payload.isValid() && isCRCcorrect(); } operator std::string() const { // Packet type is known upfront in normal operation. // Can't be used to dissect random packets. return QueryDissector::dissect(*this); } } __packed; /* * Response payload (the parametrized type inside struct HIDReport) * * command_id member in incoming HIDReport structure carries the command * type last used. */ namespace DeviceResponseConstants{ //magic numbers from firmware static constexpr auto storage_status_absolute_address = 21; static constexpr auto storage_data_absolute_address = storage_status_absolute_address + 5; static constexpr auto header_size = 8; //from _zero to last_command_status inclusive static constexpr auto footer_size = 4; //crc static constexpr auto wrapping_size = header_size + footer_size; } template struct DeviceResponse { static constexpr auto storage_status_padding_size = DeviceResponseConstants::storage_status_absolute_address - DeviceResponseConstants::header_size; uint8_t _zero; uint8_t device_status; uint8_t command_id; // originally last_command_type uint32_t last_command_crc; uint8_t last_command_status; union { uint8_t _padding[HID_REPORT_SIZE - DeviceResponseConstants::wrapping_size]; ResponsePayload payload; struct { uint8_t _storage_status_padding[storage_status_padding_size]; uint8_t command_counter; uint8_t command_id; uint8_t device_status; //@see stick20::device_status uint8_t progress_bar_value; } __packed storage_status; } __packed; uint32_t crc; void initialize() { bzero(this, sizeof *this); } uint32_t calculate_CRC() const { // w/o leading zero, a part of each HID packet // w/o 4-byte crc return misc::stm_crc32((const uint8_t *) (this) + 1, (size_t) (HID_REPORT_SIZE - 5)); } void update_CRC() { crc = calculate_CRC(); } bool isCRCcorrect() const { return crc == calculate_CRC(); } bool isValid() const { // return !_zero && payload.isValid() && isCRCcorrect() && // command_id == (uint8_t)(cmd_id); return crc != 0; } operator std::string() const { return ResponseDissector::dissect(*this); } } __packed; struct EmptyPayload { bool isValid() const { return true; } std::string dissect() const { return std::string("Empty Payload."); } } __packed; template class ClearingProxy { public: ClearingProxy(command_packet &p) { packet = p; bzero(&p, sizeof(p)); } ~ClearingProxy() { bzero(&packet, sizeof(packet)); } response_payload &data() { return packet.payload; } command_packet packet; }; template class Transaction : semantics::non_constructible { public: // Types declared in command class scope can't be reached from there. typedef command_payload CommandPayload; typedef response_payload ResponsePayload; typedef struct HIDReport OutgoingPacket; typedef struct DeviceResponse ResponsePacket; #pragma pack (pop) static_assert(std::is_pod::value, "outgoingpacket must be a pod type"); static_assert(std::is_pod::value, "ResponsePacket must be a POD type"); static_assert(sizeof(OutgoingPacket) == HID_REPORT_SIZE, "OutgoingPacket type is not the right size"); static_assert(sizeof(ResponsePacket) == HID_REPORT_SIZE, "ResponsePacket type is not the right size"); static uint32_t getCRC( const command_payload &payload) { OutgoingPacket outp; outp.initialize(); outp.payload = payload; outp.update_CRC(); return outp.crc; } template static void clear_packet(T &st) { bzero(&st, sizeof(st)); } static ClearingProxy run(std::shared_ptr dev, const command_payload &payload) { using namespace ::nitrokey::device; using namespace ::nitrokey::log; using namespace std::chrono_literals; std::lock_guard guard(send_receive_mtx); LOG(__FUNCTION__, Loglevel::DEBUG_L2); if (dev == nullptr){ LOG(std::string("Throw: Device not initialized"), Loglevel::DEBUG_L1); throw DeviceNotConnected("Device not initialized"); } dev->m_counters.total_comm_runs++; int status; OutgoingPacket outp; ResponsePacket resp; // POD types can't have non-default constructors outp.initialize(); resp.initialize(); outp.payload = payload; outp.update_CRC(); LOG("-------------------", Loglevel::DEBUG); LOG("Outgoing HID packet:", Loglevel::DEBUG); LOG(static_cast(outp), Loglevel::DEBUG); LOG(std::string("=> ") + std::string(commandid_to_string(static_cast(outp.command_id))), Loglevel::DEBUG_L1); if (!outp.isValid()) { LOG(std::string("Throw: Invalid outgoing packet"), Loglevel::DEBUG_L1); throw DeviceSendingFailure("Invalid outgoing packet"); } bool successful_communication = false; int receiving_retry_counter = 0; int sending_retry_counter = dev->get_retry_sending_count(); while (sending_retry_counter-- > 0) { dev->m_counters.sends_executed++; status = dev->send(&outp); if (status <= 0){ //FIXME early disconnection not yet working properly // LOG("Encountered communication error, disconnecting device", Loglevel::DEBUG_L2); // dev->disconnect(); dev->m_counters.sending_error++; LOG(std::string("Throw: Device error while sending command "), Loglevel::DEBUG_L1); throw DeviceSendingFailure( std::string("Device error while sending command ") + std::to_string(status)); } std::this_thread::sleep_for(dev->get_send_receive_delay()); // FIXME make checks done in device:recv here receiving_retry_counter = dev->get_retry_receiving_count(); int busy_counter = 0; auto retry_timeout = dev->get_retry_timeout(); while (receiving_retry_counter-- > 0) { dev->m_counters.recv_executed++; status = dev->recv(&resp); if (dev->get_device_model() == DeviceModel::STORAGE && resp.command_id >= stick20::CMD_START_VALUE && resp.command_id < stick20::CMD_END_VALUE ) { LOG(std::string("Detected storage device cmd, status: ") + std::to_string(resp.storage_status.device_status), Loglevel::DEBUG_L2); resp.last_command_status = static_cast(stick10::command_status::ok); switch (static_cast(resp.storage_status.device_status)) { case stick20::device_status::idle : case stick20::device_status::ok: resp.device_status = static_cast(stick10::device_status::ok); break; case stick20::device_status::busy: case stick20::device_status::busy_progressbar: //TODO this will be modified later for getting progressbar status resp.device_status = static_cast(stick10::device_status::busy); break; case stick20::device_status::wrong_password: resp.last_command_status = static_cast(stick10::command_status::wrong_password); resp.device_status = static_cast(stick10::device_status::ok); break; case stick20::device_status::no_user_password_unlock: resp.last_command_status = static_cast(stick10::command_status::AES_dec_failed); resp.device_status = static_cast(stick10::device_status::ok); break; default: LOG(std::string("Unknown storage device status, cannot translate: ") + std::to_string(resp.storage_status.device_status), Loglevel::DEBUG); resp.device_status = resp.storage_status.device_status; break; }; } //Some of the commands return wrong CRC, for now skip checking it (TODO list and report) //if (resp.device_status == 0 && resp.last_command_crc == outp.crc && resp.isCRCcorrect()) break; auto CRC_equal_awaited = true; // resp.last_command_crc == outp.crc; if (resp.device_status == static_cast(stick10::device_status::ok) && CRC_equal_awaited && resp.isValid()){ successful_communication = true; break; } if (resp.device_status == static_cast(stick10::device_status::busy)) { dev->m_counters.busy++; if (busy_counter++<10) { receiving_retry_counter++; LOG("Status busy, not decreasing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2); } else { retry_timeout *= 2; retry_timeout = std::min(retry_timeout, 300ms); busy_counter = 0; LOG("Status busy, decreasing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter) + ", current delay:" + std::to_string(retry_timeout.count()), Loglevel::DEBUG); LOG(std::string("Busy retry: status ") + std::to_string(resp.storage_status.device_status) + ", " + std::to_string(retry_timeout.count()) + "ms, counter " + std::to_string(receiving_retry_counter) + ", progress: " + std::to_string(resp.storage_status.progress_bar_value) , Loglevel::DEBUG_L1); } } if (resp.device_status == static_cast(stick10::device_status::busy) && static_cast(resp.storage_status.device_status) == stick20::device_status::busy_progressbar){ successful_communication = true; break; } LOG(std::string("Retry status - dev status, awaited cmd crc, correct packet CRC: ") + std::to_string(resp.device_status) + " " + std::to_string(CRC_equal_awaited) + " " + std::to_string(resp.isCRCcorrect()), Loglevel::DEBUG_L2); if (!resp.isCRCcorrect()) dev->m_counters.wrong_CRC++; if (!CRC_equal_awaited) dev->m_counters.CRC_other_than_awaited++; LOG( "Device is not ready or received packet's last CRC is not equal to sent CRC packet, retrying...", Loglevel::DEBUG_L2); LOG("Invalid incoming HID packet:", Loglevel::DEBUG_L2); LOG(static_cast(resp), Loglevel::DEBUG_L2); dev->m_counters.total_retries++; LOG(".", Loglevel::DEBUG_L1); std::this_thread::sleep_for(retry_timeout); continue; } if (successful_communication) break; LOG(std::string("Resending (outer loop) "), Loglevel::DEBUG_L2); LOG(std::string("sending_retry_counter count: ") + std::to_string(sending_retry_counter), Loglevel::DEBUG); } if(resp.last_command_crc != outp.crc){ LOG(std::string("Accepting response with CRC other than expected ") + "Command ID: " + std::to_string(resp.command_id) + " " + commandid_to_string(static_cast(resp.command_id)) + " " + "Reported by response and expected: " + std::to_string(resp.last_command_crc) + "!=" + std::to_string(outp.crc), Loglevel::WARNING ); } dev->set_last_command_status(resp.last_command_status); // FIXME should be handled on device.recv clear_packet(outp); if (status <= 0) { dev->m_counters.receiving_error++; LOG(std::string("Throw: Device error while executing command "), Loglevel::DEBUG_L1); throw DeviceReceivingFailure( //FIXME replace with CriticalErrorException std::string("Device error while executing command ") + std::to_string(status)); } LOG(std::string("<= ") + std::string( commandid_to_string(static_cast(resp.command_id)) + std::string(" ") + std::to_string(resp.device_status) + std::string(" ") + std::to_string(resp.storage_status.device_status) // + std::to_string( status_translate_command(resp.storage_status.device_status)) ), Loglevel::DEBUG_L1); LOG("Incoming HID packet:", Loglevel::DEBUG); LOG(static_cast(resp), Loglevel::DEBUG); if (dev->get_retry_receiving_count() - receiving_retry_counter > 2) { LOG(std::string("Packet received with receiving_retry_counter count: ") + std::to_string(receiving_retry_counter), Loglevel::DEBUG_L1); } if (resp.device_status == static_cast(stick10::device_status::busy) && static_cast(resp.storage_status.device_status) == stick20::device_status::busy_progressbar){ dev->m_counters.busy_progressbar++; LOG(std::string("Throw: Long operation in progress exception"), Loglevel::DEBUG_L1); throw LongOperationInProgressException( resp.command_id, resp.device_status, resp.storage_status.progress_bar_value); } if (!resp.isValid()) { LOG(std::string("Throw: Invalid incoming packet"), Loglevel::DEBUG_L1); throw InvalidCRCReceived("Invalid incoming packet"); } if (receiving_retry_counter <= 0){ LOG(std::string("Throw: \"Maximum receiving_retry_counter count reached for receiving response from the device!\"" + std::to_string(receiving_retry_counter)), Loglevel::DEBUG_L1); throw DeviceReceivingFailure( "Maximum receiving_retry_counter count reached for receiving response from the device!"); } dev->m_counters.communication_successful++; if (resp.last_command_status != static_cast(stick10::command_status::ok)){ dev->m_counters.command_result_not_equal_0_recv++; LOG(std::string("Throw: CommandFailedException ") + std::to_string(resp.last_command_status), Loglevel::DEBUG_L1); throw CommandFailedException(resp.command_id, resp.last_command_status); } dev->m_counters.command_successful_recv++; if (dev->get_device_model() == DeviceModel::STORAGE && resp.command_id >= stick20::CMD_START_VALUE && resp.command_id < stick20::CMD_END_VALUE ) { dev->m_counters.successful_storage_commands++; } if (!resp.isCRCcorrect()) LOG(std::string("Accepting response from device with invalid CRC. ") + "Command ID: " + std::to_string(resp.command_id) + " " + commandid_to_string(static_cast(resp.command_id)) + " " + "Reported and calculated: " + std::to_string(resp.crc) + "!=" + std::to_string(resp.calculate_CRC()), Loglevel::WARNING ); // See: DeviceResponse return resp; } static ClearingProxy run(std::shared_ptr dev) { command_payload empty_payload; return run(dev, empty_payload); } }; } } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/dissect.h0000644000175000017500000001140713275777076022226 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ /* * Protocol packet dissection */ #ifndef DISSECT_H #define DISSECT_H #include #include #include #include "misc.h" #include "cxx_semantics.h" #include "command_id.h" #include "device_proto.h" namespace nitrokey { namespace proto { template class QueryDissector : semantics::non_constructible { public: static std::string dissect(const HIDPacket &pod) { std::stringstream out; #ifdef LOG_VOLATILE_DATA out << "Raw HID packet:" << std::endl; out << ::nitrokey::misc::hexdump((const uint8_t *)(&pod), sizeof pod); #endif out << "Contents:" << std::endl; out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id)) << std::endl; out << "CRC:\t" << std::hex << std::setw(2) << std::setfill('0') << pod.crc << std::endl; out << "Payload:" << std::endl; out << pod.payload.dissect(); return out.str(); } }; template class ResponseDissector : semantics::non_constructible { public: static std::string status_translate_device(int status){ auto enum_status = static_cast(status); switch (enum_status){ case stick10::device_status::ok: return "OK"; case stick10::device_status::busy: return "BUSY"; case stick10::device_status::error: return "ERROR"; case stick10::device_status::received_report: return "RECEIVED_REPORT"; } return std::string("UNKNOWN: ") + std::to_string(status); } static std::string to_upper(std::string str){ for (auto & c: str) c = toupper(c); return str; } static std::string status_translate_command(int status){ auto enum_status = static_cast(status); switch (enum_status) { #define p(X) case X: return to_upper(std::string(#X)); p(stick10::command_status::ok) p(stick10::command_status::wrong_CRC) p(stick10::command_status::wrong_slot) p(stick10::command_status::slot_not_programmed) p(stick10::command_status::wrong_password) p(stick10::command_status::not_authorized) p(stick10::command_status::timestamp_warning) p(stick10::command_status::no_name_error) p(stick10::command_status::not_supported) p(stick10::command_status::unknown_command) p(stick10::command_status::AES_dec_failed) #undef p } return std::string("UNKNOWN: ") + std::to_string(status); } static std::string dissect(const HIDPacket &pod) { std::stringstream out; // FIXME use values from firmware (possibly generate separate // header automatically) #ifdef LOG_VOLATILE_DATA out << "Raw HID packet:" << std::endl; out << ::nitrokey::misc::hexdump((const uint8_t *)(&pod), sizeof pod); #endif out << "Device status:\t" << pod.device_status + 0 << " " << status_translate_device(pod.device_status) << std::endl; out << "Command ID:\t" << commandid_to_string((CommandID)(pod.command_id)) << " hex: " << std::hex << (int)pod.command_id << std::endl; out << "Last command CRC:\t" << std::hex << std::setw(2) << std::setfill('0') << pod.last_command_crc << std::endl; out << "Last command status:\t" << pod.last_command_status + 0 << " " << status_translate_command(pod.last_command_status) << std::endl; out << "CRC:\t" << std::hex << std::setw(2) << std::setfill('0') << pod.crc << std::endl; if((int)pod.command_id == pod.storage_status.command_id){ out << "Storage stick status (where applicable):" << std::endl; #define d(x) out << " "#x": \t"<< std::hex << std::setw(2) \ << std::setfill('0')<< static_cast(x) << std::endl; d(pod.storage_status.command_counter); d(pod.storage_status.command_id); d(pod.storage_status.device_status); d(pod.storage_status.progress_bar_value); #undef d } out << "Payload:" << std::endl; out << pod.payload.dissect(); return out.str(); } }; } } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/hidapi/hidapi.h0000644000175000017500000003305613275777076023270 0ustar janjan00000000000000/******************************************************* HIDAPI - Multi-Platform library for communication with HID devices. Alan Ott Signal 11 Software 8/22/2009 Copyright 2009, All Rights Reserved. At the discretion of the user of this library, this software may be licensed under the terms of the GNU General Public License v3, a BSD-Style license, or the original HIDAPI license as outlined in the LICENSE.txt, LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt files located at the root of the source distribution. These files may also be found in the public source code repository located at: http://github.com/signal11/hidapi . ********************************************************/ /** @file * @defgroup API hidapi API */ #ifndef HIDAPI_H__ #define HIDAPI_H__ #include #ifdef _WIN32 #define HID_API_EXPORT __declspec(dllexport) #define HID_API_CALL #else #define HID_API_EXPORT /**< API export macro */ #define HID_API_CALL /**< API call macro */ #endif #define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ #ifdef __cplusplus extern "C" { #endif struct hid_device_; typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ /** hidapi info structure */ struct hid_device_info { /** Platform-specific device path */ char *path; /** Device Vendor ID */ unsigned short vendor_id; /** Device Product ID */ unsigned short product_id; /** Serial Number */ wchar_t *serial_number; /** Device Release Number in binary-coded decimal, also known as Device Version Number */ unsigned short release_number; /** Manufacturer String */ wchar_t *manufacturer_string; /** Product string */ wchar_t *product_string; /** Usage Page for this Device/Interface (Windows/Mac only). */ unsigned short usage_page; /** Usage for this Device/Interface (Windows/Mac only).*/ unsigned short usage; /** The USB interface which this logical device represents. Valid on both Linux implementations in all cases, and valid on the Windows implementation only if the device contains more than one interface. */ int interface_number; /** Pointer to the next device */ struct hid_device_info *next; }; /** @brief Initialize the HIDAPI library. This function initializes the HIDAPI library. Calling it is not strictly necessary, as it will be called automatically by hid_enumerate() and any of the hid_open_*() functions if it is needed. This function should be called at the beginning of execution however, if there is a chance of HIDAPI handles being opened by different threads simultaneously. @ingroup API @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT HID_API_CALL hid_init(void); /** @brief Finalize the HIDAPI library. This function frees all of the static data associated with HIDAPI. It should be called at the end of execution to avoid memory leaks. @ingroup API @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT HID_API_CALL hid_exit(void); /** @brief Enumerate the HID Devices. This function returns a linked list of all the HID devices attached to the system which match vendor_id and product_id. If @p vendor_id is set to 0 then any vendor matches. If @p product_id is set to 0 then any product matches. If @p vendor_id and @p product_id are both set to 0, then all HID devices will be returned. @ingroup API @param vendor_id The Vendor ID (VID) of the types of device to open. @param product_id The Product ID (PID) of the types of device to open. @returns This function returns a pointer to a linked list of type struct #hid_device, containing information about the HID devices attached to the system, or NULL in the case of failure. Free this linked list by calling hid_free_enumeration(). */ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); /** @brief Free an enumeration Linked List This function frees a linked list created by hid_enumerate(). @ingroup API @param devs Pointer to a list of struct_device returned from hid_enumerate(). */ void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); /** @brief Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally a serial number. If @p serial_number is NULL, the first device with the specified VID and PID is opened. @ingroup API @param vendor_id The Vendor ID (VID) of the device to open. @param product_id The Product ID (PID) of the device to open. @param serial_number The Serial Number of the device to open (Optionally NULL). @returns This function returns a pointer to a #hid_device object on success or NULL on failure. */ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); /** @brief Open a HID device by its path name. The path name be determined by calling hid_enumerate(), or a platform-specific path name can be used (eg: /dev/hidraw0 on Linux). @ingroup API @param path The path name of the device to open @returns This function returns a pointer to a #hid_device object on success or NULL on failure. */ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); /** @brief Write an Output report to a HID device. The first byte of @p data[] must contain the Report ID. For devices which only support a single report, this must be set to 0x0. The remaining bytes contain the report data. Since the Report ID is mandatory, calls to hid_write() will always contain one more byte than the report contains. For example, if a hid report is 16 bytes long, 17 bytes must be passed to hid_write(), the Report ID (or 0x0, for devices with a single report), followed by the report data (16 bytes). In this example, the length passed in would be 17. hid_write() will send the data on the first OUT endpoint, if one exists. If it does not, it will send the data through the Control Endpoint (Endpoint 0). @ingroup API @param device A device handle returned from hid_open(). @param data The data to send, including the report number as the first byte. @param length The length in bytes of the data to send. @returns This function returns the actual number of bytes written and -1 on error. */ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); /** @brief Read an Input report from a HID device with timeout. Input reports are returned to the host through the INTERRUPT IN endpoint. The first byte will contain the Report number if the device uses numbered reports. @ingroup API @param device A device handle returned from hid_open(). @param data A buffer to put the read data into. @param length The number of bytes to read. For devices with multiple reports, make sure to read an extra byte for the report number. @param milliseconds timeout in milliseconds or -1 for blocking wait. @returns This function returns the actual number of bytes read and -1 on error. If no packet was available to be read within the timeout period, this function returns 0. */ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); /** @brief Read an Input report from a HID device. Input reports are returned to the host through the INTERRUPT IN endpoint. The first byte will contain the Report number if the device uses numbered reports. @ingroup API @param device A device handle returned from hid_open(). @param data A buffer to put the read data into. @param length The number of bytes to read. For devices with multiple reports, make sure to read an extra byte for the report number. @returns This function returns the actual number of bytes read and -1 on error. If no packet was available to be read and the handle is in non-blocking mode, this function returns 0. */ int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); /** @brief Set the device handle to be non-blocking. In non-blocking mode calls to hid_read() will return immediately with a value of 0 if there is no data to be read. In blocking mode, hid_read() will wait (block) until there is data to read before returning. Nonblocking can be turned on and off at any time. @ingroup API @param device A device handle returned from hid_open(). @param nonblock enable or not the nonblocking reads - 1 to enable nonblocking - 0 to disable nonblocking. @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); /** @brief Send a Feature report to the device. Feature reports are sent over the Control endpoint as a Set_Report transfer. The first byte of @p data[] must contain the Report ID. For devices which only support a single report, this must be set to 0x0. The remaining bytes contain the report data. Since the Report ID is mandatory, calls to hid_send_feature_report() will always contain one more byte than the report contains. For example, if a hid report is 16 bytes long, 17 bytes must be passed to hid_send_feature_report(): the Report ID (or 0x0, for devices which do not use numbered reports), followed by the report data (16 bytes). In this example, the length passed in would be 17. @ingroup API @param device A device handle returned from hid_open(). @param data The data to send, including the report number as the first byte. @param length The length in bytes of the data to send, including the report number. @returns This function returns the actual number of bytes written and -1 on error. */ int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); /** @brief Get a feature report from a HID device. Set the first byte of @p data[] to the Report ID of the report to be read. Make sure to allow space for this extra byte in @p data[]. Upon return, the first byte will still contain the Report ID, and the report data will start in data[1]. @ingroup API @param device A device handle returned from hid_open(). @param data A buffer to put the read data into, including the Report ID. Set the first byte of @p data[] to the Report ID of the report to be read, or set it to zero if your device does not use numbered reports. @param length The number of bytes to read, including an extra byte for the report ID. The buffer can be longer than the actual report. @returns This function returns the number of bytes read plus one for the report ID (which is still in the first byte), or -1 on error. */ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); /** @brief Close a HID device. @ingroup API @param device A device handle returned from hid_open(). */ void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); /** @brief Get The Manufacturer String from a HID device. @ingroup API @param device A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); /** @brief Get The Product String from a HID device. @ingroup API @param device A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); /** @brief Get The Serial Number String from a HID device. @ingroup API @param device A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); /** @brief Get a string from a HID device, based on its string index. @ingroup API @param device A device handle returned from hid_open(). @param string_index The index of the string to get. @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); /** @brief Get a string describing the last error which occurred. @ingroup API @param device A device handle returned from hid_open(). @returns This function returns a string containing the last error which occurred or NULL if none has occurred. */ HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); #ifdef __cplusplus } #endif #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/log.h0000644000175000017500000000542013275777076021347 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LOG_H #define LOG_H #include #include namespace nitrokey { namespace log { //for MSVC #ifdef ERROR #undef ERROR #endif enum class Loglevel : int { ERROR, WARNING, INFO, DEBUG_L1, DEBUG, DEBUG_L2 }; class LogHandler { public: virtual void print(const std::string &, Loglevel lvl) = 0; protected: std::string loglevel_to_str(Loglevel); std::string format_message_to_string(const std::string &str, const Loglevel &lvl); }; class StdlogHandler : public LogHandler { public: virtual void print(const std::string &, Loglevel lvl); }; class FunctionalLogHandler : public LogHandler { using log_function_type = std::function; log_function_type log_function; public: FunctionalLogHandler(log_function_type _log_function); virtual void print(const std::string &, Loglevel lvl); }; extern StdlogHandler stdlog_handler; class Log { public: Log() : mp_loghandler(&stdlog_handler), m_loglevel(Loglevel::WARNING) {} static Log &instance() { if (mp_instance == nullptr) mp_instance = new Log; return *mp_instance; } void operator()(const std::string &, Loglevel); void set_loglevel(Loglevel lvl) { m_loglevel = lvl; } void set_handler(LogHandler *handler) { mp_loghandler = handler; } private: LogHandler *mp_loghandler; Loglevel m_loglevel; static std::string prefix; public: static void setPrefix(std::string prefix = std::string()); private: static Log *mp_instance; }; } } #ifdef NO_LOG #define LOG(string, level) while(false){} #define LOGD(string) while(false){} #else #define LOG(string, level) nitrokey::log::Log::instance()((string), (level)) #define LOGD1(string) nitrokey::log::Log::instance()((string), (nitrokey::log::Loglevel::DEBUG_L1)) #define LOGD(string) nitrokey::log::Log::instance()((string), (nitrokey::log::Loglevel::DEBUG_L2)) #endif #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/misc.h0000644000175000017500000000567413275777076021534 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef MISC_H #define MISC_H #include #include #include #include #include "log.h" #include "LibraryException.h" #include #include namespace nitrokey { namespace misc { template std::string toHex(T value){ using namespace std; std::ostringstream oss; oss << std::hex << std::setw(sizeof(value)*2) << std::setfill('0') << value; return oss.str(); } /** * Copies string from pointer to fixed size C-style array. Src needs to be a valid C-string - eg. ended with '\0'. * Throws when source is bigger than destination. * @tparam T type of destination array * @param dest fixed size destination array * @param src pointer to source c-style valid string */ template void strcpyT(T& dest, const char* src){ if (src == nullptr) // throw EmptySourceStringException(slot_number); return; const size_t s_dest = sizeof dest; LOG(std::string("strcpyT sizes dest src ") +std::to_string(s_dest)+ " " +std::to_string(strlen(src))+ " " ,nitrokey::log::Loglevel::DEBUG_L2); if (strlen(src) > s_dest){ throw TooLongStringException(strlen(src), s_dest, src); } strncpy((char*) &dest, src, s_dest); } #define bzero(b,len) (memset((b), '\0', (len)), (void) 0) template typename T::CommandPayload get_payload(){ //Create, initialize and return by value command payload typename T::CommandPayload st; bzero(&st, sizeof(st)); return st; } template void execute_password_command(Tdev &stick, const char *password) { auto p = get_payload(); p.set_defaults(); strcpyT(p.password, password); CMDTYPE::CommandTransaction::run(stick, p); } std::string hexdump(const uint8_t *p, size_t size, bool print_header=true, bool print_ascii=true, bool print_empty=true); uint32_t stm_crc32(const uint8_t *data, size_t size); std::vector hex_string_to_byte(const char* hexString); } } #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/stick10_commands.h0000644000175000017500000006376313275777076023743 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef STICK10_COMMANDS_H #define STICK10_COMMANDS_H #include #include #include #include #include #include "device_proto.h" #include "command.h" #pragma pack (push,1) namespace nitrokey { namespace proto { /* * Stick10 protocol definition */ namespace stick10 { class GetSlotName : public Command { public: // reachable as a typedef in Transaction struct CommandPayload { uint8_t slot_number; bool isValid() const { return slot_number<0x10+3; } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; return ss.str(); } } __packed; struct ResponsePayload { uint8_t slot_name[15]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(slot_name); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class EraseSlot : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class SetTime : Command { public: struct CommandPayload { uint8_t reset; // 0 - get time, 1 - set time uint64_t time; // posix time bool isValid() const { return reset && reset != 1; } std::string dissect() const { std::stringstream ss; ss << "reset:\t" << (int)(reset) << std::endl; ss << "time:\t" << (time) << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class WriteToHOTPSlot : Command { public: struct CommandPayload { uint8_t slot_number; uint8_t slot_name[15]; uint8_t slot_secret[20]; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; union{ uint8_t slot_token_id[13]; /** OATH Token Identifier */ struct{ /** @see https://openauthentication.org/token-specs/ */ uint8_t omp[2]; uint8_t tt[2]; uint8_t mui[8]; uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 } slot_token_fields; }; union{ uint64_t slot_counter; uint8_t slot_counter_s[8]; } __packed; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; print_to_ss_volatile(slot_name); print_to_ss_volatile(slot_secret); ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; ss << "slot_token_id:\t"; for (auto i : slot_token_id) ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; ss << std::endl; ss << "slot_counter:\t[" << (int)slot_counter << "]\t" << ::nitrokey::misc::hexdump((const uint8_t *)(&slot_counter), sizeof slot_counter, false); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class WriteToTOTPSlot : Command { public: struct CommandPayload { uint8_t slot_number; uint8_t slot_name[15]; uint8_t slot_secret[20]; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; union{ uint8_t slot_token_id[13]; /** OATH Token Identifier */ struct{ /** @see https://openauthentication.org/token-specs/ */ uint8_t omp[2]; uint8_t tt[2]; uint8_t mui[8]; uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 } slot_token_fields; }; uint16_t slot_interval; bool isValid() const { return !(slot_number & 0xF0); } //TODO check std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; print_to_ss_volatile(slot_name); print_to_ss_volatile(slot_secret); ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "slot_token_id:\t"; for (auto i : slot_token_id) ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; ss << std::endl; ss << "slot_interval:\t" << (int)slot_interval << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetTOTP : Command { public: struct CommandPayload { uint8_t slot_number; uint64_t challenge; uint64_t last_totp_time; uint8_t last_interval; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; ss << "challenge:\t" << (challenge) << std::endl; ss << "last_totp_time:\t" << (last_totp_time) << std::endl; ss << "last_interval:\t" << (int)(last_interval) << std::endl; return ss.str(); } } __packed; struct ResponsePayload { union { uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 struct { uint32_t code; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; } __packed ; } __packed ; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << "code:\t" << (code) << std::endl; ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetHOTP : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return (slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; return ss.str(); } } __packed; struct ResponsePayload { union { uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 struct { uint32_t code; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; } __packed; } __packed; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << "code:\t" << (code) << std::endl; ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class ReadSlot : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; return ss.str(); } } __packed; struct ResponsePayload { uint8_t slot_name[15]; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; union{ uint8_t slot_token_id[13]; /** OATH Token Identifier */ struct{ /** @see https://openauthentication.org/token-specs/ */ uint8_t omp[2]; uint8_t tt[2]; uint8_t mui[8]; uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 } slot_token_fields; }; union{ uint64_t slot_counter; uint8_t slot_counter_s[8]; } __packed; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(slot_name); ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; ss << "slot_token_id:\t"; for (auto i : slot_token_id) ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; ss << std::endl; ss << "slot_counter:\t[" << (int)slot_counter << "]\t" << ::nitrokey::misc::hexdump((const uint8_t *)(&slot_counter), sizeof slot_counter, false); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetStatus : Command { public: struct ResponsePayload { union { uint16_t firmware_version; struct { uint8_t minor; uint8_t major; } firmware_version_st; }; union{ uint8_t card_serial[4]; uint32_t card_serial_u32; } __packed; union { uint8_t general_config[5]; struct{ uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ uint8_t capslock; /** same as numlock */ uint8_t scrolllock; /** same as numlock */ uint8_t enable_user_password; uint8_t delete_user_password; /* unused */ } __packed; } __packed; static constexpr uint8_t special_HOTP_slots = 2; bool isValid() const { return numlock < special_HOTP_slots && capslock < special_HOTP_slots && scrolllock < special_HOTP_slots && enable_user_password < 2; } std::string get_card_serial_hex() const { return nitrokey::misc::toHex(card_serial_u32); } std::string dissect() const { std::stringstream ss; ss << "firmware_version:\t" << "[" << firmware_version << "]" << "\t" << ::nitrokey::misc::hexdump( (const uint8_t *)(&firmware_version), sizeof firmware_version, false); ss << "card_serial_u32:\t" << std::hex << card_serial_u32 << std::endl; ss << "card_serial:\t" << ::nitrokey::misc::hexdump((const uint8_t *)(card_serial), sizeof card_serial, false); ss << "general_config:\t" << ::nitrokey::misc::hexdump((const uint8_t *)(general_config), sizeof general_config, false); ss << "numlock:\t" << (int)numlock << std::endl; ss << "capslock:\t" << (int)capslock << std::endl; ss << "scrolllock:\t" << (int)scrolllock << std::endl; ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetPasswordRetryCount : Command { public: struct ResponsePayload { uint8_t password_retry_count; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << " password_retry_count\t" << (int)password_retry_count << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetUserPasswordRetryCount : Command { public: struct ResponsePayload { uint8_t password_retry_count; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << " password_retry_count\t" << (int)password_retry_count << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; template void write_array(T &ss, Q (&arr)[N]){ for (int i=0; i { public: struct ResponsePayload { uint8_t password_safe_status[PWS_SLOT_COUNT]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << "password_safe_status\t"; write_array(ss, password_safe_status); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetPasswordSafeSlotName : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number\t" << (int)slot_number << std::endl; return ss.str(); } } __packed; struct ResponsePayload { uint8_t slot_name[PWS_SLOTNAME_LENGTH]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(slot_name); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetPasswordSafeSlotPassword : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << " slot_number\t" << (int)slot_number << std::endl; return ss.str(); } } __packed; struct ResponsePayload { uint8_t slot_password[PWS_PASSWORD_LENGTH]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(slot_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetPasswordSafeSlotLogin : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << " slot_number\t" << (int)slot_number << std::endl; return ss.str(); } } __packed; struct ResponsePayload { uint8_t slot_login[PWS_LOGINNAME_LENGTH]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(slot_login); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class SetPasswordSafeSlotData : Command { public: struct CommandPayload { uint8_t slot_number; uint8_t slot_name[PWS_SLOTNAME_LENGTH]; uint8_t slot_password[PWS_PASSWORD_LENGTH]; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << " slot_number\t" << (int)slot_number << std::endl; print_to_ss_volatile(slot_name); print_to_ss_volatile(slot_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class SetPasswordSafeSlotData2 : Command { public: struct CommandPayload { uint8_t slot_number; uint8_t slot_login_name[PWS_LOGINNAME_LENGTH]; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << " slot_number\t" << (int)slot_number << std::endl; print_to_ss_volatile(slot_login_name); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class ErasePasswordSafeSlot : Command { public: struct CommandPayload { uint8_t slot_number; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << " slot_number\t" << (int)slot_number << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class EnablePasswordSafe : Command { public: struct CommandPayload { uint8_t user_password[30]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(user_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class PasswordSafeInitKey : Command { /** * never used in Nitrokey App */ public: typedef Transaction CommandTransaction; }; class PasswordSafeSendSlotViaHID : Command { /** * never used in Nitrokey App */ public: struct CommandPayload { uint8_t slot_number; uint8_t slot_kind; bool isValid() const { return !(slot_number & 0xF0); } } __packed; typedef Transaction CommandTransaction; }; // TODO "Device::passwordSafeSendSlotDataViaHID" class WriteGeneralConfig : Command { public: struct CommandPayload { union{ uint8_t config[5]; struct{ uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ uint8_t capslock; /** same as numlock */ uint8_t scrolllock; /** same as numlock */ uint8_t enable_user_password; uint8_t delete_user_password; }; }; bool isValid() const { return numlock < 2 && capslock < 2 && scrolllock < 2 && enable_user_password < 2; } std::string dissect() const { std::stringstream ss; ss << "numlock:\t" << (int)numlock << std::endl; ss << "capslock:\t" << (int)capslock << std::endl; ss << "scrolllock:\t" << (int)scrolllock << std::endl; ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class FirstAuthenticate : Command { public: struct CommandPayload { uint8_t card_password[25]; uint8_t temporary_password[25]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(card_password); hexdump_to_ss(temporary_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class UserAuthenticate : Command { public: struct CommandPayload { uint8_t card_password[25]; uint8_t temporary_password[25]; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss_volatile(card_password); hexdump_to_ss(temporary_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class Authorize : Command { public: struct CommandPayload { uint32_t crc_to_authorize; uint8_t temporary_password[25]; std::string dissect() const { std::stringstream ss; ss << " crc_to_authorize:\t" << std::hex << std::setw(2) << std::setfill('0') << crc_to_authorize<< std::endl; hexdump_to_ss(temporary_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class UserAuthorize : Command { public: struct CommandPayload { uint32_t crc_to_authorize; uint8_t temporary_password[25]; std::string dissect() const { std::stringstream ss; ss << " crc_to_authorize:\t" << crc_to_authorize<< std::endl; hexdump_to_ss(temporary_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class UnlockUserPassword : Command { public: struct CommandPayload { uint8_t admin_password[25]; uint8_t user_new_password[25]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile(admin_password); print_to_ss_volatile(user_new_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class ChangeUserPin : Command { public: struct CommandPayload { uint8_t old_pin[25]; uint8_t new_pin[25]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile(old_pin); print_to_ss_volatile(new_pin); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class IsAESSupported : Command { public: struct CommandPayload { uint8_t user_password[20]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile(user_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class ChangeAdminPin : Command { public: struct CommandPayload { uint8_t old_pin[25]; uint8_t new_pin[25]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile(old_pin); print_to_ss_volatile(new_pin); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class LockDevice : Command { public: typedef Transaction CommandTransaction; }; class FactoryReset : Command { public: struct CommandPayload { uint8_t admin_password[20]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile(admin_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class BuildAESKey : Command { public: struct CommandPayload { uint8_t admin_password[20]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile(admin_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; } } } #pragma pack (pop) #endif nitrokey-app-1.3.2/libnitrokey/libnitrokey/stick10_commands_0.8.h0000644000175000017500000003435413275777076024322 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_STICK10_COMMANDS_0_8_H #define LIBNITROKEY_STICK10_COMMANDS_0_8_H #include #include #include #include #include #include "command.h" #include "device_proto.h" #include "stick10_commands.h" #pragma pack (push,1) namespace nitrokey { namespace proto { /* * Stick10 protocol definition */ namespace stick10_08 { using stick10::FirstAuthenticate; using stick10::UserAuthenticate; using stick10::SetTime; using stick10::GetStatus; using stick10::BuildAESKey; using stick10::ChangeAdminPin; using stick10::ChangeUserPin; using stick10::EnablePasswordSafe; using stick10::ErasePasswordSafeSlot; using stick10::FactoryReset; using stick10::GetPasswordRetryCount; using stick10::GetUserPasswordRetryCount; using stick10::GetPasswordSafeSlotLogin; using stick10::GetPasswordSafeSlotName; using stick10::GetPasswordSafeSlotPassword; using stick10::GetPasswordSafeSlotStatus; using stick10::GetSlotName; using stick10::IsAESSupported; using stick10::LockDevice; using stick10::PasswordSafeInitKey; using stick10::PasswordSafeSendSlotViaHID; using stick10::SetPasswordSafeSlotData; using stick10::SetPasswordSafeSlotData2; using stick10::UnlockUserPassword; using stick10::ReadSlot; class EraseSlot : Command { public: struct CommandPayload { uint8_t slot_number; uint8_t temporary_admin_password[25]; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; ss << "slot_number:\t" << (int)(slot_number) << std::endl; hexdump_to_ss(temporary_admin_password); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class SendOTPData : Command { //admin auth public: struct CommandPayload { uint8_t temporary_admin_password[25]; uint8_t type; //S-secret, N-name uint8_t id; //multiple reports for values longer than 30 bytes uint8_t data[30]; //data, does not need null termination bool isValid() const { return true; } void setTypeName(){ type = 'N'; } void setTypeSecret(){ type = 'S'; } std::string dissect() const { std::stringstream ss; hexdump_to_ss(temporary_admin_password); ss << "type:\t" << type << std::endl; ss << "id:\t" << (int)id << std::endl; #ifdef LOG_VOLATILE_DATA ss << "data:" << std::endl << ::nitrokey::misc::hexdump((const uint8_t *) (&data), sizeof data); #else ss << " Volatile data not logged" << std::endl; #endif return ss.str(); } } __packed; struct ResponsePayload { union { uint8_t data[40]; } __packed; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; #ifdef LOG_VOLATILE_DATA ss << "data:" << std::endl << ::nitrokey::misc::hexdump((const uint8_t *) (&data), sizeof data); #else ss << " Volatile data not logged" << std::endl; #endif return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class WriteToOTPSlot : Command { //admin auth public: struct CommandPayload { uint8_t temporary_admin_password[25]; uint8_t slot_number; union { uint64_t slot_counter_or_interval; uint8_t slot_counter_s[8]; } __packed; union { uint8_t _slot_config; struct { bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; union { uint8_t slot_token_id[13]; /** OATH Token Identifier */ struct { /** @see https://openauthentication.org/token-specs/ */ uint8_t omp[2]; uint8_t tt[2]; uint8_t mui[8]; uint8_t keyboard_layout; //disabled feature in nitroapp as of 20160805 } slot_token_fields; }; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; hexdump_to_ss(temporary_admin_password); ss << "slot_config:\t" << std::bitset<8>((int) _slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; ss << "slot_number:\t" << (int) (slot_number) << std::endl; ss << "slot_counter_or_interval:\t[" << (int) slot_counter_or_interval << "]\t" << ::nitrokey::misc::hexdump((const uint8_t *) (&slot_counter_or_interval), sizeof slot_counter_or_interval, false); ss << "slot_token_id:\t"; for (auto i : slot_token_id) ss << std::hex << std::setw(2) << std::setfill('0') << (int) i << " "; ss << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetHOTP : Command { public: struct CommandPayload { uint8_t slot_number; struct { uint64_t challenge; //@unused uint64_t last_totp_time; //@unused uint8_t last_interval; //@unused } __packed _unused; uint8_t temporary_user_password[25]; bool isValid() const { return (slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; hexdump_to_ss(temporary_user_password); ss << "slot_number:\t" << (int)(slot_number) << std::endl; return ss.str(); } } __packed; struct ResponsePayload { union { uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 struct { uint32_t code; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; } __packed; } __packed; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << "code:\t" << (code) << std::endl; ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class GetTOTP : Command { //user auth public: struct CommandPayload { uint8_t slot_number; uint64_t challenge; //@unused uint64_t last_totp_time; //@unused uint8_t last_interval; //@unused uint8_t temporary_user_password[25]; bool isValid() const { return !(slot_number & 0xF0); } std::string dissect() const { std::stringstream ss; hexdump_to_ss(temporary_user_password); ss << "slot_number:\t" << (int)(slot_number) << std::endl; ss << "challenge:\t" << (challenge) << std::endl; ss << "last_totp_time:\t" << (last_totp_time) << std::endl; ss << "last_interval:\t" << (int)(last_interval) << std::endl; return ss.str(); } } __packed; struct ResponsePayload { union { uint8_t whole_response[18]; //14 bytes reserved for config, but used only 1 struct { uint32_t code; union{ uint8_t _slot_config; struct{ bool use_8_digits : 1; bool use_enter : 1; bool use_tokenID : 1; }; }; } __packed ; } __packed ; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; ss << "code:\t" << (code) << std::endl; ss << "slot_config:\t" << std::bitset<8>((int)_slot_config) << std::endl; ss << "\tuse_8_digits(0):\t" << use_8_digits << std::endl; ss << "\tuse_enter(1):\t" << use_enter << std::endl; ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class WriteGeneralConfig : Command { //admin auth public: struct CommandPayload { union{ uint8_t config[5]; struct{ uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ uint8_t capslock; /** same as numlock */ uint8_t scrolllock; /** same as numlock */ uint8_t enable_user_password; uint8_t delete_user_password; }; }; uint8_t temporary_admin_password[25]; static constexpr uint8_t special_HOTP_slots = 3; bool isValid() const { return numlock < special_HOTP_slots && capslock < special_HOTP_slots && scrolllock < special_HOTP_slots && enable_user_password < 2; } std::string dissect() const { std::stringstream ss; ss << "numlock:\t" << (int)numlock << std::endl; ss << "capslock:\t" << (int)capslock << std::endl; ss << "scrolllock:\t" << (int)scrolllock << std::endl; ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; } } } #pragma pack (pop) #endif //LIBNITROKEY_STICK10_COMMANDS_0_8_H nitrokey-app-1.3.2/libnitrokey/libnitrokey/stick20_commands.h0000644000175000017500000004041113275777076023725 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef STICK20_COMMANDS_H #define STICK20_COMMANDS_H #include #include "command.h" #include #include #include "device_proto.h" #pragma pack (push,1) namespace nitrokey { namespace proto { /* * STICK20 protocol command ids * a superset (almost) of STICK10 */ namespace stick20 { class ChangeAdminUserPin20Current : public PasswordCommand {}; class ChangeAdminUserPin20New : public PasswordCommand {}; class UnlockUserPin : public PasswordCommand {}; class EnableEncryptedPartition : public PasswordCommand {}; class EnableHiddenEncryptedPartition : public PasswordCommand {}; class SetUnencryptedVolumeReadOnlyAdmin : public PasswordCommand {}; class SetUnencryptedVolumeReadWriteAdmin : public PasswordCommand {}; class SetEncryptedVolumeReadOnly : public PasswordCommand {}; class SetEncryptedVolumeReadWrite : public PasswordCommand {}; //FIXME the volume disabling commands do not need password class DisableEncryptedPartition : public PasswordCommand {}; class DisableHiddenEncryptedPartition : public PasswordCommand {}; class EnableFirmwareUpdate : public PasswordCommand {}; class ChangeUpdatePassword : Command { public: struct CommandPayload { uint8_t __gap; uint8_t current_update_password[20]; uint8_t __gap2; uint8_t new_update_password[20]; std::string dissect() const { std::stringstream ss; print_to_ss_volatile( current_update_password ); print_to_ss_volatile( new_update_password ); return ss.str(); } }; typedef Transaction CommandTransaction; }; class ExportFirmware : public PasswordCommand {}; class CreateNewKeys : public PasswordCommand {}; class FillSDCardWithRandomChars : Command { public: enum class ChosenVolumes : uint8_t { all_volumes = 0, encrypted_volume = 1 }; struct CommandPayload { uint8_t volume_flag; uint8_t kind; uint8_t admin_pin[20]; std::string dissect() const { std::stringstream ss; print_to_ss( (int) volume_flag ); print_to_ss( kind ); print_to_ss_volatile(admin_pin); return ss.str(); } void set_kind_user() { kind = (uint8_t) 'P'; } void set_defaults(){ set_kind_user(); volume_flag = static_cast(ChosenVolumes::encrypted_volume); } } __packed; typedef Transaction::command_id(), struct CommandPayload, struct EmptyPayload> CommandTransaction; }; namespace StorageCommandResponsePayload{ using namespace DeviceResponseConstants; static constexpr auto padding_size = storage_data_absolute_address - header_size; struct TransmissionData{ uint8_t _padding[padding_size]; uint8_t SendCounter_u8; uint8_t SendDataType_u8; uint8_t FollowBytesFlag_u8; uint8_t SendSize_u8; std::string dissect() const { std::stringstream ss; ss << "_padding:" << std::endl << ::nitrokey::misc::hexdump((const uint8_t *) (_padding), sizeof _padding); print_to_ss((int) SendCounter_u8); print_to_ss((int) SendDataType_u8); print_to_ss((int) FollowBytesFlag_u8); print_to_ss((int) SendSize_u8); return ss.str(); } } __packed; } namespace DeviceConfigurationResponsePacket{ struct ResponsePayload { StorageCommandResponsePayload::TransmissionData transmission_data; uint16_t MagicNumber_StickConfig_u16; /** * READ_WRITE_ACTIVE = ReadWriteFlagUncryptedVolume_u8 == 0; */ uint8_t ReadWriteFlagUncryptedVolume_u8; uint8_t ReadWriteFlagCryptedVolume_u8; union{ uint8_t VersionInfo_au8[4]; struct { uint8_t major; uint8_t minor; uint8_t _reserved2; uint8_t build_iteration; } __packed versionInfo; } __packed; uint8_t ReadWriteFlagHiddenVolume_u8; uint8_t FirmwareLocked_u8; union{ uint8_t NewSDCardFound_u8; struct { bool NewCard :1; uint8_t Counter :7; } __packed NewSDCardFound_st; } __packed; /** * SD card FILLED with random chars */ uint8_t SDFillWithRandomChars_u8; uint32_t ActiveSD_CardID_u32; union{ uint8_t VolumeActiceFlag_u8; struct { bool unencrypted :1; bool encrypted :1; bool hidden :1; } __packed VolumeActiceFlag_st; } __packed; uint8_t NewSmartCardFound_u8; uint8_t UserPwRetryCount; uint8_t AdminPwRetryCount; uint32_t ActiveSmartCardID_u32; uint8_t StickKeysNotInitiated; bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss(transmission_data.dissect()); print_to_ss( MagicNumber_StickConfig_u16 ); print_to_ss((int) ReadWriteFlagUncryptedVolume_u8 ); print_to_ss((int) ReadWriteFlagCryptedVolume_u8 ); print_to_ss((int) ReadWriteFlagHiddenVolume_u8 ); print_to_ss((int) versionInfo.major ); print_to_ss((int) versionInfo.minor ); print_to_ss((int) versionInfo.build_iteration ); print_to_ss((int) FirmwareLocked_u8 ); print_to_ss((int) NewSDCardFound_u8 ); print_to_ss((int) NewSDCardFound_st.NewCard ); print_to_ss((int) NewSDCardFound_st.Counter ); print_to_ss((int) SDFillWithRandomChars_u8 ); print_to_ss( ActiveSD_CardID_u32 ); print_to_ss((int) VolumeActiceFlag_u8 ); print_to_ss((int) VolumeActiceFlag_st.unencrypted ); print_to_ss((int) VolumeActiceFlag_st.encrypted ); print_to_ss((int) VolumeActiceFlag_st.hidden); print_to_ss((int) NewSmartCardFound_u8 ); print_to_ss((int) UserPwRetryCount ); print_to_ss((int) AdminPwRetryCount ); print_to_ss( ActiveSmartCardID_u32 ); print_to_ss((int) StickKeysNotInitiated ); return ss.str(); } } __packed; } class SendStartup : Command { public: struct CommandPayload { uint64_t localtime; // POSIX seconds from epoch start, supports until year 2106 std::string dissect() const { std::stringstream ss; print_to_ss( localtime ); return ss.str(); } void set_defaults(){ localtime = std::chrono::duration_cast ( std::chrono::system_clock::now().time_since_epoch()).count(); } }__packed; using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; typedef Transaction CommandTransaction; }; // TODO fix original nomenclature class SendSetReadonlyToUncryptedVolume : public PasswordCommand {}; class SendSetReadwriteToUncryptedVolume : public PasswordCommand {}; class SendClearNewSdCardFound : public PasswordCommand {}; class GetDeviceStatus : Command { public: using ResponsePayload = DeviceConfigurationResponsePacket::ResponsePayload; typedef Transaction CommandTransaction; }; class CheckSmartcardUsage : Command { public: typedef Transaction CommandTransaction; }; class GetSDCardOccupancy : Command { public: struct ResponsePayload { uint8_t WriteLevelMin; uint8_t WriteLevelMax; uint8_t ReadLevelMin; uint8_t ReadLevelMax; std::string dissect() const { std::stringstream ss; print_to_ss((int) WriteLevelMin); print_to_ss((int) WriteLevelMax); print_to_ss((int) ReadLevelMin); print_to_ss((int) ReadLevelMax); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; class SetupHiddenVolume : Command { public: constexpr static int MAX_HIDDEN_VOLUME_PASSWORD_SIZE = 20; struct CommandPayload { uint8_t SlotNr_u8; uint8_t StartBlockPercent_u8; uint8_t EndBlockPercent_u8; uint8_t HiddenVolumePassword_au8[MAX_HIDDEN_VOLUME_PASSWORD_SIZE]; std::string dissect() const { std::stringstream ss; print_to_ss((int) SlotNr_u8); print_to_ss((int) StartBlockPercent_u8); print_to_ss((int) EndBlockPercent_u8); print_to_ss_volatile(HiddenVolumePassword_au8); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; //disable this command for now // class LockFirmware : public PasswordCommand {}; class ProductionTest : Command { public: struct ResponsePayload { StorageCommandResponsePayload::TransmissionData transmission_data; uint8_t FirmwareVersion_au8[2]; // 2 byte // 2 uint8_t FirmwareVersionInternal_u8; // 1 byte // 3 uint8_t SD_Card_Size_u8; // 1 byte // 4 uint32_t CPU_CardID_u32; // 4 byte // 8 uint32_t SmartCardID_u32; // 4 byte // 12 uint32_t SD_CardID_u32; // 4 byte // 16 uint8_t SC_UserPwRetryCount; // User PIN retry count 1 byte // 17 uint8_t SC_AdminPwRetryCount; // Admin PIN retry count 1 byte // 18 uint8_t SD_Card_ManufacturingYear_u8; // 1 byte // 19 uint8_t SD_Card_ManufacturingMonth_u8; // 1 byte // 20 uint16_t SD_Card_OEM_u16; // 2 byte // 22 uint16_t SD_WriteSpeed_u16; // in kbyte / sec 2 byte // 24 uint8_t SD_Card_Manufacturer_u8; // 1 byte // 25 bool isValid() const { return true; } std::string dissect() const { std::stringstream ss; print_to_ss(transmission_data.dissect()); print_to_ss((int) FirmwareVersion_au8[0]); print_to_ss((int) FirmwareVersion_au8[1]); print_to_ss((int) FirmwareVersionInternal_u8); print_to_ss((int) SD_Card_Size_u8); print_to_ss( CPU_CardID_u32); print_to_ss( SmartCardID_u32); print_to_ss( SD_CardID_u32); print_to_ss((int) SC_UserPwRetryCount); print_to_ss((int) SC_AdminPwRetryCount); print_to_ss((int) SD_Card_ManufacturingYear_u8); print_to_ss((int) SD_Card_ManufacturingMonth_u8); print_to_ss( SD_Card_OEM_u16); print_to_ss( SD_WriteSpeed_u16); print_to_ss((int) SD_Card_Manufacturer_u8); return ss.str(); } } __packed; typedef Transaction CommandTransaction; }; } } } #undef print_to_ss #pragma pack (pop) #endif nitrokey-app-1.3.2/libnitrokey/log.cc0000644000175000017500000000557513275777076017165 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include "log.h" #include #include #include #include namespace nitrokey { namespace log { Log *Log::mp_instance = nullptr; StdlogHandler stdlog_handler; std::string Log::prefix = ""; std::string LogHandler::loglevel_to_str(Loglevel lvl) { switch (lvl) { case Loglevel::DEBUG_L1: return std::string("DEBUG_L1"); case Loglevel::DEBUG_L2: return std::string("DEBUG_L2"); case Loglevel::DEBUG: return std::string("DEBUG"); case Loglevel::INFO: return std::string("INFO"); case Loglevel::WARNING: return std::string("WARNING"); case Loglevel::ERROR: return std::string("ERROR"); } return std::string(""); } void Log::operator()(const std::string &logstr, Loglevel lvl) { if (mp_loghandler != nullptr){ if ((int) lvl <= (int) m_loglevel) mp_loghandler->print(prefix+logstr, lvl); } } void Log::setPrefix(const std::string prefix) { if (!prefix.empty()){ Log::prefix = "["+prefix+"]"; } else { Log::prefix = ""; } } void StdlogHandler::print(const std::string &str, Loglevel lvl) { std::string s = format_message_to_string(str, lvl); std::clog << s; } void FunctionalLogHandler::print(const std::string &str, Loglevel lvl) { std::string s = format_message_to_string(str, lvl); log_function(s); } std::string LogHandler::format_message_to_string(const std::string &str, const Loglevel &lvl) { static bool last_short = false; if (str.length() == 1){ last_short = true; return str; } time_t t = time(nullptr); tm tm = *localtime(&t); std::stringstream s; s << (last_short? "\n" : "") << "[" << std::put_time(&tm, "%c") << "]" << "[" << loglevel_to_str(lvl) << "]\t" << str << std::endl; last_short = false; return s.str(); } FunctionalLogHandler::FunctionalLogHandler(log_function_type _log_function) { log_function = _log_function; } } } nitrokey-app-1.3.2/libnitrokey/misc.cc0000644000175000017500000000631013275777076017323 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include #include #include "misc.h" #include "inttypes.h" #include #include #include "LibraryException.h" #include namespace nitrokey { namespace misc { ::std::vector hex_string_to_byte(const char* hexString){ const size_t big_string_size = 257; //arbitrary 'big' number const size_t s_size = strnlen(hexString, big_string_size); const size_t d_size = s_size/2; if (s_size%2!=0 || s_size>=big_string_size){ throw InvalidHexString(0); } auto data = ::std::vector(); data.reserve(d_size); char buf[3]; buf[2] = '\0'; for(size_t i=0; i ::std::string hexdump(const uint8_t *p, size_t size, bool print_header, bool print_ascii, bool print_empty) { ::std::stringstream out; char formatbuf[128]; const uint8_t *pstart = p; for (const uint8_t *pend = p + size; p < pend;) { if (print_header){ snprintf(formatbuf, 128, "%04x\t", static_cast (p - pstart)); out << formatbuf; } const uint8_t* pp = p; for (const uint8_t *le = p + 16; p < le; p++) { if (p < pend){ snprintf(formatbuf, 128, "%02x ", uint8_t(*p)); out << formatbuf; } else { if(print_empty) out << "-- "; } } if(print_ascii){ out << " "; for (const uint8_t *le = pp + 16; pp < le && pp < pend; pp++) { if (std::isgraph(*pp)) out << uint8_t(*pp); else out << '.'; } } out << ::std::endl; } return out.str(); } static uint32_t _crc32(uint32_t crc, uint32_t data) { int i; crc = crc ^ data; for (i = 0; i < 32; i++) { if (crc & 0x80000000) crc = (crc << 1) ^ 0x04C11DB7; // polynomial used in STM32 else crc = (crc << 1); } return crc; } uint32_t stm_crc32(const uint8_t *data, size_t size) { uint32_t crc = 0xffffffff; const uint32_t *pend = (const uint32_t *)(data + size); for (const uint32_t *p = (const uint32_t *)(data); p < pend; p++) crc = _crc32(crc, *p); return crc; } } } nitrokey-app-1.3.2/libnitrokey/python_bindings_example.py0000755000175000017500000001235713232102355023326 0ustar janjan00000000000000#!/usr/bin/env python2 """ Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import cffi from enum import Enum """ This example will print 10 HOTP codes from just written HOTP#2 slot. For more examples of use please refer to unittest/test_*.py files. """ ffi = cffi.FFI() get_string = ffi.string class DeviceErrorCode(Enum): STATUS_OK = 0 NOT_PROGRAMMED = 3 WRONG_PASSWORD = 4 STATUS_NOT_AUTHORIZED = 5 STATUS_AES_DEC_FAILED = 0xa 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") print("Please set the path using LIBNK_PATH environment variable to existing library or compile it (see " "README.md for details)") sys.exit(1) return C def get_hotp_code(lib, i): return get_string(lib.NK_get_hotp_code(i)) def to_hex(ss): return ''.join([ format(ord(s),'02x') for s in ss ]) print('Warning!') print('This example will change your configuration on inserted stick and overwrite your HOTP#2 slot.') print('Please write "continue" to continue or any other string to quit') a = raw_input() if not a == 'continue': exit() ADMIN = raw_input('Please enter your admin PIN (empty string uses 12345678) ') ADMIN = ADMIN or '12345678' # use default if empty string show_log = raw_input('Should log messages be shown (please write "yes" to enable; this will make harder reading script output) ') == 'yes' libnitrokey = get_library() if show_log: log_level = raw_input('Please select verbosity level (0-5, 2 is library default, 3 will be selected on empty input) ') log_level = log_level or '3' log_level = int(log_level) libnitrokey.NK_set_debug_level(log_level) else: libnitrokey.NK_set_debug_level(2) ADMIN_TEMP = '123123123' RFC_SECRET = to_hex('12345678901234567890') # libnitrokey.NK_login('S') # connect only to Nitrokey Storage device # libnitrokey.NK_login('P') # connect only to Nitrokey Pro device device_connected = libnitrokey.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() use_8_digits = True pin_correct = libnitrokey.NK_first_authenticate(ADMIN, ADMIN_TEMP) == DeviceErrorCode.STATUS_OK if pin_correct: print('Your PIN is correct!') else: print('Your PIN is not correct! Please try again. Please be careful to not lock your stick!') retry_count_left = libnitrokey.NK_get_admin_retry_count() print('Retry count left: %d' % retry_count_left ) exit() # For function parameters documentation please check NK_C_API.h assert libnitrokey.NK_write_config(255, 255, 255, False, True, ADMIN_TEMP) == DeviceErrorCode.STATUS_OK libnitrokey.NK_first_authenticate(ADMIN, ADMIN_TEMP) libnitrokey.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, use_8_digits, False, False, "", ADMIN_TEMP) # RFC test according to: https://tools.ietf.org/html/rfc4226#page-32 test_data = [ 1284755224, 1094287082, 137359152, 1726969429, 1640338314, 868254676, 1918287922, 82162583, 673399871, 645520489, ] print('Getting HOTP code from Nitrokey Stick (RFC test, 8 digits): ') for i in range(10): hotp_slot_1_code = get_hotp_code(libnitrokey, 1) correct_str = "correct!" if hotp_slot_1_code == str(test_data[i])[-8:] else "not correct" print('%d: %s, should be %s -> %s' % (i, hotp_slot_1_code, str(test_data[i])[-8:], correct_str)) libnitrokey.NK_logout() # disconnect device nitrokey-app-1.3.2/libnitrokey/unittest/build/libnitrokey.so0000777000175000017500000000000013221174520030325 2../../build/libnitrokey.soustar janjan00000000000000nitrokey-app-1.3.2/libnitrokey/unittest/build/run.sh0000755000175000017500000000003613221174520022151 0ustar janjan00000000000000LD_LIBRARY_PATH=. ./test_HOTP nitrokey-app-1.3.2/libnitrokey/unittest/catch_main.cpp0000644000175000017500000000152713232102355022506 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() #include "catch.hpp"nitrokey-app-1.3.2/libnitrokey/unittest/conftest.py0000644000175000017500000000661213275777076022144 0ustar janjan00000000000000""" Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import pytest from misc import ffi device_type = None def skip_if_device_version_lower_than(allowed_devices): global device_type model, version = device_type infinite_version_number = 999 if allowed_devices.get(model, infinite_version_number) > version: pytest.skip('This device model is not applicable to run this test') @pytest.fixture(scope="module") def C(request=None): fp = '../NK_C_API.h' declarations = [] with open(fp, 'r') as f: declarations = f.readlines() cnt = 0 a = iter(declarations) for declaration in a: if 'NK_device_model' in declaration: continue 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) C.NK_set_debug_level(int(os.environ.get('LIBNK_DEBUG', 2))) nk_login = C.NK_login_auto() if nk_login != 1: print('No devices detected!') assert nk_login != 0 # returns 0 if not connected or wrong model or 1 when connected global device_type firmware_version = C.NK_get_minor_firmware_version() model = 'P' if firmware_version in [7,8] else 'S' device_type = (model, firmware_version) print('Connected device: {} {}'.format(model, firmware_version)) # assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK # C.NK_status() def fin(): print('\nFinishing connection to device') C.NK_logout() print('Finished') if request: request.addfinalizer(fin) # C.NK_set_debug(True) C.NK_set_debug_level(int(os.environ.get('LIBNK_DEBUG', 3))) return C nitrokey-app-1.3.2/libnitrokey/unittest/constants.py0000644000175000017500000000301613232102355022275 0ustar janjan00000000000000""" Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ from misc import to_hex def bb(x): return bytes(x, encoding='ascii') RFC_SECRET_HR = '12345678901234567890' RFC_SECRET = to_hex(RFC_SECRET_HR) # '31323334353637383930...' bbRFC_SECRET = bb(RFC_SECRET) # print( repr((RFC_SECRET, RFC_SECRET_, len(RFC_SECRET))) ) class DefaultPasswords: ADMIN = b'12345678' USER = b'123456' ADMIN_TEMP = b'123123123' USER_TEMP = b'234234234' UPDATE = b'12345678' UPDATE_TEMP = b'123update123' class DeviceErrorCode: STATUS_OK = 0 BUSY = 1 # busy or busy progressbar in place of wrong_CRC status NOT_PROGRAMMED = 3 WRONG_PASSWORD = 4 STATUS_NOT_AUTHORIZED = 5 STATUS_AES_DEC_FAILED = 0xa class LibraryErrors: TOO_LONG_STRING = 200 INVALID_SLOT = 201 INVALID_HEX_STRING = 202 TARGET_BUFFER_SIZE_SMALLER_THAN_SOURCE = 203 nitrokey-app-1.3.2/libnitrokey/unittest/misc.py0000644000175000017500000000337513275777076021255 0ustar janjan00000000000000""" Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import cffi ffi = cffi.FFI() gs = ffi.string def to_hex(s): return "".join("{:02x}".format(ord(c)) for c in s) def wait(t): import time msg = 'Waiting for %d seconds' % t print(msg.center(40, '=')) time.sleep(t) def cast_pointer_to_tuple(obj, typen, len): # usage: # config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5) return tuple(ffi.cast("%s [%d]" % (typen, len), obj)[0:len]) def get_devices_firmware_version(C): firmware = C.NK_get_minor_firmware_version() return firmware def is_pro_rtm_07(C): firmware = get_devices_firmware_version(C) return firmware == 7 def is_pro_rtm_08(C): firmware = get_devices_firmware_version(C) return firmware in [8,9] def is_storage(C): """ exact firmware storage is sent by other function """ # TODO identify connected device directly firmware = get_devices_firmware_version(C) return firmware >= 45 def is_long_OTP_secret_handled(C): return is_pro_rtm_08(C) or is_storage(C) and get_devices_firmware_version(C) > 43 nitrokey-app-1.3.2/libnitrokey/unittest/requirements.txt0000644000175000017500000000004713221174520023175 0ustar janjan00000000000000cffi pytest-repeat pytest-randomly oathnitrokey-app-1.3.2/libnitrokey/unittest/setup_python_dependencies.sh0000644000175000017500000000006413221174520025513 0ustar janjan00000000000000#!/bin/bash pip install -r requirements.txt --user nitrokey-app-1.3.2/libnitrokey/unittest/test.cc0000644000175000017500000000646113232102355021204 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include "catch.hpp" #include #include #include "device_proto.h" #include "log.h" #include "stick10_commands.h" using namespace std; using namespace nitrokey::device; using namespace nitrokey::proto::stick10; using namespace nitrokey::log; using namespace nitrokey::misc; using Dev10 = std::shared_ptr; std::string getSlotName(Dev10 stick, int slotNo) { auto slot_req = get_payload(); slot_req.slot_number = slotNo; auto slot = ReadSlot::CommandTransaction::run(stick, slot_req); std::string sName(reinterpret_cast(slot.data().slot_name)); return sName; } TEST_CASE("Slot names are correct", "[slotNames]") { auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); auto resp = GetStatus::CommandTransaction::run(stick); auto authreq = get_payload(); strcpy((char *)(authreq.card_password), "12345678"); FirstAuthenticate::CommandTransaction::run(stick, authreq); { auto authreq = get_payload(); strcpy((char *)(authreq.user_password), "123456"); EnablePasswordSafe::CommandTransaction::run(stick, authreq); } //assuming these values were set earlier, thus failing on normal use REQUIRE(getSlotName(stick, 0x20) == std::string("1")); REQUIRE(getSlotName(stick, 0x21) == std::string("slot2")); { auto resp = GetPasswordRetryCount::CommandTransaction::run(stick); REQUIRE(resp.data().password_retry_count == 3); } { auto resp = GetUserPasswordRetryCount::CommandTransaction::run(stick); REQUIRE(resp.data().password_retry_count == 3); } { auto slot = get_payload(); slot.slot_number = 0; auto resp2 = GetPasswordSafeSlotName::CommandTransaction::run(stick, slot); std::string sName(reinterpret_cast(resp2.data().slot_name)); REQUIRE(sName == std::string("web1")); } { auto slot = get_payload(); slot.slot_number = 0; auto resp2 = GetPasswordSafeSlotPassword::CommandTransaction::run(stick, slot); std::string sName(reinterpret_cast(resp2.data().slot_password)); REQUIRE(sName == std::string("pass1")); } { auto slot = get_payload(); slot.slot_number = 0; auto resp2 = GetPasswordSafeSlotLogin::CommandTransaction::run(stick, slot); std::string sName(reinterpret_cast(resp2.data().slot_login)); REQUIRE(sName == std::string("login1")); } stick->disconnect(); } nitrokey-app-1.3.2/libnitrokey/unittest/test2.cc0000644000175000017500000001740213232102355021263 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ static const char *const default_admin_pin = "12345678"; static const char *const default_user_pin = "123456"; #include "catch.hpp" #include #include #include #include "device_proto.h" #include "log.h" //#include "stick10_commands.h" #include "stick20_commands.h" using namespace std; using namespace nitrokey::device; using namespace nitrokey::proto; using namespace nitrokey::proto::stick20; using namespace nitrokey::log; using namespace nitrokey::misc; #include template void execute_password_command(std::shared_ptr stick, const char *password, const char kind = 'P') { auto p = get_payload(); if (kind == 'P'){ p.set_kind_user(); } else { p.set_kind_admin(); } strcpyT(p.password, password); CMDTYPE::CommandTransaction::run(stick, p); this_thread::sleep_for(1000ms); } /** * fail on purpose (will result in failed test) * disable from running unwillingly */ void SKIP_TEST() { CAPTURE("Failing current test to SKIP it"); REQUIRE(false); } TEST_CASE("long operation test", "[test_long]") { SKIP_TEST(); auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); try{ auto p = get_payload(); p.set_defaults(); strcpyT(p.admin_pin, default_admin_pin); FillSDCardWithRandomChars::CommandTransaction::run(stick, p); this_thread::sleep_for(1000ms); CHECK(false); } catch (LongOperationInProgressException &progressException){ CHECK(true); } for (int i = 0; i < 30; ++i) { try { stick10::GetStatus::CommandTransaction::run(stick); } catch (LongOperationInProgressException &progressException){ CHECK((int)progressException.progress_bar_value>=0); CAPTURE((int)progressException.progress_bar_value); this_thread::sleep_for(2000ms); } } } TEST_CASE("test device internal status with various commands", "[fast]") { auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); auto p = get_payload(); p.set_defaults(); auto device_status = stick20::SendStartup::CommandTransaction::run(stick, p); REQUIRE(device_status.data().AdminPwRetryCount == 3); REQUIRE(device_status.data().UserPwRetryCount == 3); REQUIRE(device_status.data().ActiveSmartCardID_u32 != 0); auto production_status = stick20::ProductionTest::CommandTransaction::run(stick); REQUIRE(production_status.data().SD_Card_Size_u8 == 8); REQUIRE(production_status.data().SD_CardID_u32 != 0); auto sdcard_occupancy = stick20::GetSDCardOccupancy::CommandTransaction::run(stick); REQUIRE((int) sdcard_occupancy.data().ReadLevelMin >= 0); REQUIRE((int) sdcard_occupancy.data().ReadLevelMax <= 100); REQUIRE((int) sdcard_occupancy.data().WriteLevelMin >= 0); REQUIRE((int) sdcard_occupancy.data().WriteLevelMax <= 100); } TEST_CASE("setup hidden volume test", "[hidden]") { auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); stick10::LockDevice::CommandTransaction::run(stick); this_thread::sleep_for(2000ms); auto user_pin = default_user_pin; execute_password_command(stick, user_pin); auto p = get_payload(); p.SlotNr_u8 = 0; p.StartBlockPercent_u8 = 70; p.EndBlockPercent_u8 = 90; auto hidden_volume_password = "123123123"; strcpyT(p.HiddenVolumePassword_au8, hidden_volume_password); stick20::SetupHiddenVolume::CommandTransaction::run(stick, p); this_thread::sleep_for(2000ms); execute_password_command(stick, hidden_volume_password); } TEST_CASE("setup multiple hidden volumes", "[hidden]") { auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); auto user_pin = default_user_pin; stick10::LockDevice::CommandTransaction::run(stick); this_thread::sleep_for(2000ms); execute_password_command(stick, user_pin); constexpr int volume_count = 4; for (int i = 0; i < volume_count; ++i) { auto p = get_payload(); p.SlotNr_u8 = i; p.StartBlockPercent_u8 = 20 + 10*i; p.EndBlockPercent_u8 = p.StartBlockPercent_u8+i+1; auto hidden_volume_password = std::string("123123123")+std::to_string(i); strcpyT(p.HiddenVolumePassword_au8, hidden_volume_password.c_str()); stick20::SetupHiddenVolume::CommandTransaction::run(stick, p); this_thread::sleep_for(2000ms); } for (int i = 0; i < volume_count; ++i) { execute_password_command(stick, user_pin); auto hidden_volume_password = std::string("123123123")+std::to_string(i); execute_password_command(stick, hidden_volume_password.c_str()); this_thread::sleep_for(2000ms); } } //in case of a bug this could change update PIN to some unexpected value // - please save log with packet dump if this test will not pass TEST_CASE("update password change", "[dangerous]") { SKIP_TEST(); auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); auto pass1 = default_admin_pin; auto pass2 = "12345678901234567890"; auto data = { make_pair(pass1, pass2), make_pair(pass2, pass1), }; for (auto && password: data) { auto p = get_payload(); strcpyT(p.current_update_password, password.first); strcpyT(p.new_update_password, password.second); stick20::ChangeUpdatePassword::CommandTransaction::run(stick, p); } } TEST_CASE("general test", "[test]") { auto stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); stick10::LockDevice::CommandTransaction::run(stick); // execute_password_command(stick, "123456"); // execute_password_command(stick, "123456"); // execute_password_command(stick, "123123123"); execute_password_command(stick, default_user_pin); execute_password_command(stick, default_user_pin); execute_password_command(stick, default_admin_pin, 'A'); stick20::GetDeviceStatus::CommandTransaction::run(stick); this_thread::sleep_for(1000ms); // execute_password_command(stick, "123123123"); //CAUTION // execute_password_command(stick, "123123123"); //CAUTION FIRMWARE PIN execute_password_command(stick, "12345678", 'A'); // execute_password_command(stick, "12345678", 'A'); stick10::LockDevice::CommandTransaction::run(stick); } nitrokey-app-1.3.2/libnitrokey/unittest/test3.cc0000644000175000017500000001654113232102355021267 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ static const char *const default_admin_pin = "12345678"; static const char *const default_user_pin = "123456"; const char * temporary_password = "123456789012345678901234"; const char * RFC_SECRET = "12345678901234567890"; #include "catch.hpp" #include #include #include #include "device_proto.h" #include "log.h" #include "stick10_commands_0.8.h" //#include "stick20_commands.h" using namespace std; using namespace nitrokey::device; using namespace nitrokey::proto; using namespace nitrokey::proto::stick10_08; using namespace nitrokey::log; using namespace nitrokey::misc; using Dev = Stick10; using Dev10 = std::shared_ptr; void connect_and_setup(Dev10 stick) { bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); } void authorize(Dev10 stick) { auto authreq = get_payload(); strcpy((char *) (authreq.card_password), default_admin_pin); strcpy((char *) (authreq.temporary_password), temporary_password); FirstAuthenticate::CommandTransaction::run(stick, authreq); auto user_auth = get_payload(); strcpyT(user_auth.temporary_password, temporary_password); strcpyT(user_auth.card_password, default_user_pin); UserAuthenticate::CommandTransaction::run(stick, user_auth); } TEST_CASE("write slot", "[pronew]"){ auto stick = make_shared(); connect_and_setup(stick); authorize(stick); auto p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); p2.setTypeName(); strcpyT(p2.data, "test name aaa"); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); strcpyT(p2.data, RFC_SECRET); p2.setTypeSecret(); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); auto p = get_payload(); strcpyT(p.temporary_admin_password, temporary_password); p.use_8_digits = true; p.slot_number = 0 + 0x10; p.slot_counter_or_interval = 0; stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p); auto pc = get_payload(); pc.enable_user_password = 0; strcpyT(pc.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, pc); auto p3 = get_payload(); p3.slot_number = 0 + 0x10; GetHOTP::CommandTransaction::run(stick, p3); } TEST_CASE("erase slot", "[pronew]"){ auto stick = make_shared(); connect_and_setup(stick); authorize(stick); auto p = get_payload(); p.enable_user_password = 0; strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); auto p3 = get_payload(); p3.slot_number = 0 + 0x10; GetHOTP::CommandTransaction::run(stick, p3); auto erase_payload = get_payload(); erase_payload.slot_number = 0 + 0x10; strcpyT(erase_payload.temporary_admin_password, temporary_password); EraseSlot::CommandTransaction::run(stick, erase_payload); auto p4 = get_payload(); p4.slot_number = 0 + 0x10; REQUIRE_THROWS( GetHOTP::CommandTransaction::run(stick, p4) ); } TEST_CASE("write general config", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); authorize(stick); auto p = get_payload(); p.enable_user_password = 1; REQUIRE_THROWS( WriteGeneralConfig::CommandTransaction::run(stick, p) ); strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); } TEST_CASE("authorize user HOTP", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); authorize(stick); { auto p = get_payload(); p.enable_user_password = 1; strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); } auto p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); p2.setTypeName(); strcpyT(p2.data, "test name aaa"); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); strcpyT(p2.data, RFC_SECRET); p2.setTypeSecret(); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); auto p = get_payload(); strcpyT(p.temporary_admin_password, temporary_password); p.use_8_digits = true; p.slot_number = 0 + 0x10; p.slot_counter_or_interval = 0; stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p); auto p3 = get_payload(); p3.slot_number = 0 + 0x10; REQUIRE_THROWS( GetHOTP::CommandTransaction::run(stick, p3) ); strcpyT(p3.temporary_user_password, temporary_password); auto code_response = GetHOTP::CommandTransaction::run(stick, p3); REQUIRE(code_response.data().code == 84755224); } TEST_CASE("check firmware version", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); auto p = GetStatus::CommandTransaction::run(stick); REQUIRE(p.data().firmware_version == 8); } TEST_CASE("authorize user TOTP", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); authorize(stick); { auto p = get_payload(); p.enable_user_password = 1; strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); } auto p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); p2.setTypeName(); strcpyT(p2.data, "test name TOTP"); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); strcpyT(p2.data, RFC_SECRET); p2.setTypeSecret(); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); auto p = get_payload(); strcpyT(p.temporary_admin_password, temporary_password); p.use_8_digits = true; p.slot_number = 0 + 0x20; p.slot_counter_or_interval = 30; stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p); auto p_get_totp = get_payload(); p_get_totp.slot_number = 0 + 0x20; REQUIRE_THROWS( GetTOTP::CommandTransaction::run(stick, p_get_totp) ); strcpyT(p_get_totp.temporary_user_password, temporary_password); auto p_set_time = get_payload(); p_set_time.reset = 1; p_set_time.time = 59; SetTime::CommandTransaction::run(stick, p_set_time); auto code = GetTOTP::CommandTransaction::run(stick, p_get_totp); REQUIRE(code.data().code == 94287082); } nitrokey-app-1.3.2/libnitrokey/unittest/test_C_API.cpp0000644000175000017500000000443113275777076022360 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ static const int TOO_LONG_STRING = 200; #include "catch.hpp" #include #include #include "log.h" #include "../NK_C_API.h" int login; TEST_CASE("C API connect", "[BASIC]") { login = NK_login_auto(); REQUIRE(login != 0); NK_logout(); login = NK_login_auto(); REQUIRE(login != 0); NK_logout(); login = NK_login_auto(); REQUIRE(login != 0); } TEST_CASE("Check retry count", "[BASIC]") { REQUIRE(login != 0); NK_set_debug_level(3); REQUIRE(NK_get_admin_retry_count() == 3); REQUIRE(NK_get_user_retry_count() == 3); } TEST_CASE("Check long strings", "[STANDARD]") { REQUIRE(login != 0); const char* longPin = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; const char* pin = "123123123"; auto result = NK_change_user_PIN(longPin, pin); REQUIRE(result == TOO_LONG_STRING); result = NK_change_user_PIN(pin, longPin); REQUIRE(result == TOO_LONG_STRING); CAPTURE(result); } #include TEST_CASE("multiple devices with ID", "[BASIC]") { NK_logout(); NK_set_debug_level(3); auto s = NK_list_devices_by_cpuID(); REQUIRE(s!=nullptr); REQUIRE(strnlen(s, 4096) < 4096); REQUIRE(strnlen(s, 4096) > 2*4); std::cout << s << std::endl; char *string, *token; int t; string = strndup(s, 4096); free ( (void*) s); while ((token = strsep(&string, ";")) != nullptr){ if (strnlen(token, 4096) < 3) continue; std::cout << token << " connecting: "; std::cout << (t=NK_connect_with_ID(token)) << std::endl; REQUIRE(t == 1); } free (string); }nitrokey-app-1.3.2/libnitrokey/unittest/test_HOTP.cc0000644000175000017500000000770413275777076022070 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include "catch.hpp" #include #include "device_proto.h" #include "log.h" #include "stick10_commands.h" #include #include "misc.h" using namespace std; using namespace nitrokey::device; using namespace nitrokey::proto::stick10; using namespace nitrokey::log; using namespace nitrokey::misc; void hexStringToByte(uint8_t data[], const char* hexString){ REQUIRE(strlen(hexString)%2==0); char buf[3]; buf[2] = '\0'; for(int i=0; i(slot_secret) ) == 0 ); } TEST_CASE("Test HOTP codes according to RFC", "[HOTP]") { std::shared_ptr stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); auto resp = GetStatus::CommandTransaction::run(stick); const char * temporary_password = "123456789012345678901234"; { auto authreq = get_payload(); strcpy((char *)(authreq.card_password), "12345678"); strcpy((char *)(authreq.temporary_password), temporary_password); FirstAuthenticate::CommandTransaction::run(stick, authreq); } //test according to https://tools.ietf.org/html/rfc4226#page-32 { auto hwrite = get_payload(); hwrite.slot_number = 0x10; strcpy(reinterpret_cast(hwrite.slot_name), "rfc4226_lib"); //strcpy(reinterpret_cast(hwrite.slot_secret), ""); const char* secretHex = "3132333435363738393031323334353637383930"; hexStringToByte(hwrite.slot_secret, secretHex); //hwrite.slot_config; //TODO check various configs in separate test cases //strcpy(reinterpret_cast(hwrite.slot_token_id), ""); //strcpy(reinterpret_cast(hwrite.slot_counter), ""); //authorize writehotp first { auto auth = get_payload(); strcpy((char *)(auth.temporary_password), temporary_password); auth.crc_to_authorize = WriteToHOTPSlot::CommandTransaction::getCRC(hwrite); Authorize::CommandTransaction::run(stick, auth); } //run hotp command WriteToHOTPSlot::CommandTransaction::run(stick, hwrite); uint32_t codes[] = { 755224, 287082, 359152, 969429, 338314, 254676, 287922, 162583, 399871, 520489 }; for( auto code: codes){ auto gh = get_payload(); gh.slot_number = 0x10; auto resp = GetHOTP::CommandTransaction::run(stick, gh); REQUIRE( resp.data().code == code); } //checking slot programmed before with nitro-app /* for( auto code: codes){ GetHOTP::CommandTransaction::CommandPayload gh; gh.slot_number = 0x12; auto resp = GetHOTP::CommandTransaction::run(stick, gh); REQUIRE( resp.code == code); } */ } stick->disconnect(); } nitrokey-app-1.3.2/libnitrokey/unittest/test_command_ids_header.h0000644000175000017500000000560113232102355024706 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #ifndef LIBNITROKEY_TEST_COMMAND_IDS_HEADER_H_H #define LIBNITROKEY_TEST_COMMAND_IDS_HEADER_H_H #define STICK20_CMD_START_VALUE 0x20 #define STICK20_CMD_ENABLE_CRYPTED_PARI (STICK20_CMD_START_VALUE + 0) #define STICK20_CMD_DISABLE_CRYPTED_PARI (STICK20_CMD_START_VALUE + 1) #define STICK20_CMD_ENABLE_HIDDEN_CRYPTED_PARI (STICK20_CMD_START_VALUE + 2) #define STICK20_CMD_DISABLE_HIDDEN_CRYPTED_PARI (STICK20_CMD_START_VALUE + 3) #define STICK20_CMD_ENABLE_FIRMWARE_UPDATE (STICK20_CMD_START_VALUE + 4) #define STICK20_CMD_EXPORT_FIRMWARE_TO_FILE (STICK20_CMD_START_VALUE + 5) #define STICK20_CMD_GENERATE_NEW_KEYS (STICK20_CMD_START_VALUE + 6) #define STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS (STICK20_CMD_START_VALUE + 7) #define STICK20_CMD_WRITE_STATUS_DATA (STICK20_CMD_START_VALUE + 8) #define STICK20_CMD_ENABLE_READONLY_UNCRYPTED_LUN (STICK20_CMD_START_VALUE + 9) #define STICK20_CMD_ENABLE_READWRITE_UNCRYPTED_LUN (STICK20_CMD_START_VALUE + 10) #define STICK20_CMD_SEND_PASSWORD_MATRIX (STICK20_CMD_START_VALUE + 11) #define STICK20_CMD_SEND_PASSWORD_MATRIX_PINDATA (STICK20_CMD_START_VALUE + 12) #define STICK20_CMD_SEND_PASSWORD_MATRIX_SETUP (STICK20_CMD_START_VALUE + 13) #define STICK20_CMD_GET_DEVICE_STATUS (STICK20_CMD_START_VALUE + 14) #define STICK20_CMD_SEND_DEVICE_STATUS (STICK20_CMD_START_VALUE + 15) #define STICK20_CMD_SEND_HIDDEN_VOLUME_PASSWORD (STICK20_CMD_START_VALUE + 16) #define STICK20_CMD_SEND_HIDDEN_VOLUME_SETUP (STICK20_CMD_START_VALUE + 17) #define STICK20_CMD_SEND_PASSWORD (STICK20_CMD_START_VALUE + 18) #define STICK20_CMD_SEND_NEW_PASSWORD (STICK20_CMD_START_VALUE + 19) #define STICK20_CMD_CLEAR_NEW_SD_CARD_FOUND (STICK20_CMD_START_VALUE + 20) #define STICK20_CMD_SEND_STARTUP (STICK20_CMD_START_VALUE + 21) #define STICK20_CMD_SEND_CLEAR_STICK_KEYS_NOT_INITIATED (STICK20_CMD_START_VALUE + 22) #define STICK20_CMD_SEND_LOCK_STICK_HARDWARE (STICK20_CMD_START_VALUE + 23) #define STICK20_CMD_PRODUCTION_TEST (STICK20_CMD_START_VALUE + 24) #define STICK20_CMD_SEND_DEBUG_DATA (STICK20_CMD_START_VALUE + 25) #define STICK20_CMD_CHANGE_UPDATE_PIN (STICK20_CMD_START_VALUE + 26) #endif //LIBNITROKEY_TEST_COMMAND_IDS_HEADER_H_H nitrokey-app-1.3.2/libnitrokey/unittest/test_issues.cc0000644000175000017500000000517613275777076022632 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ const char * const default_admin_pin = "12345678"; const char * const default_user_pin = "123456"; const char * const temporary_password = "123456789012345678901234"; const char * const RFC_SECRET = "12345678901234567890"; const char * const hidden_volume_pass = "123456789012345"; #include "catch.hpp" #include using namespace std; using namespace nitrokey; bool test_36(){ auto i = NitrokeyManager::instance(); i->set_loglevel(3); REQUIRE(i->connect()); for (int j = 0; j < 200; ++j) { i->get_status(); i->get_status_storage_as_string(); INFO( "Iteration: " << j); } return true; } bool test_31(){ auto i = NitrokeyManager::instance(); i->set_loglevel(3); REQUIRE(i->connect()); // i->unlock_encrypted_volume(default_user_pin); // i->create_hidden_volume(0, 70, 80, hidden_volume_pass); // i->lock_device(); try{ i->get_password_safe_slot_status(); } catch (...){ //pass } i->get_status_storage(); i->get_admin_retry_count(); i->get_status_storage(); i->get_user_retry_count(); i->unlock_encrypted_volume(default_user_pin); i->get_status_storage(); i->get_password_safe_slot_status(); i->get_status_storage(); i->get_user_retry_count(); i->get_password_safe_slot_status(); i->get_status(); i->get_status_storage(); i->get_admin_retry_count(); i->get_status(); i->get_user_retry_count(); i->unlock_hidden_volume(hidden_volume_pass); i->get_status_storage(); i->get_password_safe_slot_status(); return true; } TEST_CASE("issue 31", "[issue]"){ { auto i = NitrokeyManager::instance(); i->set_loglevel(4); REQUIRE(i->connect()); i->unlock_encrypted_volume(default_user_pin); i->create_hidden_volume(0, 70, 80, hidden_volume_pass); i->lock_device(); } for(int i=0; i<20; i++){ REQUIRE(test_31()); } } TEST_CASE("issue 36", "[issue]"){ REQUIRE(test_36()); } nitrokey-app-1.3.2/libnitrokey/unittest/test_library.py0000644000175000017500000001066513232102355022774 0ustar janjan00000000000000""" Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import pytest from misc import ffi, gs, to_hex, is_pro_rtm_07, is_long_OTP_secret_handled from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, LibraryErrors, bbRFC_SECRET def test_too_long_strings(C): new_password = b'123123123' long_string = b'a' * 100 assert C.NK_change_user_PIN(long_string, new_password) == LibraryErrors.TOO_LONG_STRING assert C.NK_change_user_PIN(new_password, long_string) == LibraryErrors.TOO_LONG_STRING assert C.NK_change_admin_PIN(long_string, new_password) == LibraryErrors.TOO_LONG_STRING assert C.NK_change_admin_PIN(new_password, long_string) == LibraryErrors.TOO_LONG_STRING assert C.NK_first_authenticate(long_string, DefaultPasswords.ADMIN_TEMP) == LibraryErrors.TOO_LONG_STRING assert C.NK_erase_totp_slot(0, long_string) == LibraryErrors.TOO_LONG_STRING digits = False assert C.NK_write_hotp_slot(1, long_string, bbRFC_SECRET, 0, digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == LibraryErrors.TOO_LONG_STRING assert C.NK_write_hotp_slot(1, b'long_test', bbRFC_SECRET, 0, digits, False, False, b"", long_string) == LibraryErrors.TOO_LONG_STRING assert gs(C.NK_get_hotp_code_PIN(0, long_string)) == b"" assert C.NK_get_last_command_status() == LibraryErrors.TOO_LONG_STRING def test_invalid_slot(C): invalid_slot = 255 assert C.NK_erase_totp_slot(invalid_slot, b'some password') == LibraryErrors.INVALID_SLOT assert C.NK_write_hotp_slot(invalid_slot, b'long_test', bbRFC_SECRET, 0, False, False, False, b"", b'aaa') == LibraryErrors.INVALID_SLOT assert gs(C.NK_get_hotp_code_PIN(invalid_slot, b'some password')) == b"" assert C.NK_get_last_command_status() == LibraryErrors.INVALID_SLOT assert C.NK_erase_password_safe_slot(invalid_slot) == LibraryErrors.INVALID_SLOT assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_password_safe_slot_name(invalid_slot)) == b'' assert C.NK_get_last_command_status() == LibraryErrors.INVALID_SLOT assert gs(C.NK_get_password_safe_slot_login(invalid_slot)) == b'' assert C.NK_get_last_command_status() == LibraryErrors.INVALID_SLOT @pytest.mark.parametrize("invalid_hex_string", ['text', '00 ', '0xff', 'zzzzzzzzzzzz', 'fff', 'f' * 257, 'f' * 258]) def test_invalid_secret_hex_string_for_OTP_write(C, invalid_hex_string): """ Tests for invalid secret hex string during writing to OTP slot. Invalid strings are not hexadecimal number, empty or longer than 255 characters. """ invalid_hex_string = invalid_hex_string.encode('ascii') assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(1, b'slot_name', invalid_hex_string, 0, True, False, False, b'', DefaultPasswords.ADMIN_TEMP) == LibraryErrors.INVALID_HEX_STRING assert C.NK_write_totp_slot(1, b'python_test', invalid_hex_string, 30, True, False, False, b"", DefaultPasswords.ADMIN_TEMP) == LibraryErrors.INVALID_HEX_STRING def test_warning_binary_bigger_than_secret_buffer(C): invalid_hex_string = to_hex('1234567890') * 3 invalid_hex_string = invalid_hex_string.encode('ascii') if is_long_OTP_secret_handled(C): invalid_hex_string *= 2 assert C.NK_write_hotp_slot(1, b'slot_name', invalid_hex_string, 0, True, False, False, b'', DefaultPasswords.ADMIN_TEMP) == LibraryErrors.TARGET_BUFFER_SIZE_SMALLER_THAN_SOURCE @pytest.mark.skip(reason='Experimental') def test_clear(C): d = 'asdasdasd' print(d) C.clear_password(d) print(d)nitrokey-app-1.3.2/libnitrokey/unittest/test_multiple.py0000644000175000017500000000437013275777076023210 0ustar janjan00000000000000""" Copyright (c) 2017-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import pprint from time import sleep import pytest from collections import defaultdict from tqdm import tqdm from conftest import skip_if_device_version_lower_than from constants import DefaultPasswords, DeviceErrorCode, bb from misc import gs, wait pprint = pprint.PrettyPrinter(indent=4).pprint @pytest.mark.other @pytest.mark.info def test_get_status_storage_multiple(C): ids = gs(C.NK_list_devices_by_cpuID()) print(ids) devices_list = ids.split(b';') # # for s in devices_list: # res = C.NK_connect_with_ID(s) # assert res == 1 # # st = gs(C.NK_get_status_storage_as_string()) # # print(len(st)) # C.NK_lock_device() # for s in devices_list: res = C.NK_connect_with_ID(s) assert res == 1 v = C.NK_fill_SD_card_with_random_data(b'12345678') # print(v) devices_count = len(devices_list) assert devices_count != 0 b = 0 last_b = 0 with tqdm(total=devices_count*100) as pbar: while b/devices_count < 100: pbar.update(b - last_b) b = defaultdict (lambda: 0) ids = gs(C.NK_list_devices_by_cpuID()) devices_list = ids.split(b';') devices_count = len(devices_list) for s in devices_list: res = C.NK_connect_with_ID(s) if res != 1: continue b[s] += C.NK_get_progress_bar_value() print(b) b = sum(b.values()) print('{}: {}'.format(b, int(b/devices_count) * '=')) sleep(5) nitrokey-app-1.3.2/libnitrokey/unittest/test_multiple_devices.cc0000644000175000017500000001255213275777076024650 0ustar janjan00000000000000/* * Copyright (c) 2017-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ static const char *const default_admin_pin = "12345678"; static const char *const default_user_pin = "123456"; const char * temporary_password = "123456789012345678901234"; const char * RFC_SECRET = "12345678901234567890"; #include "catch.hpp" #include #include #include using namespace nitrokey; TEST_CASE("List devices", "[BASIC]") { shared_ptr d = make_shared(); auto v = d->enumerate(); REQUIRE(v.size() > 0); for (auto a : v){ std::cout << a; d->set_path(a); d->connect(); auto res = GetStatus::CommandTransaction::run(d); auto res2 = GetDeviceStatus::CommandTransaction::run(d); std::cout << " " << res.data().card_serial_u32 << " " << res.data().get_card_serial_hex() << " " << std::to_string(res2.data().versionInfo.minor) << std::endl; d->disconnect(); } } TEST_CASE("Regenerate AES keys", "[BASIC]") { shared_ptr d = make_shared(); auto v = d->enumerate(); REQUIRE(v.size() > 0); std::vector> devices; for (auto a : v){ std::cout << a << endl; d = make_shared(); d->set_path(a); d->connect(); devices.push_back(d); } for (auto d : devices){ auto res2 = GetDeviceStatus::CommandTransaction::run(d); std::cout << std::to_string(res2.data().versionInfo.minor) << std::endl; // nitrokey::proto::stick20::CreateNewKeys::CommandPayload p; // p.set_defaults(); // memcpy(p.password, "12345678", 8); // auto res3 = nitrokey::proto::stick20::CreateNewKeys::CommandTransaction::run(d, p); } for (auto d : devices){ //TODO watch out for multiple hid_exit calls d->disconnect(); } } TEST_CASE("Use API", "[BASIC]") { auto nm = NitrokeyManager::instance(); nm->set_loglevel(2); auto v = nm->list_devices(); REQUIRE(v.size() > 0); for (int i=0; i<10; i++){ for (auto a : v) { std::cout <<"Connect with: " << a << " " << std::boolalpha << nm->connect_with_path(a) << " "; try{ auto status_storage = nm->get_status_storage(); std::cout << status_storage.ActiveSmartCardID_u32 << " " << status_storage.ActiveSD_CardID_u32 << std::endl; // nm->fill_SD_card_with_random_data("12345678"); } catch (const LongOperationInProgressException &e){ std::cout << "long operation in progress on " << a << " " << std::to_string(e.progress_bar_value) << std::endl; // this_thread::sleep_for(1000ms); } } std::cout <<"Iteration: " << i << std::endl; } } TEST_CASE("Use API ID", "[BASIC]") { auto nm = NitrokeyManager::instance(); nm->set_loglevel(2); auto v = nm->list_devices_by_cpuID(); REQUIRE(v.size() > 0); //no refresh - should not reconnect to new devices // Scenario: // 1. Run test // 2. Remove one of the devices and reinsert it after a while // 3. Device should not be reconnected and test should not crash // 4. Remove all devices - test should continue for (int j = 0; j < 100; j++) { for (auto i : v) { if (!nm->connect_with_ID(i)) continue; int retry_count = 99; try { retry_count = nm->get_admin_retry_count(); std::cout << j << " " << i << " " << to_string(retry_count) << std::endl; } catch (...) { retry_count = 99; //pass } } } std::cout << "finished" << std::endl; } TEST_CASE("Use API ID refresh", "[BASIC]") { auto nm = NitrokeyManager::instance(); nm->set_loglevel(2); //refresh in each iteration - should reconnect to new devices // Scenario: // 1. Run test // 2. Remove one of the devices and reinsert it after a while // 3. Device should be reconnected for(int j=0; j<100; j++) { auto v = nm->list_devices_by_cpuID(); REQUIRE(v.size() > 0); for (auto i : v) { nm->connect_with_ID(i); int retry_count = 99; try { retry_count = nm->get_admin_retry_count(); std::cout << j <<" " << i << " " << to_string(retry_count) << std::endl; } catch (...){ retry_count = 99; //pass } } } std::cout << "finished" << std::endl; } nitrokey-app-1.3.2/libnitrokey/unittest/test_offline.cc0000644000175000017500000001435213275777076022735 0ustar janjan00000000000000/* * Copyright (c) 2015-2018 Nitrokey UG * * This file is part of libnitrokey. * * libnitrokey is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * libnitrokey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnitrokey. If not, see . * * SPDX-License-Identifier: LGPL-3.0 */ #include "catch.hpp" #include #include #include "../NK_C_API.h" using namespace nitrokey::proto; using namespace nitrokey::device; using namespace std; using namespace nitrokey; //This test suite assumes no Pro or Storage devices are connected TEST_CASE("Return false on no device connected", "[fast]") { INFO("This test case assumes no Pro or Storage devices are connected"); auto stick = make_shared(); bool connected = true; REQUIRE_NOTHROW(connected = stick->connect()); REQUIRE_FALSE(connected); auto stick_pro = make_shared(); REQUIRE_NOTHROW(connected = stick_pro->connect()); REQUIRE_FALSE(connected); auto i = NitrokeyManager::instance(); REQUIRE_NOTHROW(connected = i->connect()); REQUIRE_FALSE(connected); REQUIRE_FALSE(i->is_connected()); REQUIRE_FALSE(i->disconnect()); REQUIRE_FALSE(i->could_current_device_be_enumerated()); int C_connected = 1; REQUIRE_NOTHROW(C_connected = NK_login_auto()); REQUIRE(0 == C_connected); } TEST_CASE("Test C++ side behaviour in offline", "[fast]") { auto i = NitrokeyManager::instance(); string serial_number; REQUIRE_NOTHROW (serial_number = i->get_serial_number()); REQUIRE(serial_number.empty()); REQUIRE_THROWS_AS( i->get_status(), DeviceNotConnected ); REQUIRE_THROWS_AS( i->get_HOTP_code(0xFF, ""), InvalidSlotException ); REQUIRE_THROWS_AS( i->get_TOTP_code(0xFF, ""), InvalidSlotException ); REQUIRE_THROWS_AS( i->erase_hotp_slot(0xFF, ""), InvalidSlotException ); REQUIRE_THROWS_AS( i->erase_totp_slot(0xFF, ""), InvalidSlotException ); REQUIRE_THROWS_AS( i->get_totp_slot_name(0xFF), InvalidSlotException ); REQUIRE_THROWS_AS( i->get_hotp_slot_name(0xFF), InvalidSlotException ); REQUIRE_THROWS_AS( i->first_authenticate("123123", "123123"), DeviceNotConnected ); REQUIRE_THROWS_AS( i->get_connected_device_model(), DeviceNotConnected ); REQUIRE_THROWS_AS( i->clear_new_sd_card_warning("123123"), DeviceNotConnected ); } TEST_CASE("Test helper function - hex_string_to_byte", "[fast]") { using namespace nitrokey::misc; std::vector v; REQUIRE_NOTHROW(v = hex_string_to_byte("00112233445566")); const uint8_t test_data[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; REQUIRE(v.size() == sizeof(test_data)); for (int i = 0; i < v.size(); ++i) { INFO("Position i: " << i); REQUIRE(v[i] == test_data[i]); } } #include "test_command_ids_header.h" TEST_CASE("Test device commands ids", "[fast]") { // Make sure CommandID values are in sync with firmware's header // REQUIRE(STICK20_CMD_START_VALUE == static_cast(CommandID::START_VALUE)); REQUIRE(STICK20_CMD_ENABLE_CRYPTED_PARI == static_cast(CommandID::ENABLE_CRYPTED_PARI)); REQUIRE(STICK20_CMD_DISABLE_CRYPTED_PARI == static_cast(CommandID::DISABLE_CRYPTED_PARI)); REQUIRE(STICK20_CMD_ENABLE_HIDDEN_CRYPTED_PARI == static_cast(CommandID::ENABLE_HIDDEN_CRYPTED_PARI)); REQUIRE(STICK20_CMD_DISABLE_HIDDEN_CRYPTED_PARI == static_cast(CommandID::DISABLE_HIDDEN_CRYPTED_PARI)); REQUIRE(STICK20_CMD_ENABLE_FIRMWARE_UPDATE == static_cast(CommandID::ENABLE_FIRMWARE_UPDATE)); REQUIRE(STICK20_CMD_EXPORT_FIRMWARE_TO_FILE == static_cast(CommandID::EXPORT_FIRMWARE_TO_FILE)); REQUIRE(STICK20_CMD_GENERATE_NEW_KEYS == static_cast(CommandID::GENERATE_NEW_KEYS)); REQUIRE(STICK20_CMD_FILL_SD_CARD_WITH_RANDOM_CHARS == static_cast(CommandID::FILL_SD_CARD_WITH_RANDOM_CHARS)); REQUIRE(STICK20_CMD_WRITE_STATUS_DATA == static_cast(CommandID::WRITE_STATUS_DATA)); REQUIRE(STICK20_CMD_ENABLE_READONLY_UNCRYPTED_LUN == static_cast(CommandID::ENABLE_READONLY_UNCRYPTED_LUN)); REQUIRE(STICK20_CMD_ENABLE_READWRITE_UNCRYPTED_LUN == static_cast(CommandID::ENABLE_READWRITE_UNCRYPTED_LUN)); REQUIRE(STICK20_CMD_SEND_PASSWORD_MATRIX == static_cast(CommandID::SEND_PASSWORD_MATRIX)); REQUIRE(STICK20_CMD_SEND_PASSWORD_MATRIX_PINDATA == static_cast(CommandID::SEND_PASSWORD_MATRIX_PINDATA)); REQUIRE(STICK20_CMD_SEND_PASSWORD_MATRIX_SETUP == static_cast(CommandID::SEND_PASSWORD_MATRIX_SETUP)); REQUIRE(STICK20_CMD_GET_DEVICE_STATUS == static_cast(CommandID::GET_DEVICE_STATUS)); REQUIRE(STICK20_CMD_SEND_DEVICE_STATUS == static_cast(CommandID::SEND_DEVICE_STATUS)); REQUIRE(STICK20_CMD_SEND_HIDDEN_VOLUME_PASSWORD == static_cast(CommandID::SEND_HIDDEN_VOLUME_PASSWORD)); REQUIRE(STICK20_CMD_SEND_HIDDEN_VOLUME_SETUP == static_cast(CommandID::SEND_HIDDEN_VOLUME_SETUP)); REQUIRE(STICK20_CMD_SEND_PASSWORD == static_cast(CommandID::SEND_PASSWORD)); REQUIRE(STICK20_CMD_SEND_NEW_PASSWORD == static_cast(CommandID::SEND_NEW_PASSWORD)); REQUIRE(STICK20_CMD_CLEAR_NEW_SD_CARD_FOUND == static_cast(CommandID::CLEAR_NEW_SD_CARD_FOUND)); REQUIRE(STICK20_CMD_SEND_STARTUP == static_cast(CommandID::SEND_STARTUP)); REQUIRE(STICK20_CMD_SEND_CLEAR_STICK_KEYS_NOT_INITIATED == static_cast(CommandID::SEND_CLEAR_STICK_KEYS_NOT_INITIATED)); REQUIRE(STICK20_CMD_SEND_LOCK_STICK_HARDWARE == static_cast(CommandID::SEND_LOCK_STICK_HARDWARE)); REQUIRE(STICK20_CMD_PRODUCTION_TEST == static_cast(CommandID::PRODUCTION_TEST)); REQUIRE(STICK20_CMD_SEND_DEBUG_DATA == static_cast(CommandID::SEND_DEBUG_DATA)); REQUIRE(STICK20_CMD_CHANGE_UPDATE_PIN == static_cast(CommandID::CHANGE_UPDATE_PIN)); } nitrokey-app-1.3.2/libnitrokey/unittest/test_pro.py0000644000175000017500000012243613275777076022161 0ustar janjan00000000000000""" Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import pytest from conftest import skip_if_device_version_lower_than from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, bb, bbRFC_SECRET from misc import ffi, gs, wait, cast_pointer_to_tuple from misc import is_pro_rtm_07, is_pro_rtm_08, is_storage @pytest.mark.lock_device @pytest.mark.PWS def test_enable_password_safe(C): """ All Password Safe tests depend on AES keys being initialized. They will fail otherwise. """ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(b'wrong_password') == DeviceErrorCode.WRONG_PASSWORD assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.lock_device @pytest.mark.PWS def test_write_password_safe_slot(C): assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_NOT_AUTHORIZED assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK @pytest.mark.lock_device @pytest.mark.PWS @pytest.mark.slowtest def test_write_all_password_safe_slots_and_read_10_times(C): def fill(s, wid): assert wid >= len(s) numbers = '1234567890'*4 s += numbers[:wid-len(s)] assert len(s) == wid return bb(s) def get_pass(suffix): return fill('pass' + suffix, 20) def get_loginname(suffix): return fill('login' + suffix, 32) def get_slotname(suffix): return fill('slotname' + suffix, 11) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK PWS_slot_count = 16 for i in range(0, PWS_slot_count): iss = str(i) assert C.NK_write_password_safe_slot(i, get_slotname(iss), get_loginname(iss), get_pass(iss)) == DeviceErrorCode.STATUS_OK for j in range(0, 10): for i in range(0, PWS_slot_count): iss = str(i) assert gs(C.NK_get_password_safe_slot_name(i)) == get_slotname(iss) assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss) assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss) @pytest.mark.lock_device @pytest.mark.PWS @pytest.mark.slowtest @pytest.mark.xfail(reason="This test should be run directly after test_write_all_password_safe_slots_and_read_10_times") def test_read_all_password_safe_slots_10_times(C): def fill(s, wid): assert wid >= len(s) numbers = '1234567890'*4 s += numbers[:wid-len(s)] assert len(s) == wid return bb(s) def get_pass(suffix): return fill('pass' + suffix, 20) def get_loginname(suffix): return fill('login' + suffix, 32) def get_slotname(suffix): return fill('slotname' + suffix, 11) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK PWS_slot_count = 16 for j in range(0, 10): for i in range(0, PWS_slot_count): iss = str(i) assert gs(C.NK_get_password_safe_slot_name(i)) == get_slotname(iss) assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss) assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss) @pytest.mark.lock_device @pytest.mark.PWS def test_get_password_safe_slot_name(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_password_safe_slot_name(0)) == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_password_safe_slot_name(0)) == b'slotname1' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @pytest.mark.PWS def test_get_password_safe_slot_login_password(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK slot_login = C.NK_get_password_safe_slot_login(0) assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK assert gs(slot_login) == b'login1' slot_password = gs(C.NK_get_password_safe_slot_password(0)) assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK assert slot_password == b'pass1' @pytest.mark.PWS def test_erase_password_safe_slot(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_erase_password_safe_slot(0) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_password_safe_slot_name(0)) == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK # TODO CHECK shouldn't this be DeviceErrorCode.NOT_PROGRAMMED ? @pytest.mark.PWS def test_password_safe_slot_status(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_erase_password_safe_slot(0) == DeviceErrorCode.STATUS_OK assert C.NK_write_password_safe_slot(1, b'slotname2', b'login2', b'pass2') == DeviceErrorCode.STATUS_OK safe_slot_status = C.NK_get_password_safe_slot_status() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK is_slot_programmed = list(ffi.cast("uint8_t [16]", safe_slot_status)[0:16]) print((is_slot_programmed, len(is_slot_programmed))) assert is_slot_programmed[0] == 0 assert is_slot_programmed[1] == 1 @pytest.mark.aes def test_issue_device_locks_on_second_key_generation_in_sequence(C): # if is_pro_rtm_07(C) or is_pro_rtm_08(C): pytest.skip("issue to register: device locks up " "after below commands sequence (reinsertion fixes), skipping for now") assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.aes def test_regenerate_aes_key(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.lock_device @pytest.mark.aes @pytest.mark.factory_reset def test_enable_password_safe_after_factory_reset(C): assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK if is_storage(C): # for some reason storage likes to be authenticated before reset (to investigate) assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_factory_reset(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK wait(10) if is_storage(C): assert C.NK_clear_new_sd_card_warning(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK enable_password_safe_result = C.NK_enable_password_safe(DefaultPasswords.USER) assert enable_password_safe_result == DeviceErrorCode.STATUS_AES_DEC_FAILED \ or is_storage(C) and enable_password_safe_result == DeviceErrorCode.WRONG_PASSWORD assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.lock_device @pytest.mark.aes @pytest.mark.xfail(reason="NK Pro firmware bug: regenerating AES key command not always results in cleared slot data") def test_destroy_password_safe(C): """ Sometimes fails on NK Pro - slot name is not cleared ergo key generation has not succeed despite the success result returned from the device """ assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK # write password safe slot assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK # read slot assert gs(C.NK_get_password_safe_slot_name(0)) == b'slotname1' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK slot_login = C.NK_get_password_safe_slot_login(0) assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK assert gs(slot_login) == b'login1' # destroy password safe by regenerating aes key assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_password_safe_slot_name(0)) != b'slotname1' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK # check was slot status cleared safe_slot_status = C.NK_get_password_safe_slot_status() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK is_slot_programmed = list(ffi.cast("uint8_t [16]", safe_slot_status)[0:16]) assert is_slot_programmed[0] == 0 @pytest.mark.aes def test_is_AES_supported(C): if is_storage(C): pytest.skip("Storage does not implement this command") assert C.NK_is_AES_supported(b'wrong password') != 1 assert C.NK_get_last_command_status() == DeviceErrorCode.WRONG_PASSWORD assert C.NK_is_AES_supported(DefaultPasswords.USER) == 1 assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @pytest.mark.pin def test_admin_PIN_change(C): new_password = b'123123123' assert C.NK_change_admin_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, new_password) == DeviceErrorCode.STATUS_OK assert C.NK_change_admin_PIN(new_password, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.pin def test_user_PIN_change(C): new_password = b'123123123' assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_user_PIN(DefaultPasswords.USER, new_password) == DeviceErrorCode.STATUS_OK assert C.NK_change_user_PIN(new_password, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.lock_device @pytest.mark.pin def test_admin_retry_counts(C): default_admin_retry_count = 3 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_get_admin_retry_count() == default_admin_retry_count assert C.NK_change_admin_PIN(b'wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_admin_retry_count() == default_admin_retry_count - 1 assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_get_admin_retry_count() == default_admin_retry_count @pytest.mark.lock_device @pytest.mark.pin def test_user_retry_counts_change_PIN(C): assert C.NK_change_user_PIN(DefaultPasswords.USER, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK wrong_password = b'wrong_password' default_user_retry_count = 3 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count assert C.NK_change_user_PIN(wrong_password, wrong_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_user_retry_count() == default_user_retry_count - 1 assert C.NK_change_user_PIN(DefaultPasswords.USER, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count @pytest.mark.lock_device @pytest.mark.pin def test_user_retry_counts_PWSafe(C): default_user_retry_count = 3 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count assert C.NK_enable_password_safe(b'wrong_password') == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_user_retry_count() == default_user_retry_count - 1 assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count @pytest.mark.pin def test_unlock_user_password(C): default_user_retry_count = 3 default_admin_retry_count = 3 new_password = b'123123123' assert C.NK_get_user_retry_count() == default_user_retry_count assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_user_retry_count() == default_user_retry_count - 3 assert C.NK_get_admin_retry_count() == default_admin_retry_count assert C.NK_unlock_user_password(b'wrong password', DefaultPasswords.USER) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_admin_retry_count() == default_admin_retry_count - 1 assert C.NK_unlock_user_password(DefaultPasswords.ADMIN, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count assert C.NK_get_admin_retry_count() == default_admin_retry_count @pytest.mark.pin def test_admin_auth(C): assert C.NK_first_authenticate(b'wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK @pytest.mark.pin def test_user_auth(C): assert C.NK_user_authenticate(b'wrong_password', DefaultPasswords.USER_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK @pytest.mark.otp def check_HOTP_RFC_codes(C, func, prep=None, use_8_digits=False): """ # https://tools.ietf.org/html/rfc4226#page-32 """ assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK test_data = [ 1284755224, 1094287082, 137359152, 1726969429, 1640338314, 868254676, 1918287922, 82162583, 673399871, 645520489, ] for code in test_data: if prep: prep() r = func(1) code = str(code)[-8:] if use_8_digits else str(code)[-6:] assert bb(code) == r @pytest.mark.otp @pytest.mark.parametrize("use_8_digits", [False, True, ]) @pytest.mark.parametrize("use_pin_protection", [False, True, ]) def test_HOTP_RFC_use8digits_usepin(C, use_8_digits, use_pin_protection): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK if use_pin_protection: check_HOTP_RFC_codes(C, lambda x: gs(C.NK_get_hotp_code_PIN(x, DefaultPasswords.USER_TEMP)), lambda: C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP), use_8_digits=use_8_digits) else: check_HOTP_RFC_codes(C, lambda x: gs(C.NK_get_hotp_code(x)), use_8_digits=use_8_digits) @pytest.mark.otp def test_HOTP_token(C): """ Check HOTP routine with written token ID to slot. """ use_pin_protection = False assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK token_ID = b"AAV100000022" assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, False, False, True, token_ID, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for i in range(5): hotp_code = gs(C.NK_get_hotp_code(1)) assert hotp_code != b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @pytest.mark.otp def test_HOTP_counters(C): """ # https://tools.ietf.org/html/rfc4226#page-32 """ use_pin_protection = False assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK use_8_digits = True HOTP_test_data = [ 1284755224, 1094287082, 137359152, 1726969429, 1640338314, 868254676, 1918287922, 82162583, 673399871, 645520489, ] slot_number = 1 for counter, code in enumerate(HOTP_test_data): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, counter, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK r = gs(C.NK_get_hotp_code(slot_number)) code = str(code)[-8:] if use_8_digits else str(code)[-6:] assert bb(code) == r INT32_MAX = 2 ** 31 - 1 @pytest.mark.otp def test_HOTP_64bit_counter(C): if is_storage(C): pytest.xfail('bug in NK Storage HOTP firmware - counter is set with a 8 digits string, ' 'however int32max takes 10 digits to be written') oath = pytest.importorskip("oath") lib_at = lambda t: bb(oath.hotp(RFC_SECRET, t, format='dec6')) PIN_protection = False use_8_digits = False slot_number = 1 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] for t in range(INT32_MAX - 5, INT32_MAX + 5, 1): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, t, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (t, code_device) lib_res += (t, lib_at(t)) assert dev_res == lib_res @pytest.mark.otp def test_TOTP_64bit_time(C): if is_storage(C): pytest.xfail('bug in NK Storage TOTP firmware') oath = pytest.importorskip("oath") T = 1 lib_at = lambda t: bb(oath.totp(RFC_SECRET, t=t)) PIN_protection = False slot_number = 1 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_totp_slot(slot_number, b'python_test', bbRFC_SECRET, 30, False, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] for t in range(INT32_MAX - 5, INT32_MAX + 5, 1): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(t) == DeviceErrorCode.STATUS_OK code_device = gs((C.NK_get_totp_code(slot_number, T, 0, 30))) dev_res += (t, code_device) lib_res += (t, lib_at(t)) assert dev_res == lib_res @pytest.mark.otp @pytest.mark.xfail(reason="NK Pro: Test fails in 50% of cases due to test vectors set 1 second before interval count change" "Here time is changed on seconds side only and miliseconds part is not being reset apparently" "This results in available time to test of half a second on average, thus 50% failed cases" "With disabled two first test vectors test passess 10/10 times" "Fail may also occurs on NK Storage with lower occurrency since it needs less time to execute " "commands") @pytest.mark.parametrize("PIN_protection", [False, True, ]) def test_TOTP_RFC_usepin(C, PIN_protection): slot_number = 1 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # test according to https://tools.ietf.org/html/rfc6238#appendix-B assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_totp_slot(slot_number, b'python_test', bbRFC_SECRET, 30, True, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK get_func = None if PIN_protection: get_func = lambda x, y, z, r: gs(C.NK_get_totp_code_PIN(x, y, z, r, DefaultPasswords.USER_TEMP)) else: get_func = lambda x, y, z, r: gs(C.NK_get_totp_code(x, y, z, r)) # Mode: Sha1, time step X=30 test_data = [ #Time T (hex) TOTP (59, 0x1, 94287082), # Warning - test vector time 1 second before interval count changes (1111111109, 0x00000000023523EC, 7081804), # Warning - test vector time 1 second before interval count changes (1111111111, 0x00000000023523ED, 14050471), (1234567890, 0x000000000273EF07, 89005924), (2000000000, 0x0000000003F940AA, 69279037), # (20000000000, 0x0000000027BC86AA, 65353130), # 64bit is also checked in other test ] responses = [] data = [] correct = 0 for t, T, expected_code in test_data: if PIN_protection: C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(t) == DeviceErrorCode.STATUS_OK code_from_device = get_func(slot_number, T, 0, 30) # FIXME T is not changing the outcome data += [ (t, bb(str(expected_code).zfill(8))) ] responses += [ (t, code_from_device) ] correct += expected_code == code_from_device assert data == responses or correct == len(test_data) @pytest.mark.otp def test_get_slot_names(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_erase_totp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # erasing slot invalidates temporary password, so requesting authentication assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_erase_hotp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for i in range(15): name = ffi.string(C.NK_get_totp_slot_name(i)) if name == '': assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED for i in range(3): name = ffi.string(C.NK_get_hotp_slot_name(i)) if name == '': assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED @pytest.mark.otp def test_get_OTP_codes(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for i in range(15): code = gs(C.NK_get_totp_code(i, 0, 0, 0)) if code == b'': assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED for i in range(3): code = gs(C.NK_get_hotp_code(i)) if code == b'': assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED @pytest.mark.otp def test_get_OTP_code_from_not_programmed_slot(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_erase_hotp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_erase_totp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = gs(C.NK_get_hotp_code(0)) assert code == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED code = gs(C.NK_get_totp_code(0, 0, 0, 0)) assert code == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED @pytest.mark.otp def test_get_code_user_authorize(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_totp_slot(0, b'python_otp_auth', bbRFC_SECRET, 30, True, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # enable PIN protection of OTP codes with write_config # TODO create convinience function on C API side to enable/disable OTP USER_PIN protection assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = gs(C.NK_get_totp_code(0, 0, 0, 0)) assert code == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED # disable PIN protection with write_config assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = gs(C.NK_get_totp_code(0, 0, 0, 0)) assert code != b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK def cast_pointer_to_tuple(obj, typen, len): # usage: # config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5) return tuple(ffi.cast("%s [%d]" % (typen, len), obj)[0:len]) def test_read_write_config(C): # let's set sample config with pin protection and disabled scrolllock assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(0, 1, 2, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK config_raw_data = C.NK_read_config() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5) assert config == (0, 1, 2, True, False) # restore defaults and check assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK config_raw_data = C.NK_read_config() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5) assert config == (255, 255, 255, False, True) @pytest.mark.lock_device @pytest.mark.factory_reset def test_factory_reset(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, False, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_hotp_code(1)) == b"755224" assert C.NK_factory_reset(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK wait(10) assert gs(C.NK_get_hotp_code(1)) != b"287082" assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED # restore AES key assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK if is_storage(C): assert C.NK_clear_new_sd_card_warning(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.status def test_get_status(C): status = C.NK_status() s = gs(status) assert len(s) > 0 @pytest.mark.status def test_get_serial_number(C): sn = C.NK_device_serial_number() sn = gs(sn) assert len(sn) > 0 print(('Serial number of the device: ', sn)) @pytest.mark.otp @pytest.mark.parametrize("secret", ['000001', '00'*10+'ff', '00'*19+'ff', '000102', '00'*29+'ff', '00'*39+'ff', '002EF43F51AFA97BA2B46418768123C9E1809A5B' ]) def test_OTP_secret_started_from_null(C, secret): """ NK Pro 0.8+, NK Storage 0.43+ """ skip_if_device_version_lower_than({'S': 43, 'P': 8}) if len(secret) > 40: # feature: 320 bit long secret handling skip_if_device_version_lower_than({'P': 8}) oath = pytest.importorskip("oath") lib_at = lambda t: bb(oath.hotp(secret, t, format='dec6')) PIN_protection = False use_8_digits = False slot_number = 1 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] for t in range(1,5): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, b'null_secret', bb(secret), t, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (t, code_device) lib_res += (t, lib_at(t)) assert dev_res == lib_res @pytest.mark.otp @pytest.mark.parametrize("counter", [0, 3, 7, 0xffff, 0xffffffff, 0xffffffffffffffff] ) def test_HOTP_slots_read_write_counter(C, counter): """ Write different counters to all HOTP slots, read code and compare with 3rd party :param counter: """ if counter >= 1e7: # Storage does not handle counters longer than 7 digits skip_if_device_version_lower_than({'P': 7}) secret = RFC_SECRET oath = pytest.importorskip("oath") lib_at = lambda t: bb(oath.hotp(secret, t, format='dec6')) PIN_protection = False use_8_digits = False assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] for slot_number in range(3): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, b'HOTP rw' + bytes(slot_number), bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (counter, code_device) lib_res += (counter, lib_at(counter)) assert dev_res == lib_res @pytest.mark.otp @pytest.mark.parametrize("period", [30,60] ) @pytest.mark.parametrize("time", range(21,70,20) ) def test_TOTP_slots_read_write_at_time_period(C, time, period): """ Write to all TOTP slots with specified period, read code at specified time and compare with 3rd party """ secret = RFC_SECRET oath = pytest.importorskip("oath") lib_at = lambda t: bb(oath.totp(RFC_SECRET, t=t, period=period)) PIN_protection = False use_8_digits = False T = 0 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] for slot_number in range(15): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_totp_slot(slot_number, b'TOTP rw' + bytes(slot_number), bb(secret), period, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_totp_code(slot_number, T, 0, period)) dev_res += (time, code_device) lib_res += (time, lib_at(time)) assert dev_res == lib_res @pytest.mark.otp @pytest.mark.parametrize("secret", [RFC_SECRET, 2*RFC_SECRET, '12'*10, '12'*30] ) def test_TOTP_secrets(C, secret): ''' NK Pro 0.8+, NK Storage 0.44+ ''' skip_if_device_version_lower_than({'S': 44, 'P': 8}) if len(secret)>20*2: #*2 since secret is in hex # pytest.skip("Secret lengths over 20 bytes are not supported by NK Pro 0.7 and NK Storage") skip_if_device_version_lower_than({'P': 8}) slot_number = 0 time = 0 period = 30 oath = pytest.importorskip("oath") lib_at = lambda t: bb(oath.totp(secret, t=t, period=period)) PIN_protection = False use_8_digits = False T = 0 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] assert C.NK_write_totp_slot(slot_number, b'secret' + bytes(len(secret)), bb(secret), period, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_totp_code(slot_number, T, 0, period)) dev_res += (time, code_device) lib_res += (time, lib_at(time)) assert dev_res == lib_res @pytest.mark.otp @pytest.mark.parametrize("secret", [RFC_SECRET, 2*RFC_SECRET, '12'*10, '12'*30] ) def test_HOTP_secrets(C, secret): """ NK Pro 0.8+ feature needed: support for 320bit secrets """ if len(secret)>40: skip_if_device_version_lower_than({'P': 8}) slot_number = 0 counter = 0 oath = pytest.importorskip("oath") lib_at = lambda t: bb(oath.hotp(secret, counter=t)) PIN_protection = False use_8_digits = False T = 0 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] # repeat authentication for Pro 0.7 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, b'secret' + bytes(len(secret)), bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (counter, code_device) lib_res += (counter, lib_at(counter)) assert dev_res == lib_res def test_special_double_press(C): """ requires manual check after function run double press each of num-, scroll-, caps-lock and check inserted OTP codes (each 1st should be 755224) on nkpro 0.7 scrolllock should do nothing, on nkpro 0.8+ should return OTP code """ secret = RFC_SECRET counter = 0 PIN_protection = False use_8_digits = False assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(0, 1, 2, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for slot_number in range(3): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, b'double' + bytes(slot_number), bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # requires manual check @pytest.mark.otp def test_edit_OTP_slot(C): """ should change slots counter and name without changing its secret (using null secret for second update) """ # counter is not getting updated under Storage v0.43 - #TOREPORT skip_if_device_version_lower_than({'S': 44, 'P': 7}) secret = RFC_SECRET counter = 0 PIN_protection = False use_8_digits = False assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK slot_number = 0 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK first_name = b'edit slot' assert C.NK_write_hotp_slot(slot_number, first_name, bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_hotp_slot_name(slot_number)) == first_name first_code = gs(C.NK_get_hotp_code(slot_number)) changed_name = b'changedname' empty_secret = b'' assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, changed_name, empty_secret, counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK second_code = gs(C.NK_get_hotp_code(slot_number)) assert first_code == second_code assert gs(C.NK_get_hotp_slot_name(slot_number)) == changed_name @pytest.mark.otp @pytest.mark.skip @pytest.mark.parametrize("secret", ['31323334353637383930'*2,'31323334353637383930'*4] ) def test_TOTP_codes_from_nitrokeyapp(secret, C): """ Helper test for manual TOTP check of written secret by Nitrokey App Destined to run by hand """ slot_number = 0 PIN_protection = False period = 30 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_totp_code(slot_number, 0, 0, period)) oath = pytest.importorskip("oath") lib_at = lambda : bb(oath.totp(secret, period=period)) print (lib_at()) assert lib_at() == code_device nitrokey-app-1.3.2/libnitrokey/unittest/test_storage.py0000644000175000017500000003643513275777076023030 0ustar janjan00000000000000""" Copyright (c) 2015-2018 Nitrokey UG This file is part of libnitrokey. libnitrokey is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. libnitrokey is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libnitrokey. If not, see . SPDX-License-Identifier: LGPL-3.0 """ import pprint import pytest from conftest import skip_if_device_version_lower_than from constants import DefaultPasswords, DeviceErrorCode, bb from misc import gs, wait pprint = pprint.PrettyPrinter(indent=4).pprint def get_dict_from_dissect(status): x = [] for s in status.split('\n'): try: if not ':' in s: continue ss = s.replace('\t', '').replace(' (int) ', '').split(':') if not len(ss) == 2: continue x.append(ss) except: pass d = {k.strip(): v.strip() for k, v in x} return d @pytest.mark.other @pytest.mark.info def test_get_status_storage(C): skip_if_device_version_lower_than({'S': 43}) status_pointer = C.NK_get_status_storage_as_string() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK status_string = gs(status_pointer) assert len(status_string) > 0 status_dict = get_dict_from_dissect(status_string.decode('ascii')) default_admin_password_retry_count = 3 assert int(status_dict['AdminPwRetryCount']) == default_admin_password_retry_count print('C.NK_get_major_firmware_version(): {}'.format(C.NK_get_major_firmware_version())) print('C.NK_get_minor_firmware_version(): {}'.format(C.NK_get_minor_firmware_version())) @pytest.mark.other @pytest.mark.info def test_sd_card_usage(C): skip_if_device_version_lower_than({'S': 43}) data_pointer = C.NK_get_SD_usage_data_as_string() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK data_string = gs(data_pointer) assert len(data_string) > 0 data_dict = get_dict_from_dissect(data_string.decode("ascii")) assert int(data_dict['WriteLevelMax']) <= 100 @pytest.mark.encrypted def test_encrypted_volume_unlock(C): skip_if_device_version_lower_than({'S': 43}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.hidden def test_encrypted_volume_unlock_hidden(C): skip_if_device_version_lower_than({'S': 43}) hidden_volume_password = b'hiddenpassword' assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_create_hidden_volume(0, 20, 21, hidden_volume_password) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(hidden_volume_password) == DeviceErrorCode.STATUS_OK @pytest.mark.hidden def test_encrypted_volume_setup_multiple_hidden_lock(C): import random skip_if_device_version_lower_than({'S': 45}) #hangs device on lower version hidden_volume_password = b'hiddenpassword' + bb(str(random.randint(0,100))) p = lambda i: hidden_volume_password + bb(str(i)) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(4): assert C.NK_create_hidden_volume(i, 20+i*10, 20+i*10+i+1, p(i) ) == DeviceErrorCode.STATUS_OK for i in range(4): assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK @pytest.mark.hidden @pytest.mark.parametrize("volumes_to_setup", range(1, 5)) def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes(C, volumes_to_setup): skip_if_device_version_lower_than({'S': 43}) hidden_volume_password = b'hiddenpassword' p = lambda i: hidden_volume_password + bb(str(i)) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_create_hidden_volume(i, 20+i*10, 20+i*10+i+1, p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK # TODO mount and test for files assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK @pytest.mark.hidden @pytest.mark.parametrize("volumes_to_setup", range(1, 5)) def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes_unlock_at_once(C, volumes_to_setup): skip_if_device_version_lower_than({'S': 43}) hidden_volume_password = b'hiddenpassword' p = lambda i: hidden_volume_password + bb(str(i)) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_create_hidden_volume(i, 20+i*10, 20+i*10+i+1, p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK # TODO mount and test for files assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK @pytest.mark.hidden @pytest.mark.parametrize("use_slot", range(4)) def test_encrypted_volume_setup_one_hidden_no_lock_device_slot(C, use_slot): skip_if_device_version_lower_than({'S': 43}) hidden_volume_password = b'hiddenpassword' p = lambda i: hidden_volume_password + bb(str(i)) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK i = use_slot assert C.NK_create_hidden_volume(i, 20+i*10, 20+i*10+i+1, p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for j in range(3): assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK # TODO mount and test for files assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK @pytest.mark.hidden @pytest.mark.PWS def test_password_safe_slot_name_corruption(C): skip_if_device_version_lower_than({'S': 43}) volumes_to_setup = 4 # connected with encrypted volumes, possible also with hidden def fill(s, wid): assert wid >= len(s) numbers = '1234567890' * 4 s += numbers[:wid - len(s)] assert len(s) == wid return bb(s) def get_pass(suffix): return fill('pass' + suffix, 20) def get_loginname(suffix): return fill('login' + suffix, 32) def get_slotname(suffix): return fill('slotname' + suffix, 11) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK PWS_slot_count = 16 for i in range(0, PWS_slot_count): iss = str(i) assert C.NK_write_password_safe_slot(i, get_slotname(iss), get_loginname(iss), get_pass(iss)) == DeviceErrorCode.STATUS_OK def check_PWS_correctness(C): for i in range(0, PWS_slot_count): iss = str(i) assert gs(C.NK_get_password_safe_slot_name(i)) == get_slotname(iss) assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss) assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss) hidden_volume_password = b'hiddenpassword' p = lambda i: hidden_volume_password + bb(str(i)) def check_volumes_correctness(C): for i in range(volumes_to_setup): assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK # TODO mount and test for files assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK check_PWS_correctness(C) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_create_hidden_volume(i, 20+i*10, 20+i*10+i+1, p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK check_volumes_correctness(C) check_PWS_correctness(C) check_volumes_correctness(C) check_PWS_correctness(C) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK check_volumes_correctness(C) check_PWS_correctness(C) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK check_volumes_correctness(C) check_PWS_correctness(C) @pytest.mark.hidden def test_hidden_volume_corruption(C): # bug: this should return error without unlocking encrypted volume each hidden volume lock, but it does not skip_if_device_version_lower_than({'S': 43}) hidden_volume_password = b'hiddenpassword' p = lambda i: hidden_volume_password + bb(str(i)) volumes_to_setup = 4 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_create_hidden_volume(i, 20 + i * 10, 20 + i * 10 + i + 1, p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK wait(2) assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK @pytest.mark.unencrypted def test_unencrypted_volume_set_read_only(C): skip_if_device_version_lower_than({'S': 43}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_set_unencrypted_read_only(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.unencrypted def test_unencrypted_volume_set_read_write(C): skip_if_device_version_lower_than({'S': 43}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_set_unencrypted_read_write(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @pytest.mark.unencrypted def test_unencrypted_volume_set_read_only_admin(C): skip_if_device_version_lower_than({'S': 51}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_set_unencrypted_read_only_admin(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.unencrypted def test_unencrypted_volume_set_read_write_admin(C): skip_if_device_version_lower_than({'S': 51}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_set_unencrypted_read_write_admin(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.encrypted @pytest.mark.skip(reason='not supported on recent firmware, except v0.49') def test_encrypted_volume_set_read_only(C): skip_if_device_version_lower_than({'S': 99}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_set_encrypted_read_only(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.encrypted @pytest.mark.skip(reason='not supported on recent firmware, except v0.49') def test_encrypted_volume_set_read_write(C): skip_if_device_version_lower_than({'S': 99}) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_set_encrypted_read_write(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.other def test_export_firmware(C): skip_if_device_version_lower_than({'S': 43}) assert C.NK_export_firmware(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.other def test_clear_new_sd_card_notification(C): skip_if_device_version_lower_than({'S': 43}) assert C.NK_clear_new_sd_card_warning(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @pytest.mark.encrypted @pytest.mark.slowtest @pytest.mark.skip(reason='long test (about 1h)') def test_fill_SD_card(C): skip_if_device_version_lower_than({'S': 43}) status = C.NK_fill_SD_card_with_random_data(DefaultPasswords.ADMIN) assert status == DeviceErrorCode.STATUS_OK or status == DeviceErrorCode.BUSY while 1: value = C.NK_get_progress_bar_value() if value == -1: break assert 0 <= value <= 100 assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK wait(5) @pytest.mark.other @pytest.mark.info def test_get_busy_progress_on_idle(C): skip_if_device_version_lower_than({'S': 43}) value = C.NK_get_progress_bar_value() assert value == -1 assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @pytest.mark.update def test_change_update_password(C): skip_if_device_version_lower_than({'S': 43}) wrong_password = b'aaaaaaaaaaa' assert C.NK_change_update_password(wrong_password, DefaultPasswords.UPDATE_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_update_password(DefaultPasswords.UPDATE, DefaultPasswords.UPDATE_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_change_update_password(DefaultPasswords.UPDATE_TEMP, DefaultPasswords.UPDATE) == DeviceErrorCode.STATUS_OK @pytest.mark.skip(reason='no reversing method added yet') @pytest.mark.update def test_enable_firmware_update(C): skip_if_device_version_lower_than({'S': 50}) wrong_password = b'aaaaaaaaaaa' assert C.NK_enable_firmware_update(wrong_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_enable_firmware_update(DefaultPasswords.UPDATE) == DeviceErrorCode.STATUS_OK @pytest.mark.other def test_send_startup(C): skip_if_device_version_lower_than({'S': 43}) time_seconds_from_epoch = 0 # FIXME set proper date assert C.NK_send_startup(time_seconds_from_epoch) == DeviceErrorCode.STATUS_OK nitrokey-app-1.3.2/3rdparty/cppcodec/.gitignore0000644000175000017500000000004513221173144021016 0ustar janjan00000000000000CMakeLists.txt.user .*.swp .DS_Store nitrokey-app-1.3.2/3rdparty/cppcodec/.gitmodules0000644000175000017500000000000013232102405021164 0ustar janjan00000000000000nitrokey-app-1.3.2/3rdparty/cppcodec/.travis.yml0000644000175000017500000000460413221173144021144 0ustar janjan00000000000000language: cpp # sources list: https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json, # packages list: https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise matrix: include: - os: linux compiler: gcc addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'g++-4.8', 'libstdc++-4.8-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=DEBUG GXX=4.8 - os: linux compiler: gcc addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'g++-4.8', 'libstdc++-4.8-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=RELEASE GXX=4.8 - os: linux compiler: gcc addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'g++-4.9', 'libstdc++-4.9-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=DEBUG GXX=4.9 - os: linux compiler: gcc addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'g++-4.9', 'libstdc++-4.9-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=RELEASE GXX=4.9 - os: linux compiler: gcc addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'g++-5', 'libstdc++-5-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=DEBUG GXX=5 - os: linux compiler: gcc addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'g++-5', 'libstdc++-5-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=RELEASE GXX=5 - os: linux compiler: clang addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'libstdc++-4.8-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=DEBUG - os: linux compiler: clang addons: apt: sources: [ 'ubuntu-toolchain-r-test', 'kalakris-cmake' ] packages: [ 'libstdc++-4.8-dev', 'cmake' ] env: CMAKE_BUILD_TYPE=RELEASE # container-based builds sudo: false before_install: - env - export SRC_DIR="`pwd`" - if [ "$CXX" = "g++" ]; then export CXX="g++-$GXX" CC="gcc-$GXX"; fi script: - $CXX --version - cmake --version - mkdir "$TRAVIS_BUILD_DIR/build" - cd "$TRAVIS_BUILD_DIR/build" - pwd - cmake "$SRC_DIR" - make - CTEST_OUTPUT_ON_FAILURE=1 make test nitrokey-app-1.3.2/3rdparty/cppcodec/CMakeLists.txt0000644000175000017500000000336413221173144021575 0ustar janjan00000000000000cmake_minimum_required(VERSION 2.8) project(cppcodec) option(build_tests "Build tests (run as 'test' target)" ON) # These flags are for binaries built by this particular CMake project (test_cppcodec, base64enc, etc.). # In your own project that uses cppcodec, you might want to specify a different standard or error level. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") set(PUBLIC_HEADERS # base32 cppcodec/base32_crockford.hpp cppcodec/base32_default_crockford.hpp cppcodec/base32_default_hex.hpp cppcodec/base32_default_rfc4648.hpp cppcodec/base32_hex.hpp cppcodec/base32_rfc4648.hpp # base64 cppcodec/base64_default_rfc4648.hpp cppcodec/base64_default_url.hpp cppcodec/base64_rfc4648.hpp cppcodec/base64_url.hpp # hex cppcodec/hex_default_lower.hpp cppcodec/hex_default_upper.hpp cppcodec/hex_lower.hpp cppcodec/hex_upper.hpp # other stuff cppcodec/parse_error.hpp cppcodec/data/access.hpp cppcodec/data/raw_result_buffer.hpp cppcodec/detail/base32.hpp cppcodec/detail/base64.hpp cppcodec/detail/codec.hpp cppcodec/detail/config.hpp cppcodec/detail/hex.hpp cppcodec/detail/stream_codec.hpp) add_library(cppcodec OBJECT ${PUBLIC_HEADERS}) # unnecessary for building, but makes headers show up in IDEs set_target_properties(cppcodec PROPERTIES LINKER_LANGUAGE CXX) add_subdirectory(tool) if (build_tests) enable_testing() add_subdirectory(test) endif() foreach(h ${PUBLIC_HEADERS}) get_filename_component(HEADER_INCLUDE_DIRECTORY include/${h} PATH) # use DIRECTORY instead of PATH once requiring CMake 3.0 install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${h} DESTINATION ${HEADER_INCLUDE_DIRECTORY} COMPONENT "headers") endforeach() nitrokey-app-1.3.2/3rdparty/cppcodec/LICENSE.txt0000644000175000017500000000210513221173144020650 0ustar janjan00000000000000The MIT License (MIT) (See individual files for copyright holders.) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. nitrokey-app-1.3.2/3rdparty/cppcodec/README.md0000644000175000017500000002407313221173144020314 0ustar janjan00000000000000# cppcodec [![Build Status](https://travis-ci.org/tplgy/cppcodec.png)](https://travis-ci.org/tplgy/cppcodec) Header-only C++11 library to encode/decode base64, base64url, base32, base32hex and hex (a.k.a. base16) as specified in RFC 4648, plus Crockford's base32. MIT licensed with consistent, flexible API. Supports raw pointers, `std::string` and (templated) character vectors without unnecessary allocations. # Usage 1. Import cppcodec into your project (copy, git submodule, etc.) 2. Add the cppcodec root directory to your build system's list of include directories 3. Include headers and start using the API. Since cppcodec is a header-only library, no extra build step is needed. Alternatively, you can install the headers and build extra tools/tests with CMake. # Variants A number of codec variants exist for base64 and base32, defining different alphabets or specifying the use of padding and line breaks in different ways. cppcodec is designed to let you make a conscious choice about which one you're using, but assumes you will mostly stick to a single one. cppcodec's approach is to implement encoding/decoding algorithms in different namespaces (e.g. `cppcodec::base64_rfc4648`) and in addition to the natural headers, also offer convenience headers to define a shorthand alias (e.g. `base64`) for one of the variants. Here is an expected standard use of cppcodec: ```C++ #include #include #include int main() { std::vector decoded = base64::decode("YW55IGNhcm5hbCBwbGVhc3VyZQ=="); std::cout << "decoded size (\"any carnal pleasure\"): " << decoded.size() << '\n'; std::cout << base32::encode(decoded) << std::endl; // "C5Q7J833C5S6WRBC41R6RSB1EDTQ4S8" return 0; } ``` If possible, avoid including "default" headers in other header files. Non-aliasing headers omit the "default" part, e.g. `` or ``. Currently supported variants are: ### base64 * `base64_rfc4648` uses the PEM/MIME/UTF-7 alphabet, that is (in order) A-Z, a-z, 0-9 plus characters '+' and '/'. This is what's usually considered the "standard base64" that you see everywhere and requires padding ('=') but no line breaks. Whitespace and other out-of-alphabet symbols are regarded as a parse error. * `base64_url` is the same as `base64_rfc4648` (and defined in the same RFC) but uses '-' (minus) and '_' (underscore) as special characters instead of '+' and '/'. This is safe to use for URLs and file names. Padding with '=' is still required. * `base64_url_unpadded` variant is the same as `base64_url`, if you want to do without padding (which, for this one, is optional). ### base32 All base32 variants encode 5 bits as one (8-bit) character, which results in an encoded length of roughly 160% (= 8/5). Their selling point is mainly case-insensitive decoding, no special characters and alphabets that can be communicated via phone. * `base32_rfc4648` implements the popular, standardized variant defined in RFC 4648. It uses the full upper-case alphabet A-Z for the first 26 values and the digit characters 2-7 for the last ten. Padding with '=' is required and makes the encoded string a multiple of 8 characters. The codec accepts no invalid symbols, so if you want to let the user enter base32 data then consider replacing numbers '0', '1' and '8' with 'O', 'I' and 'B' on input. * `base32_crockford` implements [Crockford base32](http://www.crockford.com/wrmg/base32.html). It's less widely used than the RFC 4648 alphabet, but offers a more carefully picked alphabet and also defines decoding similar characters 'I', 'i', 'L' 'l' as '1' plus 'O' and 'o' as '0' so no care is required for user input. Crockford base32 does not use '=' padding. Checksums are not implemented. Note that the specification is ambiguous about whether to pad bit quintets to the left or to the right, i.e. whether the codec is a place-based single number encoding system or a concatenative iterative stream encoder. This codec variant picks the streaming interpretation and thus zero-pads on the right. (See http://merrigrove.blogspot.ca/2014/04/what-heck-is-base64-encoding-really.html for a detailed discussion of the issue.) * `base32_hex` is the logical extension of the hexadecimal alphabet, and also specified in RFC 4648. It uses the digit characters 0-9 for the first 10 values and the upper-case letters A-V for the remaining ones. The alphabet is conceptually simple, but contains all of the ambiguous number/letter pairs that the other variants try to avoid. It is also less suitable for verbal transmission. Padding with '=' is required and makes the encoded string a multiple of 8 characters. ### hex * `hex_upper` outputs upper-case letters and accepts lower-case as well. This is an octet-streaming codec variant and for decoding, requires an even number of input symbols. In other words, don't try to decode (0x)"F", (0x)"10F" etc. with this variant, use a place-based single number codec instead if you want to do this. Also, you are expected to prepend and remove a "0x" prefix externally as it won't be generated when encoding / will be rejected when decoding. * `hex_lower` outputs lower-case letters and accepts upper-case as well. Similar to `hex_upper`, it's stream-based (no odd symbol lengths) and does not deal with "0x" prefixes. # API All codecs expose the same API. In the below documentation, replace `` with a default alias such as `base64`, `base32` or `hex`, or with the full namespace such as `cppcodec::base64_rfc4648` or `cppcodec::base32_crockford`. For templated parameters `T` and `Result`, you can use e.g. `std::vector`, `std::string` or anything that supports: * `.data()` and `.size()` for `T` (read-only) template parameters, * for `Result` template parameters, also `.reserve(size_t)`, `.resize(size_t)` and `.push_back([uint8_t|char])`. It's possible to support types lacking these functions, consult the code directly if you need this. ### Encoding ```C++ // Convenient version, returns an std::string. std::string ::encode(const [uint8_t|char]* binary, size_t binary_size); std::string ::encode(const T& binary); // Convenient version with templated result type. Result ::encode(const [uint8_t|char]* binary, size_t binary_size); Result ::encode(const T& binary); // Reused result container version. Resizes encoded_result before writing to it. void ::encode(Result& encoded_result, const [uint8_t|char]* binary, size_t binary_size); void ::encode(Result& encoded_result, const T& binary); ``` Encode binary data into an encoded (base64/base32/hex) string. Won't throw by itself, but the result type might throw on `.resize()`. ```C++ size_t ::encode(char* encoded_result, size_t encoded_buffer_size, const [uint8_t|char]* binary, size_t binary_size) noexcept; size_t ::encode(char* encoded_result, size_t encoded_buffer_size, const T& binary) noexcept; ``` Encode binary data into pre-allocated memory with a buffer size of `::encoded_size(binary_size)` or larger. Returns the byte size of the encoded string excluding null termination, which is equal to `::encoded_size(binary_size)`. If `encoded_buffer_size` is larger than required, a single null termination character (`'\0'`) is written after the last encoded character. The `encoded_size()` function ensures that the required buffer size is large enough to hold the padding required for the respective codec variant. Provide a buffer of size `encoded_size() + 1` to make it a null-terminated C string. Calls abort() if `encoded_buffer_size` is insufficient. (That way, the function can remain `noexcept` rather than throwing on an entirely avoidable error condition.) ```C++ size_t ::encoded_size(size_t binary_size) noexcept; ``` Calculate the (exact) length of the encoded string based on binary size, excluding null termination but including padding (if specified by the codec variant). ### Decoding ```C++ // Convenient version, returns an std::vector. std::vector ::decode(const char* encoded, size_t encoded_size); std::vector ::decode(const T& encoded); // Convenient version with templated result type. Result ::decode(const char* encoded, size_t encoded_size); Result ::decode(const T& encoded); // Reused result container version. Resizes binary_result before writing to it. void ::decode(Result& binary_result, const char* encoded, size_t encoded_size); void ::decode(Result& binary_result, const T& encoded); ``` Decode an encoded (base64/base32/hex) string into a binary buffer. Throws a cppcodec::parse_error exception (inheriting from std::domain_error) if the input data does not conform to the codec variant specification. Also, the result type might throw on `.resize()`. ```C++ size_t ::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size); size_t ::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const T& encoded); ``` Decode an encoded string into pre-allocated memory with a buffer size of `::decoded_max_size(encoded_size)` or larger. Returns the byte size of the decoded binary data, which is less or equal to `::decoded_max_size(encoded_size)`. Calls abort() if `binary_buffer_size` is insufficient, for consistency with encode(). Throws a cppcodec::parse_error exception (inheriting from std::domain_error) if the input data does not conform to the codec variant specification. ```C++ size_t ::decoded_max_size(size_t encoded_size) noexcept; ``` Calculate the maximum size of the decoded binary buffer based on the encoded string length. If the codec variant does not allow padding or whitespace / line breaks, the maximum decoded size will be the exact decoded size. If the codec variant allows padding or whitespace / line breaks, the actual decoded size might be smaller. If you're using the pre-allocated memory result call, make sure to take its return value (the actual decoded size) into account. nitrokey-app-1.3.2/3rdparty/cppcodec/TODO.md0000644000175000017500000000750413221173144020124 0ustar janjan00000000000000# TODO cppcodec is in pretty good shape already. Here are a number of things I'd like to do still: * Stuff in the GitHub issues list. * Implement place-based single number codecs (as opposed to stream codecs) that view the entire input string as a single number and therefore zero-extend *to the left* to the next bit multiple (e.g. n*5 for base32, n*4 for hex). We want this to implement odd hex decoding (e.g. 0xF rather than 0x0F) and the other interpretation of Crockford base32. No use case seems to exist for base64 because it's thankfully specified well enough to always encode octet streams, not numbers. * API idea: Specialize the encode(Result&, const T&) overload to for T = number and use that to accept numbers without changing the interface. Not sure if it's a good idea to switch to a place-based single number codec based on T. * API idea: Instead of trying to fit both into the same interface, make a separate interface just for numbers. No binary arrays, templates only on the encoded side. * Naming: Current plan is to name place-based single number variants as the original variant name plus `_num` appended. Examples: `base32_crockford_num`, `hex_upper_num`, `hex_lower_num`. * Since we don't know the total number of symbols (could be ignored characters?) we might have to **(a)** assume there is no whitespace (fail) or **(b)** walk the source data twice, the first time for counting symbols and the second time for putting them into their right spot in the byte. * Investigate binary size considerations. See how well inline deduplication works in popular linkers. I've had good experiences with boost::asio but I don't know if those can translate to a codec library. * See if binary size would be saved if std::vector<[unsigned] char> could return a temporary raw_result_buffer instead of being passed down as itself, for use cases where both std::vector and raw pointer calls are in use. * Benchmark our performance against other libraries. We should be pretty fast since cppcodec is avoiding unnecessary copies or object construction, but we're also not doing any special vectorization or inline assembly. Plus it would be nice to know that the compiler optimizes the inline function calls well, instead of merely assuming it. * More codec variants: * binary - useful for debugging * octal * z-base32 might be interesting (and has some funky marginal-space-savings options if your input length isn't octets), but doesn't appear any more popular than Crockford base32. Pretty far down on the list. * base64 variants from PEM (RFC 1421), MIME (RFC 2045) and UTF-7 (RFC 2152) since they're popular and less strict than RFC 4648. Requires more sophisticated generation of whitespace and ideally also checks whether the whitespace is correctly located in the input string. * Proquints? I'm not quite sure about how useful those are in real life. * Checksums: Crockford base32 and RFC 6920 unpadded base64url define optional checksums, OpenPGP base64 has a mandatory one. Supporting these would mean a change to the API, potentially together with other options (but not necessarily so). * User options: I'm not too big on accepting invalid/non-conformant input, but maybe somebody has a valid use case where they need to be more lenient than one of the standards where the solution shouldn't be a new codec variant but instead options for an existing variant? I'm not convinced that's a good idea right now, but if you think it is then please make a point. * We'll probably want some kind of unspecified whitespace acceptance for hex, maybe there should just be a template version of cppcodec::hex for that with ignored characters as the template. * Crockford base32 allows hyphens as visual delimiter (ignored when decoding) but doesn't specify nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base32_crockford.hpp0000644000175000017500000001060413221173144024434 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE32_CROCKFORD #define CPPCODEC_BASE32_CROCKFORD #include "detail/codec.hpp" #include "detail/base32.hpp" namespace cppcodec { namespace detail { static constexpr const char base32_crockford_alphabet[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // at index 10 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 18 - no I 'J', 'K', // 20 - no L 'M', 'N', // 22 - no O 'P', 'Q', 'R', 'S', 'T', // 27 - no U 'V', 'W', 'X', 'Y', 'Z' // 32 }; static_assert(sizeof(base32_crockford_alphabet) == 32, "base32 alphabet must have 32 values"); class base32_crockford_base { public: static inline constexpr bool generates_padding() { return false; } static inline constexpr bool requires_padding() { return false; } static inline constexpr bool is_padding_symbol(char /*c*/) { return false; } static inline constexpr char symbol(uint8_t index) { return base32_crockford_alphabet[index]; } static inline constexpr uint8_t index_of(char c) { return (c >= '0' && c <= '9') ? (c - '0') // upper-case letters : (c >= 'A' && c <= 'H') ? (c - 'A' + 10) // no I : (c >= 'J' && c <= 'K') ? (c - 'J' + 18) // no L : (c >= 'M' && c <= 'N') ? (c - 'M' + 20) // no O : (c >= 'P' && c <= 'T') ? (c - 'P' + 22) // no U : (c >= 'V' && c <= 'Z') ? (c - 'V' + 27) // lower-case letters : (c >= 'a' && c <= 'h') ? (c - 'a' + 10) // no I : (c >= 'j' && c <= 'k') ? (c - 'j' + 18) // no L : (c >= 'm' && c <= 'n') ? (c - 'm' + 20) // no O : (c >= 'p' && c <= 't') ? (c - 'p' + 22) // no U : (c >= 'v' && c <= 'z') ? (c - 'v' + 27) : (c == '-') ? 253 // "Hyphens (-) can be inserted into strings [for readability]." : (c == '\0') ? 255 // stop at end of string // special cases : (c == 'O' || c == 'o') ? 0 : (c == 'I' || c == 'i' || c == 'L' || c == 'l') ? 1 : throw symbol_error(c); } static inline constexpr bool should_ignore(uint8_t index) { return index == 253; } static inline constexpr bool is_special_character(uint8_t index) { return index > 32; } static inline constexpr bool is_eof(uint8_t index) { return index == 255; } }; // base32_crockford is a concatenative iterative (i.e. streaming) interpretation of Crockford base32. // It interprets the statement "zero-extend the number to make its bit-length a multiple of 5" // to mean zero-extending it on the right. // (The other possible interpretation is base32_crockford_num, a place-based single number encoding system. // See http://merrigrove.blogspot.ca/2014/04/what-heck-is-base64-encoding-really.html for more info.) class base32_crockford : public base32_crockford_base { public: template using codec_impl = stream_codec; }; } // namespace detail using base32_crockford = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_BASE32_CROCKFORD nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base32_default_crockford.hpp0000644000175000017500000000252613221173144026144 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE32_DEFAULT_CROCKFORD #define CPPCODEC_BASE32_DEFAULT_CROCKFORD #include "base32_crockford.hpp" using base32 = cppcodec::base32_crockford; #endif // CPPCODEC_BASE32_DEFAULT_CROCKFORD nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base32_default_hex.hpp0000644000175000017500000000247613221173144024760 0ustar janjan00000000000000/** * Copyright (C) 2015, 2016 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE32_DEFAULT_HEX #define CPPCODEC_BASE32_DEFAULT_HEX #include "base32_hex.hpp" using base32 = cppcodec::base32_hex; #endif // CPPCODEC_BASE32_DEFAULT_HEX nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base32_default_rfc4648.hpp0000644000175000017500000000251413221173144025265 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE32_DEFAULT_RFC4648 #define CPPCODEC_BASE32_DEFAULT_RFC4648 #include "base32_rfc4648.hpp" using base32 = cppcodec::base32_rfc4648; #endif // CPPCODEC_BASE32_DEFAULT_RFC4648 nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base32_hex.hpp0000644000175000017500000000613613221173144023251 0ustar janjan00000000000000/** * Copyright (C) 2015, 2016 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE32_HEX #define CPPCODEC_BASE32_HEX #include "detail/codec.hpp" #include "detail/base32.hpp" namespace cppcodec { namespace detail { // RFC 4648 uses a simple alphabet: A-Z starting at index 0, then 2-7 starting at index 26. static constexpr const char base32_hex_alphabet[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' }; static_assert(sizeof(base32_hex_alphabet) == 32, "base32 alphabet must have 32 values"); class base32_hex { public: template using codec_impl = stream_codec; static inline constexpr bool generates_padding() { return true; } static inline constexpr bool requires_padding() { return true; } static inline constexpr char padding_symbol() { return '='; } static inline constexpr char symbol(uint8_t index) { return base32_hex_alphabet[index]; } static inline constexpr uint8_t index_of(char c) { return (c >= '0' && c <= '9') ? (c - '0') : (c >= 'A' && c <= 'V') ? (c - 'A' + 10) : (c == padding_symbol()) ? 254 : (c == '\0') ? 255 // stop at end of string : (c >= 'a' && c <= 'v') ? (c - 'a' + 10) // lower-case: not expected, but accepted : throw symbol_error(c); } // RFC4648 does not specify any whitespace being allowed in base32 encodings. static inline constexpr bool should_ignore(uint8_t /*index*/) { return false; } static inline constexpr bool is_special_character(uint8_t index) { return index > 32; } static inline constexpr bool is_padding_symbol(uint8_t index) { return index == 254; } static inline constexpr bool is_eof(uint8_t index) { return index == 255; } }; } // namespace detail using base32_hex = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_BASE32_HEX nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base32_rfc4648.hpp0000644000175000017500000000621213221173144023560 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE32_RFC4648 #define CPPCODEC_BASE32_RFC4648 #include "detail/codec.hpp" #include "detail/base32.hpp" namespace cppcodec { namespace detail { // RFC 4648 uses a simple alphabet: A-Z starting at index 0, then 2-7 starting at index 26. static constexpr const char base32_rfc4648_alphabet[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', // at index 26 '2', '3', '4', '5', '6', '7' }; static_assert(sizeof(base32_rfc4648_alphabet) == 32, "base32 alphabet must have 32 values"); class base32_rfc4648 { public: template using codec_impl = stream_codec; static inline constexpr bool generates_padding() { return true; } static inline constexpr bool requires_padding() { return true; } static inline constexpr char padding_symbol() { return '='; } static inline constexpr char symbol(uint8_t index) { return base32_rfc4648_alphabet[index]; } static inline constexpr uint8_t index_of(char c) { return (c >= 'A' && c <= 'Z') ? (c - 'A') : (c >= '2' && c <= '7') ? (c - '2' + 26) : (c == padding_symbol()) ? 254 : (c == '\0') ? 255 // stop at end of string : (c >= 'a' && c <= 'z') ? (c - 'a') // lower-case: not expected, but accepted : throw symbol_error(c); } // RFC4648 does not specify any whitespace being allowed in base32 encodings. static inline constexpr bool should_ignore(uint8_t /*index*/) { return false; } static inline constexpr bool is_special_character(uint8_t index) { return index > 32; } static inline constexpr bool is_padding_symbol(uint8_t index) { return index == 254; } static inline constexpr bool is_eof(uint8_t index) { return index == 255; } }; } // namespace detail using base32_rfc4648 = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_BASE32_RFC4648 nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base64_default_rfc4648.hpp0000644000175000017500000000251413221173144025272 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE64_DEFAULT_RFC4648 #define CPPCODEC_BASE64_DEFAULT_RFC4648 #include "base64_rfc4648.hpp" using base64 = cppcodec::base64_rfc4648; #endif // CPPCODEC_BASE64_DEFAULT_RFC4648 nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base64_default_url.hpp0000644000175000017500000000247013221173144024775 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE64_DEFAULT_URL #define CPPCODEC_BASE64_DEFAULT_URL #include "base64_url.hpp" using base64 = cppcodec::base64_url; #endif // CPPCODEC_BASE64_DEFAULT_URL nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base64_default_url_unpadded.hpp0000644000175000017500000000254513221173144026644 0ustar janjan00000000000000/** * Copyright (C) 2016 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE64_DEFAULT_URL_UNPADDED #define CPPCODEC_BASE64_DEFAULT_URL_UNPADDED #include "base64_url_unpadded.hpp" using base64 = cppcodec::base64_url_unpadded; #endif // CPPCODEC_BASE64_DEFAULT_URL_UNPADDED nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base64_rfc4648.hpp0000644000175000017500000000637613221173144023600 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE64_RFC4648 #define CPPCODEC_BASE64_RFC4648 #include "detail/codec.hpp" #include "detail/base64.hpp" namespace cppcodec { namespace detail { static constexpr const char base64_rfc4648_alphabet[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; static_assert(sizeof(base64_rfc4648_alphabet) == 64, "base64 alphabet must have 64 values"); class base64_rfc4648 { public: template using codec_impl = stream_codec; static inline constexpr bool generates_padding() { return true; } static inline constexpr bool requires_padding() { return true; } static inline constexpr char padding_symbol() { return '='; } static inline constexpr char symbol(uint8_t index) { return base64_rfc4648_alphabet[index]; } static inline constexpr uint8_t index_of(char c) { return (c >= 'A' && c <= 'Z') ? (c - 'A') : (c >= 'a' && c <= 'z') ? (c - 'a' + 26) : (c >= '0' && c <= '9') ? (c - '0' + 52) : (c == '+') ? (c - '+' + 62) : (c == '/') ? (c - '/' + 63) : (c == padding_symbol()) ? 254 : (c == '\0') ? 255 // stop at end of string : throw symbol_error(c); } // RFC4648 does not specify any whitespace being allowed in base64 encodings. static inline constexpr bool should_ignore(uint8_t /*index*/) { return false; } static inline constexpr bool is_special_character(uint8_t index) { return index > 64; } static inline constexpr bool is_padding_symbol(uint8_t index) { return index == 254; } static inline constexpr bool is_eof(uint8_t index) { return index == 255; } }; } // namespace detail using base64_rfc4648 = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_BASE64_RFC4648 nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base64_url.hpp0000644000175000017500000000660513221173144023275 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE64_URL #define CPPCODEC_BASE64_URL #include "detail/codec.hpp" #include "detail/base64.hpp" namespace cppcodec { namespace detail { // The URL and filename safe alphabet is also specified by RFC4648, named "base64url". // We keep the underscore ("base64_url") for consistency with the other codec variants. static constexpr const char base64_url_alphabet[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' }; static_assert(sizeof(base64_url_alphabet) == 64, "base64 alphabet must have 64 values"); class base64_url { public: template using codec_impl = stream_codec; static inline constexpr bool generates_padding() { return true; } static inline constexpr bool requires_padding() { return true; } static inline constexpr char padding_symbol() { return '='; } static inline constexpr char symbol(uint8_t index) { return base64_url_alphabet[index]; } static inline constexpr uint8_t index_of(char c) { return (c >= 'A' && c <= 'Z') ? (c - 'A') : (c >= 'a' && c <= 'z') ? (c - 'a' + 26) : (c >= '0' && c <= '9') ? (c - '0' + 52) : (c == '-') ? (c - '-' + 62) : (c == '_') ? (c - '_' + 63) : (c == padding_symbol()) ? 254 : (c == '\0') ? 255 // stop at end of string : throw symbol_error(c); } // RFC4648 does not specify any whitespace being allowed in base64 encodings. static inline constexpr bool should_ignore(uint8_t /*index*/) { return false; } static inline constexpr bool is_special_character(uint8_t index) { return index > 64; } static inline constexpr bool is_padding_symbol(uint8_t index) { return index == 254; } static inline constexpr bool is_eof(uint8_t index) { return index == 255; } }; } // namespace detail using base64_url = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_BASE64_URL nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/base64_url_unpadded.hpp0000644000175000017500000000335513221173144025140 0ustar janjan00000000000000/** * Copyright (C) 2016 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_BASE64_URL_UNPADDED #define CPPCODEC_BASE64_URL_UNPADDED #include "base64_url.hpp" namespace cppcodec { namespace detail { class base64_url_unpadded : public base64_url { public: template using codec_impl = stream_codec; static inline constexpr bool generates_padding() { return false; } static inline constexpr bool requires_padding() { return false; } }; } // namespace detail using base64_url_unpadded = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_BASE64_URL_UNPADDED nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/data/access.hpp0000644000175000017500000001445713221173144023505 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_DETAIL_DATA_ACCESS #define CPPCODEC_DETAIL_DATA_ACCESS #include // for size_t namespace cppcodec { namespace data { // This file contains a number of templated data accessors that can be // implemented in the cppcodec::data namespace for types that don't fulfill // the default type requirements: // For result types: init(Result&, ResultState&, size_t capacity), // put(Result&, ResultState&, char), finish(Result&, State&) // For const (read-only) types: char_data(const T&) // For both const and result types: size(const T&) template inline size_t size(const T& t) { return t.size(); } template inline constexpr size_t size(const T (&t)[N]) noexcept { return N * sizeof(t[0]); } class general_t {}; class specific_t : public general_t {}; class empty_result_state { template inline void size(const Result& result) { return size(result); } }; // SFINAE: Generic fallback in case no specific state function applies. template inline empty_result_state create_state(Result&, general_t) { return empty_result_state(); } // // Generic templates for containers: Use these init()/put()/finish() // implementations if no specialization was found. // template inline void init(Result& result, empty_result_state&, size_t capacity) { result.resize(0); result.reserve(capacity); } template inline void finish(Result&, empty_result_state&) { // Default is to push_back(), which already increases the size. } // For the put() default implementation, we try calling push_back() with either uint8_t or char, // whichever compiles. Scary-fancy template magic from http://stackoverflow.com/a/1386390. namespace fallback { struct flag { char c[2]; }; // sizeof > 1 flag put_uint8(...); int operator,(flag, flag); template void operator,(flag, T&); // map everything else to void char operator,(int, flag); // sizeof 1 } template inline void put_uint8(Result& result, uint8_t c) { result.push_back(c); } template struct put_impl; template <> struct put_impl { // put_uint8() available template static void put(Result& result, uint8_t c) { put_uint8(result, c); } }; template <> struct put_impl { // put_uint8() not available template static void put(Result& result, uint8_t c) { result.push_back(static_cast(c)); } }; template inline void put(Result& result, empty_result_state&, uint8_t c) { using namespace fallback; put_impl::put(result, c); } // // Specialization for container types with direct mutable data access. // The expected way to specialize is to subclass empty_result_state and // return an instance of it from a create_state() template specialization. // You can then create overloads for init(), put() and finish() // that are more specific than the empty_result_state ones above. // See the example below for direct access to a mutable data() method. // // If desired, a non-templated overload for both specific types // (result & state) can be added to tailor it to that particular result type. // template class direct_data_access_result_state : empty_result_state { public: using result_type = Result; inline void init(Result& result, size_t capacity) { // resize(0) is not called here since we don't rely on it result.reserve(capacity); } inline void put(Result& result, char c) { // This only compiles if decltype(data) == char* result.data()[m_offset++] = static_cast(c); } inline void finish(Result& result) { result.resize(m_offset); } inline size_t size(const Result&) { return m_offset; } private: size_t m_offset = 0; }; // SFINAE: Select a specific state based on the result type and possible result state type. // Implement this if direct data access (`result.data()[0] = 'x') isn't already possible // and you want to specialize it for your own result type. template ::result_type::value> inline ResultState create_state(Result&, specific_t) { return ResultState(); } template inline void init(Result& result, direct_data_access_result_state& state, size_t capacity) { state.init(result); } // Specialized put function for direct_data_access_result_state. template inline void put(Result& result, direct_data_access_result_state& state, char c) { state.put(result, c); } // char_data() is only used to read, not for result buffers. template inline const char* char_data(const T& t) { return reinterpret_cast(t.data()); } template inline const char* char_data(const T (&t)[N]) noexcept { return reinterpret_cast(&(t[0])); } template inline const uint8_t* uchar_data(const T& t) { return reinterpret_cast(char_data(t)); } } // namespace data } // namespace cppcodec #endif nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/data/raw_result_buffer.hpp0000644000175000017500000000446013221173144025755 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_DETAIL_RAW_RESULT_BUFFER #define CPPCODEC_DETAIL_RAW_RESULT_BUFFER #include // for size_t #include // for abort() #include "access.hpp" namespace cppcodec { namespace data { class raw_result_buffer { public: raw_result_buffer(char* data, size_t capacity) : m_ptr(data + capacity) , m_begin(data) { } char last() const { return *(m_ptr - 1); } void push_back(char c) { *m_ptr = c; ++m_ptr; } size_t size() const { return m_ptr - m_begin; } void resize(size_t size) { m_ptr = m_begin + size; } private: char* m_ptr; char* m_begin; }; template <> inline void init( raw_result_buffer& result, empty_result_state&, size_t capacity) { // This version of init() doesn't do a reserve(), and instead checks whether the // initial size (capacity) is enough before resizing to 0. // The codec is expected not to exceed this capacity. if (capacity > result.size()) { abort(); } result.resize(0); } template <> inline void finish(raw_result_buffer&, empty_result_state&) { } } // namespace data } // namespace cppcodec #endif nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/detail/base32.hpp0000644000175000017500000001424313221173144023645 0ustar janjan00000000000000/** * Copyright (C) 2015 Trustifier Inc. * Copyright (C) 2015 Ahmed Masud * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Adapted from https://github.com/ahmed-masud/libbase32, * commit 79761b2b79b0545697945efe0987a8d3004512f9. * Quite different now. */ #ifndef CPPCODEC_DETAIL_BASE32 #define CPPCODEC_DETAIL_BASE32 #include #include // for abort() #include "../data/access.hpp" #include "../parse_error.hpp" #include "config.hpp" #include "stream_codec.hpp" namespace cppcodec { namespace detail { template class base32 : public CodecVariant::template codec_impl> { public: static inline constexpr uint8_t binary_block_size() { return 5; } static inline constexpr uint8_t encoded_block_size() { return 8; } static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t num_bytes) { return (num_bytes == 1) ? 2 // 2 symbols, 6 padding characters : (num_bytes == 2) ? 4 // 4 symbols, 4 padding characters : (num_bytes == 3) ? 5 // 5 symbols, 3 padding characters : (num_bytes == 4) ? 7 // 7 symbols, 1 padding characters : throw std::domain_error("invalid number of bytes in a tail block"); } template CPPCODEC_ALWAYS_INLINE static constexpr uint8_t index( const uint8_t* b /*binary block*/) { return (I == 0) ? ((b[0] >> 3) & 0x1F) // first 5 bits : (I == 1) ? (((b[0] << 2) & 0x1C) | ((b[1] >> 6) & 0x3)) : (I == 2) ? ((b[1] >> 1) & 0x1F) : (I == 3) ? (((b[1] << 4) & 0x10) | ((b[2] >> 4) & 0xF)) : (I == 4) ? (((b[2] << 1) & 0x1E) | ((b[3] >> 7) & 0x1)) : (I == 5) ? ((b[3] >> 2) & 0x1F) : (I == 6) ? (((b[3] << 3) & 0x18) | ((b[4] >> 5) & 0x7)) : (I == 7) ? (b[4] & 0x1F) // last 5 bits : throw std::domain_error("invalid encoding symbol index in a block"); } template CPPCODEC_ALWAYS_INLINE static constexpr uint8_t index_last( const uint8_t* b /*binary block*/) { return (I == 1) ? ((b[0] << 2) & 0x1C) // abbreviated 2nd symbol : (I == 3) ? ((b[1] << 4) & 0x10) // abbreviated 4th symbol : (I == 4) ? ((b[2] << 1) & 0x1E) // abbreviated 5th symbol : (I == 6) ? ((b[3] << 3) & 0x18) // abbreviated 7th symbol : throw std::domain_error("invalid last encoding symbol index in a tail"); } template static void decode_block(Result& decoded, ResultState&, const uint8_t* idx); template static void decode_tail(Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len); }; // // 11111111 10101010 10110011 10111100 10010100 // => 11111 11110 10101 01011 00111 01111 00100 10100 // template template inline void base32::decode_block( Result& decoded, ResultState& state, const uint8_t* idx) { put(decoded, state, static_cast(((idx[0] << 3) & 0xF8) | ((idx[1] >> 2) & 0x7))); put(decoded, state, static_cast(((idx[1] << 6) & 0xC0) | ((idx[2] << 1) & 0x3E) | ((idx[3] >> 4) & 0x1))); put(decoded, state, static_cast(((idx[3] << 4) & 0xF0) | ((idx[4] >> 1) & 0xF))); put(decoded, state, static_cast(((idx[4] << 7) & 0x80) | ((idx[5] << 2) & 0x7C) | ((idx[6] >> 3) & 0x3))); put(decoded, state, static_cast(((idx[6] << 5) & 0xE0) | (idx[7] & 0x1F))); } template template inline void base32::decode_tail( Result& decoded, ResultState& state, const uint8_t* idx, size_t idx_len) { if (idx_len == 1) { throw invalid_input_length( "invalid number of symbols in last base32 block: found 1, expected 2, 4, 5 or 7"); } if (idx_len == 3) { throw invalid_input_length( "invalid number of symbols in last base32 block: found 3, expected 2, 4, 5 or 7"); } if (idx_len == 6) { throw invalid_input_length( "invalid number of symbols in last base32 block: found 6, expected 2, 4, 5 or 7"); } // idx_len == 2: decoded size 1 put(decoded, state, static_cast(((idx[0] << 3) & 0xF8) | ((idx[1] >> 2) & 0x7))); if (idx_len == 2) { return; } // idx_len == 4: decoded size 2 put(decoded, state, static_cast(((idx[1] << 6) & 0xC0) | ((idx[2] << 1) & 0x3E) | ((idx[3] >> 4) & 0x1))); if (idx_len == 4) { return; } // idx_len == 5: decoded size 3 put(decoded, state, static_cast(((idx[3] << 4) & 0xF0) | ((idx[4] >> 1) & 0xF))); if (idx_len == 5) { return; } // idx_len == 7: decoded size 4 put(decoded, state, static_cast(((idx[4] << 7) & 0x80) | ((idx[5] << 2) & 0x7C) | ((idx[6] >> 3) & 0x3))); } } // namespace detail } // namespace cppcodec #endif // CPPCODEC_DETAIL_BASE32 nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/detail/base64.hpp0000644000175000017500000001076513221173144023657 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * Copyright (C) 2013 Adam Rudd (bit calculations) * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Bit calculations adapted from https://github.com/adamvr/arduino-base64, * commit 999595783185a0afcba156d7276dfeaa9cb5382f. */ #ifndef CPPCODEC_DETAIL_BASE64 #define CPPCODEC_DETAIL_BASE64 #include #include #include "../data/access.hpp" #include "../parse_error.hpp" #include "config.hpp" #include "stream_codec.hpp" namespace cppcodec { namespace detail { template class base64 : public CodecVariant::template codec_impl> { public: static inline constexpr uint8_t binary_block_size() { return 3; } static inline constexpr uint8_t encoded_block_size() { return 4; } static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t num_bytes) { return (num_bytes == 1) ? 2 // 2 symbols, 2 padding characters : (num_bytes == 2) ? 3 // 3 symbols, 1 padding character : throw std::domain_error("invalid number of bytes in a tail block"); } template CPPCODEC_ALWAYS_INLINE static constexpr uint8_t index( const uint8_t* b /*binary block*/) { return (I == 0) ? (b[0] >> 2) // first 6 bits : (I == 1) ? (((b[0] & 0x3) << 4) | (b[1] >> 4)) : (I == 2) ? (((b[1] & 0xF) << 2) | (b[2] >> 6)) : (I == 3) ? (b[2] & 0x3F) // last 6 bits : throw std::domain_error("invalid encoding symbol index in a block"); } template CPPCODEC_ALWAYS_INLINE static constexpr uint8_t index_last( const uint8_t* b /*binary block*/) { return (I == 1) ? ((b[0] & 0x3) << 4) // abbreviated 2nd symbol : (I == 2) ? ((b[1] & 0xF) << 2) // abbreviated 3rd symbol : throw std::domain_error("invalid last encoding symbol index in a tail"); } template static void decode_block(Result& decoded, ResultState&, const uint8_t* idx); template static void decode_tail(Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len); }; template template inline void base64::decode_block( Result& decoded, ResultState& state, const uint8_t* idx) { data::put(decoded, state, static_cast((idx[0] << 2) + ((idx[1] & 0x30) >> 4))); data::put(decoded, state, static_cast(((idx[1] & 0xF) << 4) + ((idx[2] & 0x3C) >> 2))); data::put(decoded, state, static_cast(((idx[2] & 0x3) << 6) + idx[3])); } template template inline void base64::decode_tail( Result& decoded, ResultState& state, const uint8_t* idx, size_t idx_len) { if (idx_len == 1) { throw invalid_input_length( "invalid number of symbols in last base64 block: found 1, expected 2 or 3"); } // idx_len == 2: decoded size 1 data::put(decoded, state, static_cast((idx[0] << 2) + ((idx[1] & 0x30) >> 4))); if (idx_len == 2) { return; } // idx_len == 3: decoded size 2 data::put(decoded, state, static_cast(((idx[1] & 0xF) << 4) + ((idx[2] & 0x3C) >> 2))); } } // namespace detail } // namespace cppcodec #endif // CPPCODEC_DETAIL_BASE64 nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/detail/codec.hpp0000644000175000017500000002720113221173144023641 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_DETAIL_CODEC #define CPPCODEC_DETAIL_CODEC #include #include #include #include #include "../data/access.hpp" #include "../data/raw_result_buffer.hpp" namespace cppcodec { namespace detail { // SFINAE: Templates sometimes beat sensible overloads - make sure we don't call the wrong one. template struct non_numeric : std::enable_if::value> { }; /** * Public interface for all the codecs. For API documentation, see README.md. */ template class codec { public: // // Encoding // Convenient version, returns an std::string. static std::string encode(const uint8_t* binary, size_t binary_size); static std::string encode(const char* binary, size_t binary_size); // static std::string encode(const T& binary); -> provided by template below // Convenient version with templated result type. template static Result encode(const uint8_t* binary, size_t binary_size); template static Result encode(const char* binary, size_t binary_size); template > static Result encode(const T& binary); // Reused result container version. Resizes encoded_result before writing to it. template static void encode(Result& encoded_result, const uint8_t* binary, size_t binary_size); template static void encode(Result& encoded_result, const char* binary, size_t binary_size); template ::type* = nullptr> static void encode(Result& encoded_result, const T& binary); // Raw pointer output, assumes pre-allocated memory with size > encoded_size(binary_size). static size_t encode( char* encoded_result, size_t encoded_buffer_size, const uint8_t* binary, size_t binary_size) noexcept; static size_t encode( char* encoded_result, size_t encoded_buffer_size, const char* binary, size_t binary_size) noexcept; template static size_t encode( char* encoded_result, size_t encoded_buffer_size, const T& binary) noexcept; // Calculate the exact length of the encoded string based on binary size. static constexpr size_t encoded_size(size_t binary_size) noexcept; // // Decoding // Convenient version, returns an std::vector. static std::vector decode(const char* encoded, size_t encoded_size); // static std::vector decode(const T& encoded); -> provided by template below // Convenient version with templated result type. template static Result decode(const char* encoded, size_t encoded_size); template , typename T = std::string> static Result decode(const T& encoded); // Reused result container version. Resizes binary_result before writing to it. template static void decode(Result& binary_result, const char* encoded, size_t encoded_size); template ::type* = nullptr> static void decode(Result& binary_result, const T& encoded); // Raw pointer output, assumes pre-allocated memory with size > decoded_max_size(encoded_size). static size_t decode( uint8_t* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size); static size_t decode( char* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size); template static size_t decode( uint8_t* binary_result, size_t binary_buffer_size, const T& encoded); template static size_t decode( char* binary_result, size_t binary_buffer_size, const T& encoded); // Calculate the maximum size of the decoded binary buffer based on the encoded string length. static constexpr size_t decoded_max_size(size_t encoded_size) noexcept; }; // // Inline definitions of the above functions, using CRTP to call into CodecImpl // // // Encoding template inline std::string codec::encode(const uint8_t* binary, size_t binary_size) { return encode(binary, binary_size); } template inline std::string codec::encode(const char* binary, size_t binary_size) { return encode(reinterpret_cast(binary), binary_size); } template template inline Result codec::encode(const uint8_t* binary, size_t binary_size) { Result encoded_result; encode(encoded_result, binary, binary_size); return encoded_result; } template template inline Result codec::encode(const char* binary, size_t binary_size) { return encode(reinterpret_cast(binary), binary_size); } template template inline Result codec::encode(const T& binary) { return encode(data::uchar_data(binary), data::size(binary)); } template template inline void codec::encode( Result& encoded_result, const uint8_t* binary, size_t binary_size) { // This overload is where we reserve buffer capacity and call into CodecImpl. size_t encoded_buffer_size = encoded_size(binary_size); auto state = data::create_state(encoded_result, data::specific_t()); data::init(encoded_result, state, encoded_buffer_size); CodecImpl::encode(encoded_result, state, binary, binary_size); data::finish(encoded_result, state); assert(data::size(encoded_result) == encoded_buffer_size); } template template inline void codec::encode( Result& encoded_result, const char* binary, size_t binary_size) { encode(encoded_result, reinterpret_cast(binary), binary_size); } template template ::type*> inline void codec::encode(Result& encoded_result, const T& binary) { encode(encoded_result, data::uchar_data(binary), data::size(binary)); } template inline size_t codec::encode( char* encoded_result, size_t encoded_buffer_size, const uint8_t* binary, size_t binary_size) noexcept { // This overload is where we wrap the result pointer & size. data::raw_result_buffer encoded(encoded_result, encoded_buffer_size); encode(encoded, binary, binary_size); size_t encoded_size = data::size(encoded); if (encoded_size < encoded_buffer_size) { encoded_result[encoded_size] = '\0'; } return encoded_size; } template inline size_t codec::encode( char* encoded_result, size_t encoded_buffer_size, const char* binary, size_t binary_size) noexcept { // This overload is where we wrap the result pointer & size. return encode(encoded_result, encoded_buffer_size, reinterpret_cast(binary), binary_size); } template template inline size_t codec::encode( char* encoded_result, size_t encoded_buffer_size, const T& binary) noexcept { return encode(encoded_result, encoded_buffer_size, data::uchar_data(binary), data::size(binary)); } template inline constexpr size_t codec::encoded_size(size_t binary_size) noexcept { return CodecImpl::encoded_size(binary_size); } // // Decoding template inline std::vector codec::decode(const char* encoded, size_t encoded_size) { return decode>(encoded, encoded_size); } template template inline Result codec::decode(const char* encoded, size_t encoded_size) { Result result; decode(result, encoded, encoded_size); return result; } template template inline Result codec::decode(const T& encoded) { return decode(data::char_data(encoded), data::size(encoded)); } template template inline void codec::decode(Result& binary_result, const char* encoded, size_t encoded_size) { // This overload is where we reserve buffer capacity and call into CodecImpl. size_t binary_buffer_size = decoded_max_size(encoded_size); auto state = data::create_state(binary_result, data::specific_t()); data::init(binary_result, state, binary_buffer_size); CodecImpl::decode(binary_result, state, encoded, encoded_size); data::finish(binary_result, state); assert(data::size(binary_result) <= binary_buffer_size); } template template ::type*> inline void codec::decode(Result& binary_result, const T& encoded) { decode(binary_result, data::char_data(encoded), data::size(encoded)); } template inline size_t codec::decode( uint8_t* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size) { return decode(reinterpret_cast(binary_result), binary_buffer_size, encoded, encoded_size); } template inline size_t codec::decode( char* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size) { // This overload is where we wrap the result pointer & size. data::raw_result_buffer binary(binary_result, binary_buffer_size); decode(binary, encoded, encoded_size); return data::size(binary); } template template inline size_t codec::decode( uint8_t* binary_result, size_t binary_buffer_size, const T& encoded) { return decode(reinterpret_cast(binary_result), binary_buffer_size, encoded); } template template inline size_t codec::decode(char* binary_result, size_t binary_buffer_size, const T& encoded) { return decode(binary_result, binary_buffer_size, data::char_data(encoded), data::size(encoded)); } template inline constexpr size_t codec::decoded_max_size(size_t encoded_size) noexcept { return CodecImpl::decoded_max_size(encoded_size); } } // namespace detail } // namespace cppcodec #endif nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/detail/config.hpp0000644000175000017500000000273413221173144024035 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_DETAIL_CONFIG_HPP #define CPPCODEC_DETAIL_CONFIG_HPP #ifndef __has_attribute #define __has_attribute(x) 0 #endif #if __GNUC__ || __has_attribute(always_inline) #define CPPCODEC_ALWAYS_INLINE inline __attribute__((always_inline)) #else #define CPPCODEC_ALWAYS_INLINE inline #endif #endif // CPPCODEC_DETAIL_CONFIG_HPP nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/detail/hex.hpp0000644000175000017500000001103713221173144023350 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_DETAIL_HEX #define CPPCODEC_DETAIL_HEX #include #include // for abort() #include "../data/access.hpp" #include "../parse_error.hpp" #include "stream_codec.hpp" namespace cppcodec { namespace detail { class hex_base { public: static inline constexpr uint8_t index_of(char c) { // Hex decoding is always case-insensitive (even in RFC 4648), // it's only a question of what we want to encode ourselves. return (c >= '0' && c <= '9') ? (c - '0') : (c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c >= 'a' && c <= 'f') ? (c - 'a' + 10) : (c == '\0') ? 255 // stop at end of string : throw symbol_error(c); } // RFC4648 does not specify any whitespace being allowed in base64 encodings. static inline constexpr bool should_ignore(uint8_t /*index*/) { return false; } static inline constexpr bool is_special_character(uint8_t index) { return index > 64; } static inline constexpr bool is_eof(uint8_t index) { return index == 255; } static inline constexpr bool generates_padding() { return false; } // FIXME: doesn't require padding, but requires a multiple of the encoded block size (2) static inline constexpr bool requires_padding() { return false; } static inline constexpr bool is_padding_symbol(uint8_t /*index*/) { return false; } }; template class hex : public CodecVariant::template codec_impl> { public: static inline constexpr uint8_t binary_block_size() { return 1; } static inline constexpr uint8_t encoded_block_size() { return 2; } static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t /*num_bytes*/) noexcept { return true ? 0 : throw std::domain_error("no tails in hex encoding, should never be called"); } template CPPCODEC_ALWAYS_INLINE static constexpr uint8_t index( const uint8_t* b /*binary block*/) noexcept { return (I == 0) ? (b[0] >> 4) // first 4 bits : (I == 1) ? (b[0] & 0xF) // last 4 bits : throw std::domain_error("invalid encoding symbol index in a block"); } template CPPCODEC_ALWAYS_INLINE static constexpr uint8_t index_last( const uint8_t* b /*binary block*/) noexcept { return true ? 0 : throw std::domain_error("invalid last encoding symbol index in a tail"); } template static void decode_block(Result& decoded, ResultState&, const uint8_t* idx); template static void decode_tail(Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len); }; template template inline void hex::decode_block(Result& decoded, ResultState& state, const uint8_t* idx) { data::put(decoded, state, static_cast((idx[0] << 4) | idx[1])); } template template inline void hex::decode_tail(Result&, ResultState&, const uint8_t*, size_t) { throw invalid_input_length( "odd-length hex input is not supported by the streaming octet decoder, " "use a place-based number decoder instead"); } } // namespace detail } // namespace cppcodec #endif // CPPCODEC_DETAIL_HEX nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/detail/stream_codec.hpp0000644000175000017500000002430013221173144025211 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_DETAIL_STREAM_CODEC #define CPPCODEC_DETAIL_STREAM_CODEC #include // for abort() #include #include "../parse_error.hpp" #include "config.hpp" namespace cppcodec { namespace detail { template class stream_codec { public: template static void encode( Result& encoded_result, ResultState&, const uint8_t* binary, size_t binary_size); template static void decode( Result& binary_result, ResultState&, const char* encoded, size_t encoded_size); static constexpr size_t encoded_size(size_t binary_size) noexcept; static constexpr size_t decoded_max_size(size_t encoded_size) noexcept; }; template // default for CodecVariant::generates_padding() == false struct padder { template CPPCODEC_ALWAYS_INLINE void operator()(Result&, ResultState&, EncodedBlockSizeT) { } }; template<> // specialization for CodecVariant::generates_padding() == true struct padder { template CPPCODEC_ALWAYS_INLINE void operator()( Result& encoded, ResultState& state, EncodedBlockSizeT num_padding_characters) { for (EncodedBlockSizeT i = 0; i < num_padding_characters; ++i) { data::put(encoded, state, CodecVariant::padding_symbol()); } } }; template struct enc { // Block encoding: Go from 0 to (block size - 1), append a symbol for each iteration unconditionally. template static CPPCODEC_ALWAYS_INLINE void block(Result& encoded, ResultState& state, const uint8_t* src) { using EncodedBlockSizeT = decltype(Codec::encoded_block_size()); constexpr static const EncodedBlockSizeT SymbolIndex = static_cast(I - 1); enc().template block(encoded, state, src); data::put(encoded, state, CodecVariant::symbol(Codec::template index(src))); } // Tail encoding: Go from 0 until (runtime) num_symbols, append a symbol for each iteration. template static CPPCODEC_ALWAYS_INLINE void tail( Result& encoded, ResultState& state, const uint8_t* src, EncodedBlockSizeT num_symbols) { constexpr static const EncodedBlockSizeT SymbolIndex = Codec::encoded_block_size() - I; constexpr static const EncodedBlockSizeT NumSymbols = SymbolIndex + static_cast(1); if (num_symbols == NumSymbols) { data::put(encoded, state, CodecVariant::symbol(Codec::template index_last(src))); padder pad; #ifdef _MSC_VER pad.operator()(encoded, state, Codec::encoded_block_size() - NumSymbols); #else pad.template operator()(encoded, state, Codec::encoded_block_size() - NumSymbols); #endif return; } data::put(encoded, state, CodecVariant::symbol(Codec::template index(src))); enc().template tail(encoded, state, src, num_symbols); } }; template<> // terminating specialization struct enc<0> { template static CPPCODEC_ALWAYS_INLINE void block(Result&, ResultState&, const uint8_t*) { } template static CPPCODEC_ALWAYS_INLINE void tail(Result&, ResultState&, const uint8_t*, EncodedBlockSizeT) { abort(); // Not reached: block() should be called if num_symbols == block size, not tail(). } }; template template inline void stream_codec::encode( Result& encoded_result, ResultState& state, const uint8_t* src, size_t src_size) { using encoder = enc; const uint8_t* src_end = src + src_size; if (src_size >= Codec::binary_block_size()) { src_end -= Codec::binary_block_size(); for (; src <= src_end; src += Codec::binary_block_size()) { encoder::template block(encoded_result, state, src); } src_end += Codec::binary_block_size(); } if (src_end > src) { auto remaining_src_len = src_end - src; if (!remaining_src_len || remaining_src_len >= Codec::binary_block_size()) { abort(); return; } auto num_symbols = Codec::num_encoded_tail_symbols(remaining_src_len); encoder::template tail(encoded_result, state, src, num_symbols); } } template template inline void stream_codec::decode( Result& binary_result, ResultState& state, const char* src_encoded, size_t src_size) { const char* src = src_encoded; const char* src_end = src + src_size; uint8_t idx[Codec::encoded_block_size()] = {}; uint8_t last_value_idx = 0; while (src < src_end) { if (CodecVariant::should_ignore(idx[last_value_idx] = CodecVariant::index_of(*(src++)))) { continue; } if (CodecVariant::is_special_character(idx[last_value_idx])) { break; } ++last_value_idx; if (last_value_idx == Codec::encoded_block_size()) { Codec::decode_block(binary_result, state, idx); last_value_idx = 0; } } uint8_t last_idx = last_value_idx; if (CodecVariant::is_padding_symbol(idx[last_value_idx])) { if (!last_value_idx) { // Don't accept padding at the start of a block. // The encoder should have omitted that padding altogether. throw padding_error(); } // We're in here because we just read a (first) padding character. Try to read more. ++last_idx; while (src < src_end) { // Use idx[last_value_idx] to avoid declaring another uint8_t. It's unused now so that's okay. if (CodecVariant::is_eof(idx[last_value_idx] = CodecVariant::index_of(*(src++)))) { break; } if (!CodecVariant::is_padding_symbol(idx[last_value_idx])) { throw padding_error(); } ++last_idx; if (last_idx > Codec::encoded_block_size()) { throw padding_error(); } } } if (last_idx) { if (CodecVariant::requires_padding() && last_idx != Codec::encoded_block_size()) { // If the input is not a multiple of the block size then the input is incorrect. throw padding_error(); } if (last_value_idx >= Codec::encoded_block_size()) { abort(); return; } Codec::decode_tail(binary_result, state, idx, last_value_idx); } } template inline constexpr size_t stream_codec::encoded_size(size_t binary_size) noexcept { using C = Codec; // constexpr rules make this a lot harder to read than it actually is. return CodecVariant::generates_padding() // With padding, the encoded size is a multiple of the encoded block size. // To calculate that, round the binary size up to multiple of the binary block size, // then convert to encoded by multiplying with { base32: 8/5, base64: 4/3 }. ? (binary_size + (C::binary_block_size() - 1) - ((binary_size + (C::binary_block_size() - 1)) % C::binary_block_size())) * C::encoded_block_size() / C::binary_block_size() // No padding: only pad to the next multiple of 5 bits, i.e. at most a single extra byte. : (binary_size * C::encoded_block_size() / C::binary_block_size()) + (((binary_size * C::encoded_block_size()) % C::binary_block_size()) ? 1 : 0); } template inline constexpr size_t stream_codec::decoded_max_size(size_t encoded_size) noexcept { using C = Codec; return CodecVariant::requires_padding() ? (encoded_size / C::encoded_block_size() * C::binary_block_size()) : (encoded_size / C::encoded_block_size() * C::binary_block_size()) + ((encoded_size % C::encoded_block_size()) * C::binary_block_size() / C::encoded_block_size()); } } // namespace detail } // namespace cppcodec #endif // CPPCODEC_DETAIL_STREAM_CODEC nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/hex_default_lower.hpp0000644000175000017500000000246013221173144025022 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_HEX_DEFAULT_LOWER #define CPPCODEC_HEX_DEFAULT_LOWER #include "hex_lower.hpp" using hex = cppcodec::hex_lower; #endif // CPPCODEC_HEX_DEFAULT_LOWER nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/hex_default_upper.hpp0000644000175000017500000000246013221173144025025 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_HEX_DEFAULT_UPPER #define CPPCODEC_HEX_DEFAULT_UPPER #include "hex_upper.hpp" using hex = cppcodec::hex_upper; #endif // CPPCODEC_HEX_DEFAULT_UPPER nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/hex_lower.hpp0000644000175000017500000000363213221173144023320 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_HEX_LOWER #define CPPCODEC_HEX_LOWER #include "detail/codec.hpp" #include "detail/hex.hpp" namespace cppcodec { namespace detail { static constexpr const char hex_lower_alphabet[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // at index 10 'a', 'b', 'c', 'd', 'e', 'f' }; static_assert(sizeof(hex_lower_alphabet) == 16, "hex alphabet must have 16 values"); class hex_lower : public hex_base { public: template using codec_impl = stream_codec; static inline constexpr char symbol(uint8_t index) { return hex_lower_alphabet[index]; } }; } // namespace detail using hex_lower = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_HEX_LOWER nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/hex_upper.hpp0000644000175000017500000000361313221173144023322 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_HEX_UPPER #define CPPCODEC_HEX_UPPER #include "detail/codec.hpp" #include "detail/hex.hpp" namespace cppcodec { namespace detail { static constexpr const char hex_upper_alphabet[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static_assert(sizeof(hex_upper_alphabet) == 16, "hex alphabet must have 16 values"); class hex_upper : public hex_base { public: template using codec_impl = stream_codec; static inline constexpr char symbol(uint8_t index) { return hex_upper_alphabet[index]; } }; } // namespace detail using hex_upper = detail::codec>; } // namespace cppcodec #endif // CPPCODEC_HEX_UPPER nitrokey-app-1.3.2/3rdparty/cppcodec/cppcodec/parse_error.hpp0000644000175000017500000000632313221173144023647 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef CPPCODEC_PARSE_ERROR #define CPPCODEC_PARSE_ERROR #include #include namespace cppcodec { namespace detail { // <*stream> headers include a lot of code and noticeably increase compile times. // The only thing we want from them really is a char-to-string conversion. // That's easy to implement with many less lines of code, so let's do it ourselves. template static void uctoa(unsigned char n, char (&s)[N]) { static_assert(N >= 4, "need at least 4 bytes to convert an unsigned char to string safely"); int i = sizeof(s) - 1; int num_chars = 1; s[i--] = '\0'; do { // generate digits in reverse order s[i--] = n % 10 + '0'; // get next digit ++num_chars; } while ((n /= 10) > 0); // delete it if (num_chars == sizeof(s)) { return; } for (i = 0; i < num_chars; ++i) { // move chars to front of string s[i] = s[i + (sizeof(s) - num_chars)]; } } } // end namespace detail class parse_error : public std::domain_error { public: using std::domain_error::domain_error; }; // Avoids memory allocation, so it can be used in constexpr functions. class symbol_error : public parse_error { public: symbol_error(char c) : parse_error(symbol_error::make_error_message(c)) , m_symbol(c) { } symbol_error(const symbol_error&) = default; char symbol() const noexcept { return m_symbol; } private: static std::string make_error_message(char c) { char s[4]; detail::uctoa(*reinterpret_cast(&c), s); return std::string("parse error: character [") + &(s[0]) + " '" + c + "'] out of bounds"; } private: char m_symbol; }; class invalid_input_length : public parse_error { public: using parse_error::parse_error; }; class padding_error : public invalid_input_length { public: padding_error() : invalid_input_length("parse error: codec expects padded input string but padding was invalid") { } padding_error(const padding_error&) = default; }; } // namespace cppcodec #endif // CPPCODEC_PARSE_ERROR nitrokey-app-1.3.2/3rdparty/cppcodec/test/CMakeLists.txt0000644000175000017500000000031613221173144022546 0ustar janjan00000000000000# For cppcodec itself, don't prefer system headers over development ones. include_directories(BEFORE ${PROJECT_SOURCE_DIR}) add_executable(test_cppcodec test_cppcodec.cpp) add_test(cppcodec test_cppcodec) nitrokey-app-1.3.2/3rdparty/cppcodec/test/test_cppcodec.cpp0000644000175000017500000014762613221173144023351 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #define CATCH_CONFIG_MAIN #include "catch/single_include/catch.hpp" #include #include #include #include #include #include #include #include #include #include // for memcmp() #include TEST_CASE("Douglas Crockford's base32", "[base32][crockford]") { using base32 = cppcodec::base32_crockford; SECTION("encoded size calculation") { REQUIRE(base32::encoded_size(0) == 0); REQUIRE(base32::encoded_size(1) == 2); REQUIRE(base32::encoded_size(2) == 4); REQUIRE(base32::encoded_size(3) == 5); REQUIRE(base32::encoded_size(4) == 7); REQUIRE(base32::encoded_size(5) == 8); REQUIRE(base32::encoded_size(6) == 10); REQUIRE(base32::encoded_size(10) == 16); } SECTION("maximum decoded size calculation") { REQUIRE(base32::decoded_max_size(0) == 0); REQUIRE(base32::decoded_max_size(1) == 0); REQUIRE(base32::decoded_max_size(2) == 1); REQUIRE(base32::decoded_max_size(3) == 1); REQUIRE(base32::decoded_max_size(4) == 2); REQUIRE(base32::decoded_max_size(5) == 3); REQUIRE(base32::decoded_max_size(6) == 3); REQUIRE(base32::decoded_max_size(7) == 4); REQUIRE(base32::decoded_max_size(8) == 5); REQUIRE(base32::decoded_max_size(9) == 5); REQUIRE(base32::decoded_max_size(10) == 6); REQUIRE(base32::decoded_max_size(16) == 10); } std::string hello = "Hello World"; std::string hello_encoded = "91JPRV3F41BPYWKCCG"; std::string hello_encoded_null = "91JPRV3F41BPYWKCCG00"; const uint8_t* hello_uint_ptr = reinterpret_cast(hello.data()); const uint8_t* hello_uint_ptr_encoded = reinterpret_cast(hello_encoded.data()); std::vector hello_uint_vector(hello_uint_ptr, hello_uint_ptr + hello.size()); std::vector hello_char_vector_encoded( hello_encoded.data(), hello_encoded.data() + hello_encoded.size()); std::vector hello_uint_vector_encoded( hello_uint_ptr_encoded, hello_uint_ptr_encoded + hello_encoded.size()); SECTION("encoding data") { REQUIRE(base32::encode(std::vector()) == ""); REQUIRE(base32::encode(std::vector({0})) == "00"); REQUIRE(base32::encode(std::vector({0, 0})) == "0000"); REQUIRE(base32::encode(std::vector({0, 0, 0})) == "00000"); REQUIRE(base32::encode(std::vector({0, 0, 0, 0})) == "0000000"); REQUIRE(base32::encode(std::vector({0, 0, 0, 0, 0})) == "00000000"); REQUIRE(base32::encode(std::vector({0, 0, 0, 0, 0, 0})) == "0000000000"); // Constructing an std::string reduces the size of the char array by one (null terminator). // Therefore, the result for passing the string literal directly ends up encoding // one more character, which produces two more symbols in this particular case. REQUIRE(base32::encode(std::string("Hello World")) == hello_encoded); REQUIRE(base32::encode("Hello World") == hello_encoded_null); REQUIRE(base32::encode(std::string("foo")) == "CSQPY"); REQUIRE(base32::encode(std::string("lowercase UPPERCASE 1434567 !@#$%^&*")) == "DHQQESBJCDGQ6S90AN850HAJ8D0N6H9064T36D1N6RVJ08A04CJ2AQH658"); REQUIRE(base32::encode(std::string("Wow, it really works!")) == "AXQQEB10D5T20WK5C5P6RY90EXQQ4TVK44"); } SECTION("decoding data") { REQUIRE(base32::decode("") == std::vector()); REQUIRE(base32::decode("00") == std::vector({0})); REQUIRE(base32::decode("0000") == std::vector({0, 0})); REQUIRE(base32::decode("00000") == std::vector({0, 0, 0})); REQUIRE(base32::decode("0000000") == std::vector({0, 0, 0, 0})); REQUIRE(base32::decode("00000000") == std::vector({0, 0, 0, 0, 0})); REQUIRE(base32::decode("0000000000") == std::vector({0, 0, 0, 0, 0, 0})); // For decoding data, the result should be the same whether or not there is // a null terminator at the end, because the input is a string (not binary array). REQUIRE(base32::decode(std::string("91JPRV3F41BPYWKCCG")) == hello_uint_vector); REQUIRE(base32::decode("91JPRV3F41BPYWKCCG") == hello_uint_vector); REQUIRE(base32::decode("CSQPY") == "foo"); REQUIRE(base32::decode("DHQQESBJCDGQ6S90AN850HAJ8D0N6H9064T36D1N6RVJ08A04CJ2AQH658") == "lowercase UPPERCASE 1434567 !@#$%^&*"); // Lowercase should decode just as well as uppercase. REQUIRE(base32::decode("AXQQEB10D5T20WK5C5P6RY90EXQQ4TVK44") == "Wow, it really works!"); REQUIRE(base32::decode("axqqeb10d5t20wk5c5p6ry90exqq4tvk44") == "Wow, it really works!"); // Dashes are allowed for visual separation and ignored when decoding. REQUIRE(base32::decode("-C-SQ--PY-") == "foo"); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(base32::decode("0"), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("000"), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("000000"), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("000000000"), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(base32::decode("00======"), cppcodec::symbol_error&); // no padding for Crockford REQUIRE_THROWS_AS(base32::decode("Uu"), cppcodec::symbol_error&); // only a checksum symbol here REQUIRE_THROWS_AS(base32::decode("++"), cppcodec::symbol_error&); // make sure it's not base64 REQUIRE_THROWS_AS(base32::decode("//"), cppcodec::symbol_error&); // ...ditto } // Only test overloads once (for base32_crockford, since it happens to be the first one). // Since it's all templated, we assume that overloads work/behave similarly for other codecs. SECTION("encode() overloads") { // Other convenient overloads for taking raw pointer input. REQUIRE(base32::encode(hello.data(), hello.size()) == hello_encoded); REQUIRE(base32::encode(hello_uint_ptr, hello.size()) == hello_encoded); // Reused result pointer. Put the extra null terminator version in the middle to test resizing. std::string result; REQUIRE((base32::encode(result, hello_uint_ptr, hello.size()), result) == hello_encoded); REQUIRE((base32::encode(result, "Hello World"), result) == hello_encoded_null); REQUIRE((base32::encode(result, hello.data(), hello.size()), result) == hello_encoded); // Templated result. Use std::vector to exercise non-char array types. REQUIRE(base32::encode>(hello) == hello_uint_vector_encoded); REQUIRE(base32::encode>(hello.data(), hello.size()) == hello_uint_vector_encoded); REQUIRE(base32::encode>(hello_uint_ptr, hello.size()) == hello_uint_vector_encoded); // Raw pointer output. std::vector hello_char_result; hello_char_result.resize(base32::encoded_size(hello.size())); REQUIRE(hello_char_result.size() == hello_char_vector_encoded.size()); size_t result_size; result_size = base32::encode(hello_char_result.data(), hello_char_result.size(), hello); REQUIRE(result_size == hello_char_vector_encoded.size()); REQUIRE(hello_char_result == hello_char_vector_encoded); result_size = base32::encode( hello_char_result.data(), hello_char_result.size(), hello.data(), hello.size()); REQUIRE(result_size == hello_char_vector_encoded.size()); REQUIRE(hello_char_result == hello_char_vector_encoded); // Test that when passed a larger buffer, the null termination character will be written // after the last proper symbol. (Also test uint8_t* overload.) hello_char_result.resize(hello_char_result.size() + 1); hello_char_result[hello_char_result.size() - 1] = 'x'; result_size = base32::encode( hello_char_result.data(), hello_char_result.size(), hello_uint_ptr, hello.size()); REQUIRE(result_size == hello_char_vector_encoded.size()); REQUIRE(hello_char_result[hello_char_result.size() - 1] == '\0'); hello_char_result.resize(hello_char_result.size() - 1); REQUIRE(hello_char_result == hello_char_vector_encoded); } // Only test overloads once (for base32_crockford, since it happens to be the first one). // Since it's all templated, we assume that overloads work/behave similarly for other codecs. SECTION("decode() overloads") { // Other convenient overloads for taking raw pointer input. REQUIRE(base32::decode(hello_encoded.data(), hello_encoded.size()) == hello_uint_vector); // Reused result pointer. Put a different string in the middle to test resizing. std::vector result; REQUIRE((base32::decode(result, hello_encoded.data(), hello_encoded.size()), result) == hello_uint_vector); REQUIRE((base32::decode(result, "00"), result) == std::vector({0})); REQUIRE((base32::decode(result, hello_encoded), result) == hello_uint_vector); // Templated result. Use std::string to exercise non-uint8_t array types. REQUIRE(base32::decode(hello_encoded) == hello); REQUIRE(base32::decode(hello_uint_vector_encoded) == hello); REQUIRE(base32::decode(hello_encoded.data(), hello_encoded.size()) == hello); // Raw pointer output. std::vector hello_uint_result; std::vector hello_char_result; size_t hello_decoded_max_size = base32::decoded_max_size(hello_encoded.size()); REQUIRE(hello.size() <= hello_decoded_max_size); hello_char_result.resize(hello_decoded_max_size); size_t result_size = base32::decode( hello_char_result.data(), hello_char_result.size(), hello_encoded); REQUIRE(result_size == hello.size()); REQUIRE(std::string(hello_char_result.data(), hello_char_result.data() + result_size) == hello); hello_char_result.resize(hello_decoded_max_size); result_size = base32::decode( hello_char_result.data(), hello_char_result.size(), hello_encoded.data(), hello_encoded.size()); REQUIRE(result_size == hello.size()); REQUIRE(std::string(hello_char_result.data(), hello_char_result.data() + result_size) == hello); hello_uint_result.resize(hello_decoded_max_size); result_size = base32::decode( hello_uint_result.data(), hello_uint_result.size(), hello_encoded); REQUIRE(result_size == hello.size()); hello_uint_result.resize(result_size); REQUIRE(hello_uint_result == hello_uint_vector); hello_uint_result.resize(hello_decoded_max_size); result_size = base32::decode( hello_uint_result.data(), hello_uint_result.size(), hello_encoded.data(), hello_encoded.size()); REQUIRE(result_size == hello.size()); hello_uint_result.resize(result_size); REQUIRE(hello_uint_result == hello_uint_vector); } } TEST_CASE("base32hex", "[base32][hex]") { using base32 = cppcodec::base32_hex; SECTION("encoded size calculation") { REQUIRE(base32::encoded_size(0) == 0); REQUIRE(base32::encoded_size(1) == 8); REQUIRE(base32::encoded_size(2) == 8); REQUIRE(base32::encoded_size(3) == 8); REQUIRE(base32::encoded_size(4) == 8); REQUIRE(base32::encoded_size(5) == 8); REQUIRE(base32::encoded_size(6) == 16); REQUIRE(base32::encoded_size(10) == 16); } SECTION("maximum decoded size calculation") { REQUIRE(base32::decoded_max_size(0) == 0); REQUIRE(base32::decoded_max_size(1) == 0); REQUIRE(base32::decoded_max_size(2) == 0); REQUIRE(base32::decoded_max_size(3) == 0); REQUIRE(base32::decoded_max_size(4) == 0); REQUIRE(base32::decoded_max_size(5) == 0); REQUIRE(base32::decoded_max_size(6) == 0); REQUIRE(base32::decoded_max_size(7) == 0); REQUIRE(base32::decoded_max_size(8) == 5); REQUIRE(base32::decoded_max_size(9) == 5); REQUIRE(base32::decoded_max_size(10) == 5); REQUIRE(base32::decoded_max_size(16) == 10); } SECTION("encoding data") { REQUIRE(base32::encode(std::vector()) == ""); REQUIRE(base32::encode(std::vector({0})) == "00======"); REQUIRE(base32::encode(std::vector({0, 0})) == "0000===="); REQUIRE(base32::encode(std::vector({0, 0, 0})) == "00000==="); REQUIRE(base32::encode(std::vector({0, 0, 0, 0})) == "0000000="); REQUIRE(base32::encode(std::vector({0, 0, 0, 0, 0})) == "00000000"); REQUIRE(base32::encode(std::vector({0, 0, 0, 0, 0, 0})) == "0000000000======"); // Constructing an std::string reduces the size of the char array by one (null terminator). // Therefore, the result for passing the string literal directly ends up encoding // one more character, which produces two more symbols in this particular case. REQUIRE(base32::encode(std::string("Hello")) == "91IMOR3F"); REQUIRE(base32::encode("Hello") == "91IMOR3F00======"); // RFC 4648: 10. Test Vectors REQUIRE(base32::encode(std::string("")) == ""); REQUIRE(base32::encode(std::string("f")) == "CO======"); REQUIRE(base32::encode(std::string("fo")) == "CPNG===="); REQUIRE(base32::encode(std::string("foo")) == "CPNMU==="); REQUIRE(base32::encode(std::string("foob")) == "CPNMUOG="); REQUIRE(base32::encode(std::string("fooba")) == "CPNMUOJ1"); REQUIRE(base32::encode(std::string("foobar")) == "CPNMUOJ1E8======"); // Other test strings. REQUIRE(base32::encode(std::vector({255, 255, 255, 255, 255})) == "VVVVVVVV"); } SECTION("decoding data") { REQUIRE(base32::decode("") == std::vector()); REQUIRE(base32::decode("00======") == std::vector({0})); REQUIRE(base32::decode("0000====") == std::vector({0, 0})); REQUIRE(base32::decode("00000===") == std::vector({0, 0, 0})); REQUIRE(base32::decode("0000000=") == std::vector({0, 0, 0, 0})); REQUIRE(base32::decode("00000000") == std::vector({0, 0, 0, 0, 0})); REQUIRE(base32::decode("0000000000======") == std::vector({0, 0, 0, 0, 0, 0})); // For decoding data, the result should be the same whether or not there is // a null terminator at the end, because the input is a string (not binary array). REQUIRE(base32::decode(std::string("91IMOR3F")) == "Hello"); REQUIRE(base32::decode("91IMOR3F") == "Hello"); // RFC 4648: 10. Test Vectors REQUIRE(base32::decode("") == ""); REQUIRE(base32::decode("CO======") == "f"); REQUIRE(base32::decode("CPNG====") == "fo"); REQUIRE(base32::decode("CPNMU===") == "foo"); REQUIRE(base32::decode("CPNMUOG=") == "foob"); REQUIRE(base32::decode("CPNMUOJ1") == "fooba"); REQUIRE(base32::decode("CPNMUOJ1E8======") == "foobar"); // Other test strings. REQUIRE(base32::decode("VVVVVVVV") == std::vector({255, 255, 255, 255, 255})); // Lowercase should decode just as well as uppercase. REQUIRE(base32::decode("cpnmuoj1") == "fooba"); REQUIRE(base32::decode("cPnMuOj1") == "fooba"); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(base32::decode("0"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base32::decode("00"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base32::decode("00==="), cppcodec::padding_error&); REQUIRE_THROWS_AS(base32::decode("0======="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("000====="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("000000=="), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(base32::decode("W0======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("X0======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("Y0======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("Z0======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("CPNM UOJ1"), cppcodec::symbol_error&); // no spaces REQUIRE_THROWS_AS(base32::decode("CPNM-UOJ1"), cppcodec::symbol_error&); // no dashes } } TEST_CASE("base32 (RFC 4648)", "[base32][rfc4648]") { using base32 = cppcodec::base32_rfc4648; SECTION("encoded size calculation") { REQUIRE(base32::encoded_size(0) == 0); REQUIRE(base32::encoded_size(1) == 8); REQUIRE(base32::encoded_size(2) == 8); REQUIRE(base32::encoded_size(3) == 8); REQUIRE(base32::encoded_size(4) == 8); REQUIRE(base32::encoded_size(5) == 8); REQUIRE(base32::encoded_size(6) == 16); REQUIRE(base32::encoded_size(10) == 16); } SECTION("maximum decoded size calculation") { REQUIRE(base32::decoded_max_size(0) == 0); REQUIRE(base32::decoded_max_size(1) == 0); REQUIRE(base32::decoded_max_size(2) == 0); REQUIRE(base32::decoded_max_size(3) == 0); REQUIRE(base32::decoded_max_size(4) == 0); REQUIRE(base32::decoded_max_size(5) == 0); REQUIRE(base32::decoded_max_size(6) == 0); REQUIRE(base32::decoded_max_size(7) == 0); REQUIRE(base32::decoded_max_size(8) == 5); REQUIRE(base32::decoded_max_size(9) == 5); REQUIRE(base32::decoded_max_size(10) == 5); REQUIRE(base32::decoded_max_size(16) == 10); } SECTION("encoding data") { REQUIRE(base32::encode(std::vector()) == ""); REQUIRE(base32::encode(std::vector({0})) == "AA======"); REQUIRE(base32::encode(std::vector({0, 0})) == "AAAA===="); REQUIRE(base32::encode(std::vector({0, 0, 0})) == "AAAAA==="); REQUIRE(base32::encode(std::vector({0, 0, 0, 0})) == "AAAAAAA="); REQUIRE(base32::encode(std::vector({0, 0, 0, 0, 0})) == "AAAAAAAA"); REQUIRE(base32::encode(std::vector({0, 0, 0, 0, 0, 0})) == "AAAAAAAAAA======"); // Constructing an std::string reduces the size of the char array by one (null terminator). // Therefore, the result for passing the string literal directly ends up encoding // one more character, which produces two more symbols in this particular case. REQUIRE(base32::encode(std::string("12345")) == "GEZDGNBV"); REQUIRE(base32::encode("12345") == "GEZDGNBVAA======"); // RFC 4648: 10. Test Vectors REQUIRE(base32::encode(std::string("")) == ""); REQUIRE(base32::encode(std::string("f")) == "MY======"); REQUIRE(base32::encode(std::string("fo")) == "MZXQ===="); REQUIRE(base32::encode(std::string("foo")) == "MZXW6==="); REQUIRE(base32::encode(std::string("foob")) == "MZXW6YQ="); REQUIRE(base32::encode(std::string("fooba")) == "MZXW6YTB"); REQUIRE(base32::encode(std::string("foobar")) == "MZXW6YTBOI======"); // Other test strings. REQUIRE(base32::encode(std::string("ABCDE")) == "IFBEGRCF"); REQUIRE(base32::encode(std::vector({255, 255, 255, 255, 255})) == "77777777"); } SECTION("decoding data") { REQUIRE(base32::decode("") == std::vector()); REQUIRE(base32::decode("AA======") == std::vector({0})); REQUIRE(base32::decode("AAAA====") == std::vector({0, 0})); REQUIRE(base32::decode("AAAAA===") == std::vector({0, 0, 0})); REQUIRE(base32::decode("AAAAAAA=") == std::vector({0, 0, 0, 0})); REQUIRE(base32::decode("AAAAAAAA") == std::vector({0, 0, 0, 0, 0})); REQUIRE(base32::decode("AAAAAAAAAA======") == std::vector({0, 0, 0, 0, 0, 0})); // For decoding data, the result should be the same whether or not there is // a null terminator at the end, because the input is a string (not binary array). REQUIRE(base32::decode(std::string("GEZDGNBV")) == "12345"); REQUIRE(base32::decode("GEZDGNBV") == "12345"); // RFC 4648: 10. Test Vectors REQUIRE(base32::decode("") == ""); REQUIRE(base32::decode("MY======") == "f"); REQUIRE(base32::decode("MZXQ====") == "fo"); REQUIRE(base32::decode("MZXW6===") == "foo"); REQUIRE(base32::decode("MZXW6YQ=") == "foob"); REQUIRE(base32::decode("MZXW6YTB") == "fooba"); REQUIRE(base32::decode("MZXW6YTBOI======") == "foobar"); // Other test strings. REQUIRE(base32::decode("IFBEGRCF") == "ABCDE"); REQUIRE(base32::decode("77777777") == std::vector({255, 255, 255, 255, 255})); // Lowercase should decode just as well as uppercase. REQUIRE(base32::decode("mzxw6ytb") == "fooba"); REQUIRE(base32::decode("mZxW6yTb") == "fooba"); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(base32::decode("A"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base32::decode("AA"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base32::decode("AA==="), cppcodec::padding_error&); REQUIRE_THROWS_AS(base32::decode("A======="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("AAA====="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base32::decode("AAAAAA=="), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(base32::decode("0A======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("1A======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("8A======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("9A======"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base32::decode("GEZD GNBV"), cppcodec::symbol_error&); // no spaces REQUIRE_THROWS_AS(base32::decode("GEZD-GNBV"), cppcodec::symbol_error&); // no dashes } } TEST_CASE("base64 (RFC 4648)", "[base64][rfc4648]") { using base64 = cppcodec::base64_rfc4648; SECTION("encoded size calculation") { REQUIRE(base64::encoded_size(0) == 0); REQUIRE(base64::encoded_size(1) == 4); REQUIRE(base64::encoded_size(2) == 4); REQUIRE(base64::encoded_size(3) == 4); REQUIRE(base64::encoded_size(4) == 8); REQUIRE(base64::encoded_size(5) == 8); REQUIRE(base64::encoded_size(6) == 8); REQUIRE(base64::encoded_size(7) == 12); REQUIRE(base64::encoded_size(12) == 16); } SECTION("maximum decoded size calculation") { REQUIRE(base64::decoded_max_size(0) == 0); REQUIRE(base64::decoded_max_size(1) == 0); REQUIRE(base64::decoded_max_size(2) == 0); REQUIRE(base64::decoded_max_size(3) == 0); REQUIRE(base64::decoded_max_size(4) == 3); REQUIRE(base64::decoded_max_size(5) == 3); REQUIRE(base64::decoded_max_size(6) == 3); REQUIRE(base64::decoded_max_size(7) == 3); REQUIRE(base64::decoded_max_size(8) == 6); REQUIRE(base64::decoded_max_size(9) == 6); REQUIRE(base64::decoded_max_size(10) == 6); REQUIRE(base64::decoded_max_size(11) == 6); REQUIRE(base64::decoded_max_size(12) == 9); REQUIRE(base64::decoded_max_size(16) == 12); } SECTION("encoding data") { REQUIRE(base64::encode(std::vector()) == ""); REQUIRE(base64::encode(std::vector({0})) == "AA=="); REQUIRE(base64::encode(std::vector({0, 0})) == "AAA="); REQUIRE(base64::encode(std::vector({0, 0, 0})) == "AAAA"); REQUIRE(base64::encode(std::vector({0, 0, 0, 0})) == "AAAAAA=="); REQUIRE(base64::encode(std::vector({0, 0, 0, 0, 0})) == "AAAAAAA="); REQUIRE(base64::encode(std::vector({0, 0, 0, 0, 0, 0})) == "AAAAAAAA"); // Constructing an std::string reduces the size of the char array by one (null terminator). // Therefore, the result for passing the string literal directly ends up encoding // one more character, which produces two more symbols in this particular case. REQUIRE(base64::encode(std::string("Man")) == "TWFu"); REQUIRE(base64::encode("Man") == "TWFuAA=="); // Wikipedia REQUIRE(base64::encode(std::string("pleasure.")) == "cGxlYXN1cmUu"); REQUIRE(base64::encode(std::string("leasure.")) == "bGVhc3VyZS4="); REQUIRE(base64::encode(std::string("easure.")) == "ZWFzdXJlLg=="); REQUIRE(base64::encode(std::string("asure.")) == "YXN1cmUu"); REQUIRE(base64::encode(std::string("sure.")) == "c3VyZS4="); REQUIRE(base64::encode(std::string("any carnal pleas")) == "YW55IGNhcm5hbCBwbGVhcw=="); REQUIRE(base64::encode(std::string("any carnal pleasu")) == "YW55IGNhcm5hbCBwbGVhc3U="); REQUIRE(base64::encode(std::string("any carnal pleasur")) == "YW55IGNhcm5hbCBwbGVhc3Vy"); // RFC 4648: 9. Illustrations and Examples, adapted for more special characters REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})) == "FPu/A9l+"); REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9})) == "FPu/A9k="); REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03})) == "FPu/Aw=="); // RFC 4648: 10. Test Vectors REQUIRE(base64::encode(std::string("")) == ""); REQUIRE(base64::encode(std::string("f")) == "Zg=="); REQUIRE(base64::encode(std::string("fo")) == "Zm8="); REQUIRE(base64::encode(std::string("foo")) == "Zm9v"); REQUIRE(base64::encode(std::string("foob")) == "Zm9vYg=="); REQUIRE(base64::encode(std::string("fooba")) == "Zm9vYmE="); REQUIRE(base64::encode(std::string("foobar")) == "Zm9vYmFy"); // Other test strings. REQUIRE(base64::encode(std::string("123")) == "MTIz"); REQUIRE(base64::encode(std::string("ABC")) == "QUJD"); REQUIRE(base64::encode(std::string("\xFF\xFF\xFF")) == "////"); } SECTION("decoding data") { REQUIRE(base64::decode("") == std::vector()); REQUIRE(base64::decode("AA==") == std::vector({0})); REQUIRE(base64::decode("AAA=") == std::vector({0, 0})); REQUIRE(base64::decode("AAAA") == std::vector({0, 0, 0})); REQUIRE(base64::decode("AAAAAA==") == std::vector({0, 0, 0, 0})); REQUIRE(base64::decode("AAAAAAA=") == std::vector({0, 0, 0, 0, 0})); REQUIRE(base64::decode("AAAAAAAA") == std::vector({0, 0, 0, 0, 0, 0})); // For decoding data, the result should be the same whether or not there is // a null terminator at the end, because the input is a string (not binary array). REQUIRE(base64::decode(std::string("TWFu")) == "Man"); REQUIRE(base64::decode("TWFu") == "Man"); // Wikipedia REQUIRE(base64::decode("cGxlYXN1cmUu") == "pleasure."); REQUIRE(base64::decode("bGVhc3VyZS4=") == "leasure."); REQUIRE(base64::decode("ZWFzdXJlLg==") == "easure."); REQUIRE(base64::decode("YXN1cmUu") == "asure."); REQUIRE(base64::decode("c3VyZS4=") == "sure."); REQUIRE(base64::decode("YW55IGNhcm5hbCBwbGVhcw==") == "any carnal pleas"); REQUIRE(base64::decode("YW55IGNhcm5hbCBwbGVhc3U=") == "any carnal pleasu"); REQUIRE(base64::decode("YW55IGNhcm5hbCBwbGVhc3Vy") == "any carnal pleasur"); // RFC 4648: 9. Illustrations and Examples, adapted for more special characters REQUIRE(base64::decode("FPu/A9l+") == std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})); REQUIRE(base64::decode("FPu/A9k=") == std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9})); REQUIRE(base64::decode("FPu/Aw==") == std::vector({0x14, 0xFB, 0xBF, 0x03})); // RFC 4648: 10. Test Vectors REQUIRE(base64::decode("") == ""); REQUIRE(base64::decode("Zg==") == "f"); REQUIRE(base64::decode("Zm8=") == "fo"); REQUIRE(base64::decode("Zm9v") == "foo"); REQUIRE(base64::decode("Zm9vYg==") == "foob"); REQUIRE(base64::decode("Zm9vYmE=") == "fooba"); REQUIRE(base64::decode("Zm9vYmFy") == "foobar"); // Other test strings. REQUIRE(base64::decode("MTIz") == "123"); REQUIRE(base64::decode("QUJD") == "ABC"); REQUIRE(base64::decode("////") == std::vector({255, 255, 255})); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(base64::decode("A"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base64::decode("AA"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base64::decode("ABCDE"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base64::decode("A==="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base64::decode("AAAA===="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base64::decode("AAAAA==="), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(base64::decode("A&B="), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base64::decode("--"), cppcodec::symbol_error&); // this is not base64url REQUIRE_THROWS_AS(base64::decode("__"), cppcodec::symbol_error&); // ...ditto } } TEST_CASE("base64 (unpadded URL-safe)", "[base64][url_unpadded]") { using base64 = cppcodec::base64_url_unpadded; SECTION("encoded size calculation") { REQUIRE(base64::encoded_size(0) == 0); REQUIRE(base64::encoded_size(1) == 2); REQUIRE(base64::encoded_size(2) == 3); REQUIRE(base64::encoded_size(3) == 4); REQUIRE(base64::encoded_size(4) == 6); REQUIRE(base64::encoded_size(5) == 7); REQUIRE(base64::encoded_size(6) == 8); REQUIRE(base64::encoded_size(7) == 10); REQUIRE(base64::encoded_size(12) == 16); } SECTION("maximum decoded size calculation") { REQUIRE(base64::decoded_max_size(0) == 0); REQUIRE(base64::decoded_max_size(1) == 0); REQUIRE(base64::decoded_max_size(2) == 1); REQUIRE(base64::decoded_max_size(3) == 2); REQUIRE(base64::decoded_max_size(4) == 3); REQUIRE(base64::decoded_max_size(5) == 3); REQUIRE(base64::decoded_max_size(6) == 4); REQUIRE(base64::decoded_max_size(7) == 5); REQUIRE(base64::decoded_max_size(8) == 6); REQUIRE(base64::decoded_max_size(9) == 6); REQUIRE(base64::decoded_max_size(10) == 7); REQUIRE(base64::decoded_max_size(11) == 8); REQUIRE(base64::decoded_max_size(12) == 9); REQUIRE(base64::decoded_max_size(16) == 12); } SECTION("encoding data") { REQUIRE(base64::encode(std::vector()) == ""); REQUIRE(base64::encode(std::vector({0})) == "AA"); REQUIRE(base64::encode(std::vector({0, 0})) == "AAA"); REQUIRE(base64::encode(std::vector({0, 0, 0})) == "AAAA"); REQUIRE(base64::encode(std::vector({0, 0, 0, 0})) == "AAAAAA"); REQUIRE(base64::encode(std::vector({0, 0, 0, 0, 0})) == "AAAAAAA"); REQUIRE(base64::encode(std::vector({0, 0, 0, 0, 0, 0})) == "AAAAAAAA"); // RFC 4648: 9. Illustrations and Examples, adapted for more special characters REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})) == "FPu_A9l-"); REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9})) == "FPu_A9k"); REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03})) == "FPu_Aw"); // RFC 4648: 10. Test Vectors REQUIRE(base64::encode(std::string("")) == ""); REQUIRE(base64::encode(std::string("f")) == "Zg"); REQUIRE(base64::encode(std::string("fo")) == "Zm8"); REQUIRE(base64::encode(std::string("foo")) == "Zm9v"); REQUIRE(base64::encode(std::string("foob")) == "Zm9vYg"); REQUIRE(base64::encode(std::string("fooba")) == "Zm9vYmE"); REQUIRE(base64::encode(std::string("foobar")) == "Zm9vYmFy"); // Other test strings. REQUIRE(base64::encode(std::string("123")) == "MTIz"); REQUIRE(base64::encode(std::string("ABC")) == "QUJD"); REQUIRE(base64::encode(std::string("\xFF\xFF\xFF")) == "____"); } SECTION("decoding data") { REQUIRE(base64::decode("") == std::vector()); REQUIRE(base64::decode("AA") == std::vector({0})); REQUIRE(base64::decode("AAA") == std::vector({0, 0})); REQUIRE(base64::decode("AAAA") == std::vector({0, 0, 0})); REQUIRE(base64::decode("AAAAAA") == std::vector({0, 0, 0, 0})); REQUIRE(base64::decode("AAAAAAA") == std::vector({0, 0, 0, 0, 0})); REQUIRE(base64::decode("AAAAAAAA") == std::vector({0, 0, 0, 0, 0, 0})); // RFC 4648: 9. Illustrations and Examples, adapted for more special characters REQUIRE(base64::decode("FPu_A9l-") == std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})); REQUIRE(base64::decode("FPu_A9k") == std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9})); REQUIRE(base64::decode("FPu_Aw") == std::vector({0x14, 0xFB, 0xBF, 0x03})); // RFC 4648: 10. Test Vectors REQUIRE(base64::decode("") == ""); REQUIRE(base64::decode("Zg") == "f"); REQUIRE(base64::decode("Zg==") == "f"); REQUIRE(base64::decode("Zm8") == "fo"); REQUIRE(base64::decode("Zm8=") == "fo"); REQUIRE(base64::decode("Zm9v") == "foo"); REQUIRE(base64::decode("Zm9vYg") == "foob"); REQUIRE(base64::decode("Zm9vYg==") == "foob"); REQUIRE(base64::decode("Zm9vYmE") == "fooba"); REQUIRE(base64::decode("Zm9vYmE=") == "fooba"); REQUIRE(base64::decode("Zm9vYmFy") == "foobar"); // Other test strings. REQUIRE(base64::decode("MTIz") == "123"); REQUIRE(base64::decode("QUJD") == "ABC"); REQUIRE(base64::decode("____") == std::vector({255, 255, 255})); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(base64::decode("A"), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base64::decode("AAAAA"), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(base64::decode("A&B"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base64::decode("++"), cppcodec::symbol_error&); // this is not standard base64 REQUIRE_THROWS_AS(base64::decode("//"), cppcodec::symbol_error&); // ...ditto } } TEST_CASE("base64 (URL-safe)", "[base64][url]") { using base64 = cppcodec::base64_url; SECTION("encoded size calculation") { REQUIRE(base64::encoded_size(0) == 0); REQUIRE(base64::encoded_size(1) == 4); REQUIRE(base64::encoded_size(2) == 4); REQUIRE(base64::encoded_size(3) == 4); REQUIRE(base64::encoded_size(4) == 8); REQUIRE(base64::encoded_size(5) == 8); REQUIRE(base64::encoded_size(6) == 8); REQUIRE(base64::encoded_size(7) == 12); REQUIRE(base64::encoded_size(12) == 16); } SECTION("maximum decoded size calculation") { REQUIRE(base64::decoded_max_size(0) == 0); REQUIRE(base64::decoded_max_size(1) == 0); REQUIRE(base64::decoded_max_size(2) == 0); REQUIRE(base64::decoded_max_size(3) == 0); REQUIRE(base64::decoded_max_size(4) == 3); REQUIRE(base64::decoded_max_size(5) == 3); REQUIRE(base64::decoded_max_size(6) == 3); REQUIRE(base64::decoded_max_size(7) == 3); REQUIRE(base64::decoded_max_size(8) == 6); REQUIRE(base64::decoded_max_size(9) == 6); REQUIRE(base64::decoded_max_size(10) == 6); REQUIRE(base64::decoded_max_size(11) == 6); REQUIRE(base64::decoded_max_size(12) == 9); REQUIRE(base64::decoded_max_size(16) == 12); } SECTION("encoding data") { REQUIRE(base64::encode(std::vector()) == ""); REQUIRE(base64::encode(std::vector({0})) == "AA=="); REQUIRE(base64::encode(std::vector({0, 0})) == "AAA="); REQUIRE(base64::encode(std::vector({0, 0, 0})) == "AAAA"); REQUIRE(base64::encode(std::vector({0, 0, 0, 0})) == "AAAAAA=="); REQUIRE(base64::encode(std::vector({0, 0, 0, 0, 0})) == "AAAAAAA="); REQUIRE(base64::encode(std::vector({0, 0, 0, 0, 0, 0})) == "AAAAAAAA"); // RFC 4648: 9. Illustrations and Examples, adapted for more special characters REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})) == "FPu_A9l-"); REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9})) == "FPu_A9k="); REQUIRE(base64::encode(std::vector({0x14, 0xFB, 0xBF, 0x03})) == "FPu_Aw=="); // RFC 4648: 10. Test Vectors REQUIRE(base64::encode(std::string("")) == ""); REQUIRE(base64::encode(std::string("f")) == "Zg=="); REQUIRE(base64::encode(std::string("fo")) == "Zm8="); REQUIRE(base64::encode(std::string("foo")) == "Zm9v"); REQUIRE(base64::encode(std::string("foob")) == "Zm9vYg=="); REQUIRE(base64::encode(std::string("fooba")) == "Zm9vYmE="); REQUIRE(base64::encode(std::string("foobar")) == "Zm9vYmFy"); // Other test strings. REQUIRE(base64::encode(std::string("123")) == "MTIz"); REQUIRE(base64::encode(std::string("ABC")) == "QUJD"); REQUIRE(base64::encode(std::string("\xFF\xFF\xFF")) == "____"); } SECTION("decoding data") { REQUIRE(base64::decode("") == std::vector()); REQUIRE(base64::decode("AA==") == std::vector({0})); REQUIRE(base64::decode("AAA=") == std::vector({0, 0})); REQUIRE(base64::decode("AAAA") == std::vector({0, 0, 0})); REQUIRE(base64::decode("AAAAAA==") == std::vector({0, 0, 0, 0})); REQUIRE(base64::decode("AAAAAAA=") == std::vector({0, 0, 0, 0, 0})); REQUIRE(base64::decode("AAAAAAAA") == std::vector({0, 0, 0, 0, 0, 0})); // RFC 4648: 9. Illustrations and Examples, adapted for more special characters REQUIRE(base64::decode("FPu_A9l-") == std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9, 0x7E})); REQUIRE(base64::decode("FPu_A9k=") == std::vector({0x14, 0xFB, 0xBF, 0x03, 0xD9})); REQUIRE(base64::decode("FPu_Aw==") == std::vector({0x14, 0xFB, 0xBF, 0x03})); // RFC 4648: 10. Test Vectors REQUIRE(base64::decode("") == ""); REQUIRE(base64::decode("Zg==") == "f"); REQUIRE(base64::decode("Zm8=") == "fo"); REQUIRE(base64::decode("Zm9v") == "foo"); REQUIRE(base64::decode("Zm9vYg==") == "foob"); REQUIRE(base64::decode("Zm9vYmE=") == "fooba"); REQUIRE(base64::decode("Zm9vYmFy") == "foobar"); // Other test strings. REQUIRE(base64::decode("MTIz") == "123"); REQUIRE(base64::decode("QUJD") == "ABC"); REQUIRE(base64::decode("____") == std::vector({255, 255, 255})); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(base64::decode("A"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base64::decode("AA"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base64::decode("ABCDE"), cppcodec::padding_error&); REQUIRE_THROWS_AS(base64::decode("A==="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base64::decode("AAAA===="), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(base64::decode("AAAAA==="), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(base64::decode("A&B="), cppcodec::symbol_error&); REQUIRE_THROWS_AS(base64::decode("++"), cppcodec::symbol_error&); // this is not standard base64 REQUIRE_THROWS_AS(base64::decode("//"), cppcodec::symbol_error&); // ...ditto } } TEST_CASE("hex (lowercase)", "[hex][lower]") { using hex = cppcodec::hex_lower; SECTION("encoded size calculation") { REQUIRE(hex::encoded_size(0) == 0); REQUIRE(hex::encoded_size(1) == 2); REQUIRE(hex::encoded_size(2) == 4); REQUIRE(hex::encoded_size(3) == 6); REQUIRE(hex::encoded_size(4) == 8); REQUIRE(hex::encoded_size(5) == 10); REQUIRE(hex::encoded_size(6) == 12); REQUIRE(hex::encoded_size(8) == 16); REQUIRE(hex::encoded_size(10) == 20); } SECTION("maximum decoded size calculation") { REQUIRE(hex::decoded_max_size(0) == 0); REQUIRE(hex::decoded_max_size(1) == 0); REQUIRE(hex::decoded_max_size(2) == 1); REQUIRE(hex::decoded_max_size(3) == 1); REQUIRE(hex::decoded_max_size(4) == 2); REQUIRE(hex::decoded_max_size(5) == 2); REQUIRE(hex::decoded_max_size(6) == 3); REQUIRE(hex::decoded_max_size(7) == 3); REQUIRE(hex::decoded_max_size(8) == 4); REQUIRE(hex::decoded_max_size(9) == 4); REQUIRE(hex::decoded_max_size(10) == 5); REQUIRE(hex::decoded_max_size(16) == 8); REQUIRE(hex::decoded_max_size(20) == 10); } SECTION("encoding data") { REQUIRE(hex::encode(std::vector()) == ""); REQUIRE(hex::encode(std::vector({0})) == "00"); REQUIRE(hex::encode(std::vector({0, 0})) == "0000"); REQUIRE(hex::encode(std::vector({0, 0, 0})) == "000000"); REQUIRE(hex::encode(std::vector({0, 0, 0, 0})) == "00000000"); REQUIRE(hex::encode(std::vector({0, 0, 0, 0, 0})) == "0000000000"); REQUIRE(hex::encode(std::vector({0, 0, 0, 0, 0, 0})) == "000000000000"); // Constructing an std::string reduces the size of the char array by one (null terminator). // Therefore, the result for passing the string literal directly ends up encoding // one more character, which produces two more symbols in this particular case. REQUIRE(hex::encode(std::string("1")) == "31"); REQUIRE(hex::encode("1") == "3100"); REQUIRE(hex::encode(std::string("A")) == "41"); REQUIRE(hex::encode(std::vector({255})) == "ff"); // RFC 4648: 10. Test Vectors REQUIRE(hex::encode(std::string("")) == ""); REQUIRE(hex::encode(std::string("f")) == "66"); REQUIRE(hex::encode(std::string("fo")) == "666f"); REQUIRE(hex::encode(std::string("foo")) == "666f6f"); REQUIRE(hex::encode(std::string("foob")) == "666f6f62"); REQUIRE(hex::encode(std::string("fooba")) == "666f6f6261"); REQUIRE(hex::encode(std::string("foobar")) == "666f6f626172"); } SECTION("decoding data") { REQUIRE(hex::decode("") == std::vector()); REQUIRE(hex::decode("00") == std::vector({0})); REQUIRE(hex::decode("0000") == std::vector({0, 0})); REQUIRE(hex::decode("000000") == std::vector({0, 0, 0})); REQUIRE(hex::decode("00000000") == std::vector({0, 0, 0, 0})); REQUIRE(hex::decode("0000000000") == std::vector({0, 0, 0, 0, 0})); REQUIRE(hex::decode("000000000000") == std::vector({0, 0, 0, 0, 0, 0})); // For decoding data, the result should be the same whether or not there is // a null terminator at the end, because the input is a string (not binary array). REQUIRE(hex::decode(std::string("31")) == "1"); REQUIRE(hex::decode("31") == "1"); // RFC 4648: 10. Test Vectors REQUIRE(hex::decode("") == ""); REQUIRE(hex::decode("66") == "f"); REQUIRE(hex::decode("666f") == "fo"); REQUIRE(hex::decode("666f6f") == "foo"); REQUIRE(hex::decode("666f6f62") == "foob"); REQUIRE(hex::decode("666f6f6261") == "fooba"); REQUIRE(hex::decode("666f6f626172") == "foobar"); // Uppercase should decode just as well as lowercase. REQUIRE(hex::decode("666F6F6261") == "fooba"); REQUIRE(hex::decode("666F6f6261") == "fooba"); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(hex::decode("0"), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(hex::decode("000"), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(hex::decode("1g"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(hex::decode("66 6f"), cppcodec::symbol_error&); // no spaces REQUIRE_THROWS_AS(hex::decode("66-6f"), cppcodec::symbol_error&); // no dashes } } TEST_CASE("hex (uppercase)", "[hex][upper]") { using hex = cppcodec::hex_upper; SECTION("encoded size calculation") { REQUIRE(hex::encoded_size(0) == 0); REQUIRE(hex::encoded_size(1) == 2); REQUIRE(hex::encoded_size(2) == 4); REQUIRE(hex::encoded_size(3) == 6); REQUIRE(hex::encoded_size(4) == 8); REQUIRE(hex::encoded_size(5) == 10); REQUIRE(hex::encoded_size(6) == 12); REQUIRE(hex::encoded_size(8) == 16); REQUIRE(hex::encoded_size(10) == 20); } SECTION("maximum decoded size calculation") { REQUIRE(hex::decoded_max_size(0) == 0); REQUIRE(hex::decoded_max_size(1) == 0); REQUIRE(hex::decoded_max_size(2) == 1); REQUIRE(hex::decoded_max_size(3) == 1); REQUIRE(hex::decoded_max_size(4) == 2); REQUIRE(hex::decoded_max_size(5) == 2); REQUIRE(hex::decoded_max_size(6) == 3); REQUIRE(hex::decoded_max_size(7) == 3); REQUIRE(hex::decoded_max_size(8) == 4); REQUIRE(hex::decoded_max_size(9) == 4); REQUIRE(hex::decoded_max_size(10) == 5); REQUIRE(hex::decoded_max_size(16) == 8); REQUIRE(hex::decoded_max_size(20) == 10); } SECTION("encoding data") { REQUIRE(hex::encode(std::vector()) == ""); REQUIRE(hex::encode(std::vector({0})) == "00"); REQUIRE(hex::encode(std::vector({0, 0})) == "0000"); REQUIRE(hex::encode(std::vector({0, 0, 0})) == "000000"); REQUIRE(hex::encode(std::vector({0, 0, 0, 0})) == "00000000"); REQUIRE(hex::encode(std::vector({0, 0, 0, 0, 0})) == "0000000000"); REQUIRE(hex::encode(std::vector({0, 0, 0, 0, 0, 0})) == "000000000000"); // Constructing an std::string reduces the size of the char array by one (null terminator). // Therefore, the result for passing the string literal directly ends up encoding // one more character, which produces two more symbols in this particular case. REQUIRE(hex::encode(std::string("1")) == "31"); REQUIRE(hex::encode("1") == "3100"); REQUIRE(hex::encode(std::string("A")) == "41"); REQUIRE(hex::encode(std::vector({255})) == "FF"); // RFC 4648: 10. Test Vectors REQUIRE(hex::encode(std::string("")) == ""); REQUIRE(hex::encode(std::string("f")) == "66"); REQUIRE(hex::encode(std::string("fo")) == "666F"); REQUIRE(hex::encode(std::string("foo")) == "666F6F"); REQUIRE(hex::encode(std::string("foob")) == "666F6F62"); REQUIRE(hex::encode(std::string("fooba")) == "666F6F6261"); REQUIRE(hex::encode(std::string("foobar")) == "666F6F626172"); } SECTION("decoding data") { REQUIRE(hex::decode("") == std::vector()); REQUIRE(hex::decode("00") == std::vector({0})); REQUIRE(hex::decode("0000") == std::vector({0, 0})); REQUIRE(hex::decode("000000") == std::vector({0, 0, 0})); REQUIRE(hex::decode("00000000") == std::vector({0, 0, 0, 0})); REQUIRE(hex::decode("0000000000") == std::vector({0, 0, 0, 0, 0})); REQUIRE(hex::decode("000000000000") == std::vector({0, 0, 0, 0, 0, 0})); // For decoding data, the result should be the same whether or not there is // a null terminator at the end, because the input is a string (not binary array). REQUIRE(hex::decode(std::string("31")) == "1"); REQUIRE(hex::decode("31") == "1"); // RFC 4648: 10. Test Vectors REQUIRE(hex::decode("") == ""); REQUIRE(hex::decode("66") == "f"); REQUIRE(hex::decode("666F") == "fo"); REQUIRE(hex::decode("666F6F") == "foo"); REQUIRE(hex::decode("666F6F62") == "foob"); REQUIRE(hex::decode("666F6F6261") == "fooba"); REQUIRE(hex::decode("666F6F626172") == "foobar"); // Lowercase should decode just as well as uppercase. REQUIRE(hex::decode("666f6f6261") == "fooba"); REQUIRE(hex::decode("666f6F6261") == "fooba"); // An invalid number of symbols should throw the right kind of parse_error. REQUIRE_THROWS_AS(hex::decode("0"), cppcodec::invalid_input_length&); REQUIRE_THROWS_AS(hex::decode("000"), cppcodec::invalid_input_length&); // An invalid symbol should throw a symbol error. REQUIRE_THROWS_AS(hex::decode("1G"), cppcodec::symbol_error&); REQUIRE_THROWS_AS(hex::decode("66 6F"), cppcodec::symbol_error&); // no spaces REQUIRE_THROWS_AS(hex::decode("66-6F"), cppcodec::symbol_error&); // no dashes } } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/CMakeLists.txt0000644000175000017500000000061613221173144022547 0ustar janjan00000000000000# For cppcodec itself, don't prefer system headers over development ones. include_directories(BEFORE ${PROJECT_SOURCE_DIR}) add_executable(base32enc base32enc.cpp) add_executable(base32dec base32dec.cpp) add_executable(base64enc base64enc.cpp) add_executable(base64dec base64dec.cpp) add_executable(hexenc hexenc.cpp) add_executable(hexdec hexdec.cpp) add_executable(helloworld helloworld.cpp) nitrokey-app-1.3.2/3rdparty/cppcodec/tool/base32dec.cpp0000644000175000017500000000361113221173144022244 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) { size_t arglen = strlen(argv[i]); try { std::cout << cppcodec::base32_crockford::decode(argv[i], arglen) << std::endl; } catch (const cppcodec::parse_error& e) { std::cout << "#" << i << ": " << e.what() << std::endl; } try { std::cout << cppcodec::base32_rfc4648::decode(argv[i], arglen) << std::endl; } catch (const cppcodec::parse_error& e) { std::cout << "#" << i << ": " << e.what() << std::endl; } } return 0; } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/base32enc.cpp0000644000175000017500000000311013221173144022250 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) { size_t arglen = strlen(argv[i]); std::cout << cppcodec::base32_crockford::encode(argv[i], arglen) << std::endl; std::cout << cppcodec::base32_rfc4648::encode(argv[i], arglen) << std::endl; } return 0; } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/base64dec.cpp0000644000175000017500000000357513221173144022262 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) { size_t arglen = strlen(argv[i]); try { std::cout << cppcodec::base64_rfc4648::decode(argv[i], arglen) << std::endl; } catch (const cppcodec::parse_error& e) { std::cout << "#" << i << ": " << e.what() << std::endl; } try { std::cout << cppcodec::base64_url::decode(argv[i], arglen) << std::endl; } catch (const cppcodec::parse_error& e) { std::cout << "#" << i << ": " << e.what() << std::endl; } } return 0; } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/base64enc.cpp0000644000175000017500000000307413221173144022266 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) { size_t arglen = strlen(argv[i]); std::cout << cppcodec::base64_rfc4648::encode(argv[i], arglen) << std::endl; std::cout << cppcodec::base64_url::encode(argv[i], arglen) << std::endl; } return 0; } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/helloworld.cpp0000644000175000017500000000325513221173144022670 0ustar janjan00000000000000/** * This is free and unencumbered software released into the public domain. * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * For more information, please refer to */ #include #include #include int main() { std::vector decoded = base64::decode("YW55IGNhcm5hbCBwbGVhc3VyZQ=="); std::cout << "decoded size (\"any carnal pleasure\"): " << decoded.size() << '\n'; std::cout << base32::encode(decoded) << std::endl; // "C5Q7J833C5S6WRBC41R6RSB1EDTQ4S8" return 0; } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/hexdec.cpp0000644000175000017500000000356113221173144021755 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) { size_t arglen = strlen(argv[i]); try { std::cout << cppcodec::hex_lower::decode(argv[i], arglen) << std::endl; } catch (const cppcodec::parse_error& e) { std::cout << "#" << i << ": " << e.what() << std::endl; } try { std::cout << cppcodec::hex_upper::decode(argv[i], arglen) << std::endl; } catch (const cppcodec::parse_error& e) { std::cout << "#" << i << ": " << e.what() << std::endl; } } return 0; } nitrokey-app-1.3.2/3rdparty/cppcodec/tool/hexenc.cpp0000644000175000017500000000306113221173144021762 0ustar janjan00000000000000/** * Copyright (C) 2015 Topology LP * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #include #include int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) { size_t arglen = strlen(argv[i]); std::cout << cppcodec::hex_lower::encode(argv[i], arglen) << std::endl; std::cout << cppcodec::hex_upper::encode(argv[i], arglen) << std::endl; } return 0; }