File indexing completed on 2024-05-05 05:53:14

0001 /*
0002  * SPDX-License-Identifier: GPL-3.0-or-later
0003  * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
0004  */
0005 #ifndef SECRETS_H
0006 #define SECRETS_H
0007 
0008 #include "sodium_cpp.h"
0009 #include "../hmac/hmac.h"
0010 
0011 #include <QByteArray>
0012 #include <QCryptographicHash>
0013 #include <QString>
0014 
0015 #include <functional>
0016 #include <optional>
0017 
0018 namespace secrets
0019 {
0020     class EncryptedSecret
0021     {
0022     public:
0023         static std::optional<EncryptedSecret> from(const QByteArray& cryptText, const QByteArray& nonce);
0024         const QByteArray& cryptText(void) const;
0025         const QByteArray& nonce(void) const;
0026         unsigned long long messageLength(void) const;
0027     private:
0028         EncryptedSecret(const QByteArray &taggedCryptText, const QByteArray &nonce);
0029     private:
0030         const QByteArray m_taggedCryptText;
0031         const QByteArray m_nonce;
0032     };
0033 
0034     class KeyDerivationParameters
0035     {
0036     public:
0037         static std::optional<KeyDerivationParameters> create(unsigned long long keyLength = crypto_secretbox_KEYBYTES,
0038                                                       int algorithm = crypto_pwhash_ALG_DEFAULT,
0039                                                       size_t memoryCost = crypto_pwhash_MEMLIMIT_MODERATE,
0040                                                       unsigned long long cpuCost = crypto_pwhash_OPSLIMIT_MODERATE);
0041         int algorithm(void) const;
0042         unsigned long long keyLength(void) const;
0043         size_t memoryCost(void) const;
0044         unsigned long long cpuCost(void) const;
0045     private:
0046         KeyDerivationParameters(int algorithm, unsigned long long keyLength, size_t memoryCost, unsigned long long cpuCost);
0047     private:
0048         const int m_algorithm;
0049         const unsigned long long m_keyLength;
0050         const size_t m_memoryCost;
0051         const unsigned long long m_cpuCost;
0052     };
0053 
0054     class SecureMemory
0055     {
0056     public:
0057         static SecureMemory * allocate(size_t size);
0058         virtual ~SecureMemory();
0059         size_t size(void) const;
0060         const unsigned char * constData(void) const;
0061         unsigned char * data(void);
0062     private:
0063         SecureMemory(void * memory, size_t size);
0064         Q_DISABLE_COPY(SecureMemory)
0065     private:
0066         unsigned char * const m_secureMemory;
0067         const size_t m_size;
0068     };
0069 
0070     using SecureRandom = std::function<bool(void *, size_t)>;
0071     bool defaultSecureRandom(void *data, size_t size);
0072 
0073     class SecureMasterKey
0074     {
0075     public:
0076         static bool validate(const SecureMemory *secret);
0077         static bool validate(const KeyDerivationParameters &params);
0078         static bool validate(const QByteArray &salt);
0079         static SecureMasterKey * derive(const SecureMemory *password, const KeyDerivationParameters &params, const SecureRandom &random = defaultSecureRandom);
0080         static SecureMasterKey * derive(const SecureMemory *password, const KeyDerivationParameters &params, const QByteArray &salt, const SecureRandom &random = defaultSecureRandom);
0081     public:
0082         const KeyDerivationParameters params(void) const;
0083         const QByteArray salt(void) const;
0084         virtual ~SecureMasterKey();
0085         std::optional<EncryptedSecret> encrypt(const SecureMemory *secret) const;
0086         SecureMemory * decrypt(const EncryptedSecret &secret) const;
0087     private:
0088         SecureMasterKey(unsigned char *keyMemory, const KeyDerivationParameters &params, const QByteArray &salt, const SecureRandom &random);
0089         Q_DISABLE_COPY(SecureMasterKey)
0090     private:
0091         unsigned char * const m_secureKeyMemory;
0092         const KeyDerivationParameters m_params;
0093         const QByteArray m_salt;
0094         const SecureRandom m_secureRandom;
0095     };
0096 
0097     SecureMemory * decodeBase32(const QString &encoded, int from = 0, int until = -1);
0098 }
0099 
0100 #endif