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:
Diffstat (limited to 'src/Authorization/Challenge/PWDv1Challenge.js')
-rw-r--r--src/Authorization/Challenge/PWDv1Challenge.js102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/Authorization/Challenge/PWDv1Challenge.js b/src/Authorization/Challenge/PWDv1Challenge.js
new file mode 100644
index 0000000..13a3559
--- /dev/null
+++ b/src/Authorization/Challenge/PWDv1Challenge.js
@@ -0,0 +1,102 @@
+import sodium from 'libsodium-wrappers';
+
+export default class PWDv1Challenge {
+
+ constructor(data) {
+ this._salts = null;
+ if(data.hasOwnProperty('salts')) {
+ this._salts = data.salts;
+ }
+ this._password = null;
+ }
+
+ /**
+ *
+ * @returns {null}
+ */
+ getPassword() {
+ return this._password;
+ }
+
+ /**
+ *
+ * @param value
+ * @returns {PWDv1Challenge}
+ */
+ setPassword(value) {
+ this._password = value;
+
+ return this;
+ }
+
+ /**
+ * Generate a challenge solution with the user provided password
+ * and the server provided salts
+ *
+ * @returns {string}
+ */
+ solve() {
+ if(this._password.length < 12) throw new Error('Password is too short');
+ if(this._password.length > 128) throw new Error('Password is too long');
+ let salts = this._salts;
+
+ let passwordSalt = sodium.from_hex(salts[0]),
+ genericHashKey = sodium.from_hex(salts[1]),
+ passwordHashSalt = sodium.from_hex(salts[2]),
+ genericHash = sodium.crypto_generichash(
+ sodium.crypto_generichash_BYTES_MAX,
+ new Uint8Array([...sodium.from_string(this._password), ...passwordSalt]),
+ genericHashKey
+ );
+
+ let passwordHash = sodium.crypto_pwhash(
+ sodium.crypto_box_SEEDBYTES,
+ genericHash,
+ passwordHashSalt,
+ sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
+ sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
+ sodium.crypto_pwhash_ALG_DEFAULT
+ );
+
+
+ return sodium.to_hex(passwordHash);
+ }
+
+ /**
+ * Create the salts and the secret for the server
+ * using the user provided password
+ *
+ * @returns {{salts: *[], secret: *}}
+ */
+ create() {
+ if(this._password.length < 12) throw new Error('Password is too short');
+ if(this._password.length > 128) throw new Error('Password is too long');
+
+ let passwordSalt = sodium.randombytes_buf(256),
+ genericHashKey = sodium.randombytes_buf(sodium.crypto_generichash_KEYBYTES_MAX),
+ genericHash = sodium.crypto_generichash(
+ sodium.crypto_generichash_BYTES_MAX,
+ new Uint8Array([...sodium.from_string(this._password), ...passwordSalt]),
+ genericHashKey
+ );
+
+ let passwordHashSalt = sodium.sodium(sodium.crypto_pwhash_SALTBYTES),
+ passwordHash = sodium.crypto_pwhash(
+ sodium.crypto_box_SEEDBYTES,
+ genericHash,
+ passwordHashSalt,
+ sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
+ sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
+ sodium.crypto_pwhash_ALG_DEFAULT
+ );
+
+ return {
+ salts : [
+ sodium.to_hex(passwordSalt),
+ sodium.to_hex(genericHashKey),
+ sodium.to_hex(passwordHashSalt)
+ ],
+ secret: sodium.to_hex(passwordHash)
+ }
+ }
+} \ No newline at end of file