Throw errors when unsupported encryption types found

Signed-off-by: Marius David Wieschollek's avatarMarius David Wieschollek <passwords.public@mdns.eu>
parent cbf025d7
......@@ -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,
......
......@@ -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
......@@ -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);
......@@ -148,12 +148,27 @@ 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
......@@ -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();
......
......@@ -47,6 +47,7 @@ export default class CSEv1Keychain {
return this._keys[id];
}
// TODO custom error here
throw new Error('Unknown CSE key id');
}
......
export default class ChallengeTypeNotSupported extends Error {
/**
*
*/
constructor() {
super('The required authentication challenge is not supported by this client');
}
}
\ No newline at end of file
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
export default class TokenTypeNotSupported extends Error{
/**
*
*/
constructor() {
super('None of the available tokens are supported by this client.');
}
}
\ No newline at end of file
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment