clientsideencryption.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #ifndef CLIENTSIDEENCRYPTION_H
  2. #define CLIENTSIDEENCRYPTION_H
  3. #include <QString>
  4. #include <QObject>
  5. #include <QJsonDocument>
  6. #include <QSslCertificate>
  7. #include <QSslKey>
  8. #include <QFile>
  9. #include <QVector>
  10. #include <QMap>
  11. #include <openssl/evp.h>
  12. #include "accountfwd.h"
  13. #include "networkjobs.h"
  14. namespace QKeychain {
  15. class Job;
  16. class WritePasswordJob;
  17. class ReadPasswordJob;
  18. }
  19. namespace OCC {
  20. QString e2eeBaseUrl();
  21. namespace EncryptionHelper {
  22. QByteArray generateRandomFilename();
  23. OWNCLOUDSYNC_EXPORT QByteArray generateRandom(int size);
  24. QByteArray generatePassword(const QString &wordlist, const QByteArray& salt);
  25. OWNCLOUDSYNC_EXPORT QByteArray encryptPrivateKey(
  26. const QByteArray& key,
  27. const QByteArray& privateKey,
  28. const QByteArray &salt
  29. );
  30. OWNCLOUDSYNC_EXPORT QByteArray decryptPrivateKey(
  31. const QByteArray& key,
  32. const QByteArray& data
  33. );
  34. OWNCLOUDSYNC_EXPORT QByteArray extractPrivateKeySalt(const QByteArray &data);
  35. OWNCLOUDSYNC_EXPORT QByteArray encryptStringSymmetric(
  36. const QByteArray& key,
  37. const QByteArray& data
  38. );
  39. OWNCLOUDSYNC_EXPORT QByteArray decryptStringSymmetric(
  40. const QByteArray& key,
  41. const QByteArray& data
  42. );
  43. QByteArray privateKeyToPem(const QByteArray key);
  44. //TODO: change those two EVP_PKEY into QSslKey.
  45. QByteArray encryptStringAsymmetric(
  46. EVP_PKEY *publicKey,
  47. const QByteArray& data
  48. );
  49. QByteArray decryptStringAsymmetric(
  50. EVP_PKEY *privateKey,
  51. const QByteArray& data
  52. );
  53. OWNCLOUDSYNC_EXPORT bool fileEncryption(const QByteArray &key, const QByteArray &iv,
  54. QFile *input, QFile *output, QByteArray& returnTag);
  55. OWNCLOUDSYNC_EXPORT bool fileDecryption(const QByteArray &key, const QByteArray &iv,
  56. QFile *input, QFile *output);
  57. //
  58. // Simple classes for safe (RAII) handling of OpenSSL
  59. // data structures
  60. //
  61. class CipherCtx {
  62. public:
  63. CipherCtx() : _ctx(EVP_CIPHER_CTX_new())
  64. {
  65. }
  66. ~CipherCtx()
  67. {
  68. EVP_CIPHER_CTX_free(_ctx);
  69. }
  70. operator EVP_CIPHER_CTX*()
  71. {
  72. return _ctx;
  73. }
  74. private:
  75. Q_DISABLE_COPY(CipherCtx)
  76. EVP_CIPHER_CTX *_ctx;
  77. };
  78. class OWNCLOUDSYNC_EXPORT StreamingDecryptor
  79. {
  80. public:
  81. StreamingDecryptor(const QByteArray &key, const QByteArray &iv, quint64 totalSize);
  82. ~StreamingDecryptor() = default;
  83. QByteArray chunkDecryption(const char *input, quint64 chunkSize);
  84. [[nodiscard]] bool isInitialized() const;
  85. [[nodiscard]] bool isFinished() const;
  86. private:
  87. Q_DISABLE_COPY(StreamingDecryptor)
  88. CipherCtx _ctx;
  89. bool _isInitialized = false;
  90. bool _isFinished = false;
  91. quint64 _decryptedSoFar = 0;
  92. quint64 _totalSize = 0;
  93. };
  94. }
  95. class OWNCLOUDSYNC_EXPORT ClientSideEncryption : public QObject {
  96. Q_OBJECT
  97. public:
  98. class PKey;
  99. ClientSideEncryption();
  100. void initialize(const AccountPtr &account);
  101. private:
  102. void generateKeyPair(const AccountPtr &account);
  103. void generateCSR(const AccountPtr &account, PKey keyPair);
  104. void sendSignRequestCSR(const AccountPtr &account, PKey keyPair, const QByteArray &csrContent);
  105. void encryptPrivateKey(const AccountPtr &account);
  106. public:
  107. void forgetSensitiveData(const AccountPtr &account);
  108. private slots:
  109. void publicKeyFetched(QKeychain::Job *incoming);
  110. void privateKeyFetched(QKeychain::Job *incoming);
  111. void mnemonicKeyFetched(QKeychain::Job *incoming);
  112. signals:
  113. void initializationFinished(bool isNewMnemonicGenerated = false);
  114. private:
  115. void getPrivateKeyFromServer(const AccountPtr &account);
  116. void getPublicKeyFromServer(const AccountPtr &account);
  117. void fetchAndValidatePublicKeyFromServer(const AccountPtr &account);
  118. void decryptPrivateKey(const AccountPtr &account, const QByteArray &key);
  119. void fetchFromKeyChain(const AccountPtr &account);
  120. [[nodiscard]] bool checkPublicKeyValidity(const AccountPtr &account) const;
  121. [[nodiscard]] bool checkServerPublicKeyValidity(const QByteArray &serverPublicKeyString) const;
  122. void writePrivateKey(const AccountPtr &account);
  123. void writeCertificate(const AccountPtr &account);
  124. void writeMnemonic(const AccountPtr &account);
  125. bool isInitialized = false;
  126. public:
  127. //QSslKey _privateKey;
  128. QByteArray _privateKey;
  129. QSslKey _publicKey;
  130. QSslCertificate _certificate;
  131. QString _mnemonic;
  132. bool _newMnemonicGenerated = false;
  133. };
  134. /* Generates the Metadata for the folder */
  135. struct EncryptedFile {
  136. QByteArray encryptionKey;
  137. QByteArray mimetype;
  138. QByteArray initializationVector;
  139. QByteArray authenticationTag;
  140. QString encryptedFilename;
  141. QString originalFilename;
  142. int fileVersion;
  143. int metadataKey;
  144. };
  145. class OWNCLOUDSYNC_EXPORT FolderMetadata {
  146. public:
  147. FolderMetadata(AccountPtr account, const QByteArray& metadata = QByteArray(), int statusCode = -1);
  148. QByteArray encryptedMetadata();
  149. void addEncryptedFile(const EncryptedFile& f);
  150. void removeEncryptedFile(const EncryptedFile& f);
  151. void removeAllEncryptedFiles();
  152. [[nodiscard]] QVector<EncryptedFile> files() const;
  153. private:
  154. /* Use std::string and std::vector internally on this class
  155. * to ease the port to Nlohmann Json API
  156. */
  157. void setupEmptyMetadata();
  158. void setupExistingMetadata(const QByteArray& metadata);
  159. [[nodiscard]] QByteArray encryptMetadataKey(const QByteArray& metadataKey) const;
  160. [[nodiscard]] QByteArray decryptMetadataKey(const QByteArray& encryptedKey) const;
  161. [[nodiscard]] QByteArray encryptJsonObject(const QByteArray& obj, const QByteArray pass) const;
  162. [[nodiscard]] QByteArray decryptJsonObject(const QByteArray& encryptedJsonBlob, const QByteArray& pass) const;
  163. QVector<EncryptedFile> _files;
  164. QMap<int, QByteArray> _metadataKeys;
  165. AccountPtr _account;
  166. QVector<QPair<QString, QString>> _sharing;
  167. };
  168. } // namespace OCC
  169. #endif