diff options
author | Marius David Wieschollek <passwords.public@mdns.eu> | 2020-01-13 22:46:04 +0300 |
---|---|---|
committer | Marius David Wieschollek <passwords.public@mdns.eu> | 2020-01-13 22:46:04 +0300 |
commit | 0fcdbfe39264cf04daca3a52ebdc8d1ec55a7290 (patch) | |
tree | 7a0dcb7ce865ad0ddb8dc96a02c6abc5cf5a80b4 | |
parent | cbf025d7825f28fbe555cd18cb0f13bde2698d50 (diff) |
Throw errors when unsupported encryption types found
Signed-off-by: Marius David Wieschollek <passwords.public@mdns.eu>
-rw-r--r-- | src/Api/Api.js | 5 | ||||
-rw-r--r-- | src/Authorization/Challenge/PWDv1Challenge.js | 21 | ||||
-rw-r--r-- | src/Authorization/SessionAuthorization.js | 21 | ||||
-rw-r--r-- | src/Encryption/CSEv1Encryption.js | 2 | ||||
-rw-r--r-- | src/Encryption/Keychain/CSEv1Keychain.js | 1 | ||||
-rw-r--r-- | src/Exception/ChallengeTypeNotSupported.js | 9 | ||||
-rw-r--r-- | src/Exception/EncryptionTypeNotSupported.js | 29 | ||||
-rw-r--r-- | src/Exception/TokenTypeNotSupported.js | 9 | ||||
-rw-r--r-- | src/Repositories/FolderRepository.js | 2 | ||||
-rw-r--r-- | src/Repositories/PasswordRepository.js | 2 | ||||
-rw-r--r-- | src/Repositories/TagRepository.js | 2 |
11 files changed, 84 insertions, 19 deletions
diff --git a/src/Api/Api.js b/src/Api/Api.js index db21b18..a2d1957 100644 --- a/src/Api/Api.js +++ b/src/Api/Api.js @@ -35,6 +35,8 @@ import HttpError from '../Exception/Http/HttpError'; import EventEmitter from 'eventemitter3'; import UserToken from '../Authorization/Token/UserToken'; import RequestToken from '../Authorization/Token/RequestToken'; +import TokenTypeNotSupported from '../Exception/TokenTypeNotSupported'; +import EncryptionTypeNotSupported from '../Exception/EncryptionTypeNotSupported'; export default class Api { @@ -278,6 +280,9 @@ export default class Api { contenttype : ResponseContentTypeError, decoding : ResponseDecodingError, property : UnknownPropertyError, + challenge : TokenTypeNotSupported, + token : TokenTypeNotSupported, + encryption : EncryptionTypeNotSupported, network : NetworkError, http : HttpError, 400 : BadRequestError, diff --git a/src/Authorization/Challenge/PWDv1Challenge.js b/src/Authorization/Challenge/PWDv1Challenge.js index ebd55fc..13a3559 100644 --- a/src/Authorization/Challenge/PWDv1Challenge.js +++ b/src/Authorization/Challenge/PWDv1Challenge.js @@ -72,15 +72,15 @@ export default class PWDv1Challenge { 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 = this._generateRandom(256), - genericHashKey = this._generateRandom(sodium.crypto_generichash_KEYBYTES_MAX), + 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 = this._generateRandom(sodium.crypto_pwhash_SALTBYTES), + let passwordHashSalt = sodium.sodium(sodium.crypto_pwhash_SALTBYTES), passwordHash = sodium.crypto_pwhash( sodium.crypto_box_SEEDBYTES, genericHash, @@ -99,19 +99,4 @@ export default class PWDv1Challenge { secret: sodium.to_hex(passwordHash) } } - - // noinspection JSMethodCanBeStatic - /** - * - * @param length - * @returns {Uint8Array} - * @private - * @deprecated - */ - _generateRandom(length) { - let array = new Uint8Array(length); - window.crypto.getRandomValues(array); - - return array; - } }
\ No newline at end of file diff --git a/src/Authorization/SessionAuthorization.js b/src/Authorization/SessionAuthorization.js index 7389998..1b9b853 100644 --- a/src/Authorization/SessionAuthorization.js +++ b/src/Authorization/SessionAuthorization.js @@ -29,7 +29,7 @@ export default class SessionAuthorization { let requirements = response.getData(); if(requirements.hasOwnProperty('challenge')) { - this._challenge = this._api.getClass('challenge.pwdv1', requirements.challenge); + this._createChallenge(requirements.challenge); } if(requirements.hasOwnProperty('token')) { this._createTokens(requirements.token); @@ -150,10 +150,25 @@ export default class SessionAuthorization { /** * + * @param {Object} challenge + * @private + */ + _createChallenge(challenge) { + if(challenge.type === 'PWDv1r1') { + this._challenge = this._api.getClass('challenge.pwdv1', challenge); + } else { + throw new this._api.getClass('exception.challenge'); + } + } + + /** + * * @param {Object[]} tokens * @private */ _createTokens(tokens) { + this._tokens = []; + for(let token of tokens) { if(token.type === 'user-token') { let model = this._api.getClass('token.user', this._api, token.id, token.label, token.description, token.request); @@ -164,5 +179,9 @@ export default class SessionAuthorization { this._tokens.push(model); } } + + if(this._tokens.length === 0 && tokens.length !== 0) { + throw new this._api.getClass('exception.token'); + } } }
\ No newline at end of file diff --git a/src/Encryption/CSEv1Encryption.js b/src/Encryption/CSEv1Encryption.js index ddd75fd..8a7d347 100644 --- a/src/Encryption/CSEv1Encryption.js +++ b/src/Encryption/CSEv1Encryption.js @@ -29,6 +29,7 @@ export default class CSEv1Encryption { * @returns {Object} */ async encrypt(object, type) { + // TODO custom errors here if(!this.fields.hasOwnProperty(type)) throw new Error('Invalid object type'); await this.ready(); @@ -57,6 +58,7 @@ export default class CSEv1Encryption { * @returns {Object} */ async decrypt(object, type) { + // TODO custom errors here if(!this.fields.hasOwnProperty(type)) throw new Error('Invalid object type'); if(object.cseType !== 'CSEv1r1') throw new Error('Unsupported encryption type'); await this.ready(); diff --git a/src/Encryption/Keychain/CSEv1Keychain.js b/src/Encryption/Keychain/CSEv1Keychain.js index b2d49f7..ba3904b 100644 --- a/src/Encryption/Keychain/CSEv1Keychain.js +++ b/src/Encryption/Keychain/CSEv1Keychain.js @@ -47,6 +47,7 @@ export default class CSEv1Keychain { return this._keys[id]; } + // TODO custom error here throw new Error('Unknown CSE key id'); } diff --git a/src/Exception/ChallengeTypeNotSupported.js b/src/Exception/ChallengeTypeNotSupported.js new file mode 100644 index 0000000..106bfa2 --- /dev/null +++ b/src/Exception/ChallengeTypeNotSupported.js @@ -0,0 +1,9 @@ +export default class ChallengeTypeNotSupported extends Error { + + /** + * + */ + constructor() { + super('The required authentication challenge is not supported by this client'); + } +}
\ No newline at end of file diff --git a/src/Exception/EncryptionTypeNotSupported.js b/src/Exception/EncryptionTypeNotSupported.js new file mode 100644 index 0000000..b1fefc4 --- /dev/null +++ b/src/Exception/EncryptionTypeNotSupported.js @@ -0,0 +1,29 @@ +export default class EncryptionTypeNotSupported extends Error { + + /** + * + * @return {string} + */ + get objectId() { + return this._objectId; + } + + /** + * + * @return {string} + */ + get cseType() { + return this._cseType; + } + + /** + * + * @param {string} objectId + * @param {string} cseType + */ + constructor(objectId, cseType) { + super(`The encryption type ${cseType} used for ${objectId} is not supported by this client`); + this._objectId = objectId; + this._cseType = cseType; + } +}
\ No newline at end of file diff --git a/src/Exception/TokenTypeNotSupported.js b/src/Exception/TokenTypeNotSupported.js new file mode 100644 index 0000000..8db0b4f --- /dev/null +++ b/src/Exception/TokenTypeNotSupported.js @@ -0,0 +1,9 @@ +export default class TokenTypeNotSupported extends Error{ + + /** + * + */ + constructor() { + super('None of the available tokens are supported by this client.'); + } +}
\ No newline at end of file diff --git a/src/Repositories/FolderRepository.js b/src/Repositories/FolderRepository.js index a06d362..0bacf31 100644 --- a/src/Repositories/FolderRepository.js +++ b/src/Repositories/FolderRepository.js @@ -107,6 +107,8 @@ export default class FolderRepository { async _dataToModel(data) { if(data.cseType === 'CSEv1r1') { data = await this._api.getCseV1Encryption().decrypt(data, 'folder'); + } else if(data.cseType !== 'none') { + throw new this._api.getClass('exception.encryption', data.id, data.cseType); } let folder = this._api.getClass('model.folder', this._api, data); diff --git a/src/Repositories/PasswordRepository.js b/src/Repositories/PasswordRepository.js index f0a34fa..87f3274 100644 --- a/src/Repositories/PasswordRepository.js +++ b/src/Repositories/PasswordRepository.js @@ -107,6 +107,8 @@ export default class PasswordRepository { async _dataToModel(data) { if(data.cseType === 'CSEv1r1') { data = await this._api.getCseV1Encryption().decrypt(data, 'password'); + } else if(data.cseType !== 'none') { + throw new this._api.getClass('exception.encryption', data.id, data.cseType); } let password = this._api.getClass('model.password', this._api, data); diff --git a/src/Repositories/TagRepository.js b/src/Repositories/TagRepository.js index 4b3df4d..d2ca891 100644 --- a/src/Repositories/TagRepository.js +++ b/src/Repositories/TagRepository.js @@ -107,6 +107,8 @@ export default class TagRepository { async _dataToModel(data) { if(data.cseType === 'CSEv1r1') { data = await this._api.getCseV1Encryption().decrypt(data, 'tag'); + } else if(data.cseType !== 'none') { + throw new this._api.getClass('exception.encryption', data.id, data.cseType); } let tag = this._api.getClass('model.tag', this._api, data); |