Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.mdns.eu/nextcloud/passwords-client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius David Wieschollek <passwords.public@mdns.eu>2024-01-04 17:25:37 +0300
committerMarius David Wieschollek <passwords.public@mdns.eu>2024-01-04 17:25:37 +0300
commit501ebf83509f88ba93aece92ed8d73b13d2c62af (patch)
tree57c0bfcc5d84e88cc2057197d66cb657c54fc8e3
parent6e716981adeeade0a71414dbc445870614902a91 (diff)
Fix export encryption
Signed-off-by: Marius David Wieschollek <passwords.public@mdns.eu>
-rw-r--r--src/ClassLoader/DefaultClassLoader.js8
-rw-r--r--src/Encryption/ExportV1Encryption.js35
-rw-r--r--src/Services/EncryptionService.js85
3 files changed, 92 insertions, 36 deletions
diff --git a/src/ClassLoader/DefaultClassLoader.js b/src/ClassLoader/DefaultClassLoader.js
index 16ff9ec..a54e6f5 100644
--- a/src/ClassLoader/DefaultClassLoader.js
+++ b/src/ClassLoader/DefaultClassLoader.js
@@ -67,6 +67,8 @@ import Logger from "../Logger/Logger";
import DefectField from "../Model/CustomField/DefectField";
import PreconditionFailedError from "../Exception/Http/PreconditionFailedError";
import EventEmitter from "../Event/EventEmitter";
+import EncryptionService from "../Services/EncryptionService";
+import InvalidRangeError from "../Exception/Services/InvalidRangeError";
export default class DefaultClassLoader extends BasicClassLoader {
@@ -120,13 +122,14 @@ export default class DefaultClassLoader extends BasicClassLoader {
'encryption.none' : () => { return new NoEncryption(this.getInstance('classes')); },
'encryption.csev1': () => { return new CSEv1Encryption(this.getInstance('classes')); },
- 'encryption.expv1': () => { return new ExportV1Encryption(this.getInstance('classes')); },
+ 'encryption.expv1': () => { return new ExportV1Encryption(this.getInstance('service.encryption')); },
'keychain.csev1': (k, p) => { return new CSEv1Keychain(this.getInstance('classes'), k, p); },
- 'service.hash' : () => { return new HashService(this.getInstance('classes')); },
+ 'service.hash' : () => { return new HashService(this.getInstance('client')); },
'service.model' : () => { return new ModelService(this.getInstance('classes')); },
'service.password': () => { return new PasswordService(this.getInstance('client')); },
+ 'service.encryption': () => { return new EncryptionService(this.getInstance('classes')); },
'logger': Logger,
@@ -160,6 +163,7 @@ export default class DefaultClassLoader extends BasicClassLoader {
'exception.encryption.key.missing': MissingEncryptionKeyError,
'exception.encryption.text.length': InvalidEncryptedTextLength,
'exception.configuration' : ConfigurationError,
+ 'exception.service.range' : InvalidRangeError,
// Old deprecated errors
diff --git a/src/Encryption/ExportV1Encryption.js b/src/Encryption/ExportV1Encryption.js
index 4cd743e..609daec 100644
--- a/src/Encryption/ExportV1Encryption.js
+++ b/src/Encryption/ExportV1Encryption.js
@@ -1,36 +1,33 @@
import sodium from 'libsodium-wrappers';
-import CSEv1Encryption from './CSEv1Encryption';
-export default class ExportV1Encryption extends CSEv1Encryption {
+export default class ExportV1Encryption {
+
+ /**
+ * @param {EncryptionService} encryptionService
+ */
+ constructor(encryptionService) {
+ this._encryptionService = encryptionService;
+ }
/**
* Encrypts the message with the user defined password
*
- * @param message
- * @param password
+ * @param {String} message
+ * @param {String} password
* @returns {*}
*/
- encryptWithPassword(message, password) {
- let salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES),
- key = this._passwordToKey(password, salt),
- encrypted = this._encrypt(message, key);
-
- return sodium.to_hex(new Uint8Array([...salt, ...encrypted]));
+ async encrypt(message, password) {
+ return await this._encryptionService.encryptAsync(message, password);
}
/**
* Decrypts the message with the user defined password
*
- * @param message
- * @param password
+ * @param {String} message
+ * @param {String} password
* @returns {*}
*/
- decryptWithPassword(message, password) {
- let encrypted = sodium.from_hex(message),
- salt = encrypted.slice(0, sodium.crypto_pwhash_SALTBYTES),
- text = encrypted.slice(sodium.crypto_pwhash_SALTBYTES),
- key = this._passwordToKey(password, salt);
-
- return sodium.to_string(this._decrypt(text, key));
+ async decrypt(message, password) {
+ return await this._encryptionService.decryptAsync(message, password);
}
} \ No newline at end of file
diff --git a/src/Services/EncryptionService.js b/src/Services/EncryptionService.js
index 7f81498..af4c778 100644
--- a/src/Services/EncryptionService.js
+++ b/src/Services/EncryptionService.js
@@ -2,18 +2,43 @@ import sodium from 'libsodium-wrappers';
export default class EncryptionService {
- constructor() {
+ /**
+ *
+ * @param {BasicClassLoader} classLoader
+ */
+ constructor(classLoader) {
+ this._ready = classLoader.getClass('state.boolean', false);
+ this._classLoader = classLoader;
+
+ sodium.ready.then(() => {this._ready.set(true);});
+ }
+
+ /**
+ *
+ * @returns {Promise<Boolean>}
+ */
+ async ready() {
+ await this._ready.awaitTrue();
+ return true;
+ }
+
+ /**
+ * @returns {Boolean}
+ */
+ enabled() {
+ return this._ready.get();
}
/**
* Encrypt the message with the given key and return a hex encoded string
*
* @param {String} message
- * @param {String} key
+ * @param {String} passphrase
* @returns {String}
- * @private
*/
encrypt(message, passphrase) {
+ if(!this.enabled()) throw this._classLoader.getClass('exception.encryption.enabled');
+
let {key, salt} = this._passwordToKey(passphrase);
let encrypted = this._encrypt(message, key);
@@ -21,20 +46,48 @@ export default class EncryptionService {
}
/**
- * Decrypt the hex or base64 encoded message with the given key
+ * Decrypt the hex encoded message with the given key
*
- * @param {String} encodedString
- * @param {Uint8Array} key
+ * @param {String} message
+ * @param {Uint8Array} passphrase
* @returns {String}
- * @private
*/
- _decryptString(encodedString, passphrase) {
- let salt = encodedString.slice(0, sodium.crypto_pwhash_SALTBYTES),
+ decrypt(message, passphrase) {
+ if(!this.enabled()) throw this._classLoader.getClass('exception.encryption.enabled');
+
+ let encodedString = sodium.from_hex(message),
+ salt = encodedString.slice(0, sodium.crypto_pwhash_SALTBYTES),
text = encodedString.slice(sodium.crypto_pwhash_SALTBYTES),
- key = this._passwordToKey(passphrase, salt);
+ {key, } = this._passwordToKey(passphrase, salt);
return sodium.to_string(this._decrypt(text, key));
}
+
+ /**
+ * Encrypt the message with the given key and return a hex encoded string
+ *
+ * @param {String} message
+ * @param {String} passphrase
+ * @returns {Promise<String>}
+ */
+ async encryptAsync(message, passphrase) {
+ await this.ready();
+ return this.encrypt(message, passphrase);
+ }
+
+
+ /**
+ Decrypt the hex encoded message with the given key
+
+ @param {String} message
+ @param {Uint8Array} passphrase
+ * @returns {Promise<String>}
+ */
+ async decryptAsync(message, passphrase) {
+ await this.ready();
+ return this.decrypt(message, passphrase);
+ }
+
/**
* Encrypt the message with the given key
*
@@ -69,13 +122,15 @@ export default class EncryptionService {
// noinspection JSMethodCanBeStatic
/**
*
- * @param password
- * @param salt
- * @returns {Uint8Array}
+ * @param {String} password
+ * @param {String} salt
+ * @return {{salt: *, key: *}}
* @private
*/
- _passwordToKey(password) {
- let salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES);
+ _passwordToKey(password, salt = null) {
+ if(salt === null) {
+ salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES);
+ }
let key = sodium.crypto_pwhash(
sodium.crypto_box_SEEDBYTES,