61 lines
2.4 KiB
C++
61 lines
2.4 KiB
C++
/*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
* SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
|
|
*/
|
|
#ifndef OATH_H
|
|
#define OATH_H
|
|
|
|
#include <QByteArray>
|
|
#include <QCryptographicHash>
|
|
#include <QDateTime>
|
|
#include <QSharedPointer>
|
|
|
|
#include <functional>
|
|
#include <optional>
|
|
|
|
namespace oath
|
|
{
|
|
class Encoder
|
|
{
|
|
public:
|
|
Encoder(uint tokenLength, bool addChecksum = false);
|
|
virtual ~Encoder();
|
|
virtual QString encode(quint32) const;
|
|
uint tokenLength(void) const;
|
|
bool checksum(void) const;
|
|
static quint32 reduceMod10(quint32 value, uint tokenLength);
|
|
private:
|
|
Q_DISABLE_COPY_MOVE(Encoder)
|
|
private:
|
|
static constexpr const quint32 powerTable[10] = {
|
|
1, 10, 100, 1'000, 10'000, 100'000, 1'000'000, 10'000'000, 100'000'000, 1'000'000'000
|
|
};
|
|
const uint m_tokenLength;
|
|
const bool m_addChecksum;
|
|
};
|
|
|
|
class Algorithm
|
|
{
|
|
public:
|
|
static bool validate(const Encoder *encoder);
|
|
static bool validate(QCryptographicHash::Algorithm algorithm, const std::optional<uint> offset);
|
|
static std::optional<Algorithm> create(QCryptographicHash::Algorithm algorithm, const std::optional<uint> offset, const QSharedPointer<const Encoder> &encoder, bool requireSaneKeyLength = false);
|
|
static std::optional<Algorithm> totp(QCryptographicHash::Algorithm algorithm, uint tokenLength, bool requireSaneKeyLength = false);
|
|
static std::optional<Algorithm> hotp(const std::optional<uint> offset, uint tokenLength, bool checksum, bool requireSaneKeyLength = false);
|
|
std::optional<QString> compute(quint64 counter, char * secretBuffer, int length) const;
|
|
private:
|
|
Algorithm(const QSharedPointer<const Encoder> &encoder, const std::function<quint32(const QByteArray &)> &truncation, QCryptographicHash::Algorithm algorithm, bool requireSaneKeyLength);
|
|
private:
|
|
const QSharedPointer<const Encoder> m_encoder;
|
|
const std::function<quint32(const QByteArray &)> m_truncation;
|
|
bool m_enforceKeyLength;
|
|
const QCryptographicHash::Algorithm m_algorithm;
|
|
};
|
|
|
|
uint luhnChecksum(quint32 value, uint digits);
|
|
std::optional<quint64> count(const QDateTime &epoch, uint timeStep, const std::function<qint64(void)> &clock = &QDateTime::currentMSecsSinceEpoch);
|
|
std::optional<QDateTime> fromCounter(quint64 count, const QDateTime &epoch, uint timeStep);
|
|
}
|
|
|
|
#endif
|