Commit 8c473dac authored by Karel Slaný's avatar Karel Slaný

Computing PIN hash and storing it to configuration file.

parent 55505843
......@@ -23,8 +23,12 @@ winphone|winrt|win32 {
QMAKE_CXXFLAGS += \
-g -O0 -std=c++11 \
-Wall -Wextra -pedantic
SOURCES += src/crypto/crypto.c
HEADERS += src/crypto/crypto.h
SOURCES += \
src/crypto/crypto.c \
src/crypto/pin.c
HEADERS += \
src/crypto/crypto.h \
src/crypto/pin.h
LIBS += \
-lcrypto
}
......
......@@ -27,6 +27,7 @@
#include <openssl/cms.h>
#include <openssl/err.h>
#include <string.h>
#include "src/crypto/crypto.h"
/* Extract data from CMS (successor of PKCS#7)
......
/*
* Copyright (C) 2014-2016 CZ.NIC
*
* 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 <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include <assert.h>
#include <openssl/evp.h>
#include "src/crypto/pin.h"
#define PBKDF2_SHA256_NAME "PBKDF2-HMAC-SHA-256-64"
#define PBKDF2_SHA256_ITER 1000 /* Do not change the value as it will break PIN checking. */
#define PBKDF2_SHA256_OUT 32
/*!
* @brief PBKDF2-SHA256 generates 32 byte hashes.
*/
static
int pbkdf2_sha256_func(const void *pass, size_t pass_len,
const void *salt, size_t salt_len, int iter, void *out, size_t out_len)
{
return PKCS5_PBKDF2_HMAC(pass, pass_len, salt, salt_len, iter,
EVP_sha256(), out_len, out) == 1 ? 0 : -1;
}
const struct pin_alg pbkdf2_sha256 = {
.name = PBKDF2_SHA256_NAME,
.iter = PBKDF2_SHA256_ITER,
.out_len = PBKDF2_SHA256_OUT,
.func = pbkdf2_sha256_func
};
/*
* Copyright (C) 2014-2016 CZ.NIC
*
* 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 <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#ifndef _PIN_H_
#define _PIN_H_
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PIN_HASH_MAX 128
/*!
* @brief Hash function prototype.
*
* @param[in] pass Password/PIN.
* @param[in] pass_len Password length.
* @param[in] salt Salt.
* @param[in] salt_len Salt length.
* @param[in] iter Number of iterations (should be >= 1, RFC 2898 suggests >= 1000).
* @param[out] out Buffer to write generated password/hash into.
* @param[in] out_len Size of output buffer.
*
* @retval 0 Success.
* @retval -1 Error.
*/
typedef int (*key_hash_func)(const void *pass, size_t pass_len,
const void *salt, size_t salt_len, int iter, void *out, size_t out_len);
/*!
* @brief Describes the PIN hashing algorithm.
*/
struct pin_alg {
const char *name; /*!< Algorithm name. */
int iter; /*!< Brief Number of iterations. */
int out_len; /*!< Generated output length. */
key_hash_func func; /*!< Hash function. */
};
extern const struct pin_alg pbkdf2_sha256;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _PIN_H_ */
......@@ -74,6 +74,9 @@ int main(int argc, char *argv[])
QCoreApplication::addLibraryPath("./");
QApplication app(argc, argv);
/* Initialise random number generator. */
qsrand(QDateTime::currentDateTimeUtc().toTime_t());
/* set application data, indentification, etc. */
app.setOrganizationName(APP_ORG_NAME);
app.setOrganizationDomain(APP_ORG_DOMAIN);
......
......@@ -40,6 +40,9 @@ Settings::Settings(void)
msgLifeTimeInDays(DEFAULT_MSG_LIFETIME),
fileLifeTimeInDays(DEFAULT_FILE_LIFETIME),
_pinVal(),
pinAlg(),
pinSalt(),
pinCode(),
lastUpdate("")
{
}
......@@ -71,7 +74,20 @@ void Settings::saveGlobalSettingsToFile(QSettings &settings) const
if (!globSet._pinVal.isEmpty()) {
settings.setValue(SETTINGS_PIN_VAL,
QString::fromUtf8(globSet._pinVal.toUtf8().toBase64()));
Q_ASSERT(!globSet.pinAlg.isEmpty());
settings.setValue(SETTINGS_PIN_ALG,
globSet.pinAlg);
Q_ASSERT(!globSet.pinSalt.isEmpty());
settings.setValue(SETTINGS_PIN_SALT,
QString::fromUtf8(globSet.pinSalt.toBase64()));
Q_ASSERT(!globSet.pinCode.isEmpty());
settings.setValue(SETTINGS_PIN_VAL,
QString::fromUtf8(globSet.pinCode.toBase64()));
}
settings.setValue(SETTINGS_LAST_UPDATE, globSet.lastUpdate);
settings.endGroup();
}
......
......@@ -44,6 +44,9 @@
#define SETTINGS_MSG_LIFETIME_IN_DAYS "msg_lifetime"
#define SETTINGS_FILE_LIFETIME_IN_DAYS "file_lifetime"
#define SETTINGS_PIN_VAL "pin_val"
#define SETTINGS_PIN_ALG "pin_alg"
#define SETTINGS_PIN_SALT "pin_salt"
#define SETTINGS_PIN_CODE "pin_code"
#define SETTINGS_LAST_UPDATE "last_update"
#define SETTINGS_LANGUAGE "language"
#define SETTINGS_FONTSIZE "font_size"
......@@ -93,6 +96,9 @@ public:
int msgLifeTimeInDays;
int fileLifeTimeInDays;
QString _pinVal; /*! PIN value is not read from the configuration file, nor it is stored to the configuration file. */
QString pinAlg; /*!< PIN algorithm identifier. */
QByteArray pinSalt; /*!< Salt value used to generate PIN hash. */
QByteArray pinCode; /*!< Hashed PIN code. */
QString lastUpdate;
};
......
......@@ -22,8 +22,9 @@
*/
#include "src/setwrapper.h"
#include "src/crypto/pin.h"
#include "src/settings.h"
#include "src/setwrapper.h"
GlobalSettingsQmlWrapper::GlobalSettingsQmlWrapper(QObject *parent)
: QObject(parent)
......@@ -117,10 +118,30 @@ void GlobalSettingsQmlWrapper::updateSettings(const QString &language,
void GlobalSettingsQmlWrapper::updatePinSettings(const QString &pinValue)
/* ========================================================================= */
{
unsigned char hash[PIN_HASH_MAX];
if (!pinValue.isEmpty()) {
/* Store PIN value. */
globSet._pinVal = pinValue;
/* Currently there is only one algorithm. */
globSet.pinAlg = pbkdf2_sha256.name;
/* Generate random salt. */
globSet.pinSalt.clear();
for (int i = 0; i < 32; ++i) {
globSet.pinSalt.append(qrand() % 256);
}
/* Compute PIN code. */
QByteArray pin(globSet._pinVal.toUtf8());
pbkdf2_sha256.func(pin.constData(), pin.size(),
globSet.pinSalt.constData(), globSet.pinSalt.size(),
pbkdf2_sha256.iter, hash, pbkdf2_sha256.out_len);
globSet.pinCode = QByteArray((char *)hash, pbkdf2_sha256.out_len);
} else {
globSet._pinVal.clear();
globSet.pinAlg.clear();
globSet.pinSalt.clear();
globSet.pinCode.clear();
}
QSettings settings(Settings::settingsPath(), QSettings::IniFormat);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment