From d28c59544fbd1fc1d5e9c5517d6a82d97d4353c8 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 6 Oct 2017 21:23:14 -0400 Subject: [PATCH] encrypt/decrypt ciphers --- src/app/services/cipherService.js | 202 +++++++++++++++++++++++++++++- 1 file changed, 200 insertions(+), 2 deletions(-) diff --git a/src/app/services/cipherService.js b/src/app/services/cipherService.js index 94e0d9552b..3095f70a09 100644 --- a/src/app/services/cipherService.js +++ b/src/app/services/cipherService.js @@ -1,7 +1,7 @@ angular .module('bit.services') - .factory('cipherService', function (cryptoService, apiService, $q, $window) { + .factory('cipherService', function (cryptoService, apiService, $q, $window, constants) { var _service = {}; _service.decryptLogins = function (encryptedLogins) { @@ -15,7 +15,7 @@ angular return unencryptedLogins; }; - _service.decryptLogin = function (encryptedLogin, isCipher) { + _service.decryptLogin = function (encryptedLogin) { if (!encryptedLogin) throw "encryptedLogin is undefined or null"; var key = null; @@ -58,6 +58,88 @@ angular return login; }; + _service.decryptCiphers = function (encryptedCiphers) { + if (!encryptedCiphers) throw "encryptedCiphers is undefined or null"; + + var unencryptedCiphers = []; + for (var i = 0; i < encryptedCiphers.length; i++) { + unencryptedCiphers.push(_service.decryptLogin(encryptedCiphers[i])); + } + + return unencryptedCiphers; + }; + + _service.decryptCipher = function (encryptedCipher) { + if (!encryptedCipher) throw "encryptedCipher is undefined or null"; + + var key = null; + if (encryptedCipher.OrganizationId) { + key = cryptoService.getOrgKey(encryptedLogin.OrganizationId); + } + + var cipher = { + id: encryptedCipher.Id, + organizationId: encryptedCipher.OrganizationId, + collectionIds: encryptedCipher.CollectionIds || [], + 'type': encryptedCipher.Type, + folderId: encryptedCipher.FolderId, + favorite: encryptedCipher.Favorite, + edit: encryptedCipher.Edit, + organizationUseTotp: encryptedCipher.OrganizationUseTotp, + attachments: null + }; + + var cipherData = encryptedCipher.Data; + if (cipherData) { + cipher.name = cryptoService.decrypt(cipherData.Name, key); + cipher.notes = cipherData.Notes && cipherData.Notes !== '' ? cryptoService.decrypt(cipherData.Notes, key) : null; + cipher.fields = _service.decryptFields(key, cipherData.Fields); + + var dataObj = {}; + switch (cipher.type) { + case constants.cipherType.login: + dataObj.uri = cipherData.Uri && cipherData.Uri !== '' ? cryptoService.decrypt(cipherData.Uri, key) : null; + dataObj.username = cipherData.Username && cipherData.Username !== '' ? cryptoService.decrypt(cipherData.Username, key) : null; + dataObj.password = cipherData.Password && cipherData.Password !== '' ? cryptoService.decrypt(cipherData.Password, key) : null; + dataObj.totp = cipherData.Totp && cipherData.Totp !== '' ? cryptoService.decrypt(cipherData.Totp, key) : null; + cipher.login = dataObj; + break; + case constants.cipherType.secureNote: + dataObj.type = cipherData.Type; + cipher.secureNote = dataObj; + break; + case constants.cipherType.card: + dataObj.cardholderName = cipherData.CardholderName && cipherData.CardholderName !== '' ? cryptoService.decrypt(cipherData.CardholderName, key) : null; + dataObj.number = cipherData.Number && cipherData.Number !== '' ? cryptoService.decrypt(cipherData.Number, key) : null; + dataObj.brand = cipherData.Brand && cipherData.Brand !== '' ? cryptoService.decrypt(cipherData.Brand, key) : null; + dataObj.expMonth = cipherData.ExpMonth && cipherData.ExpMonth !== '' ? cryptoService.decrypt(cipherData.ExpMonth, key) : null; + dataObj.expYear = cipherData.ExpYear && cipherData.ExpYear !== '' ? cryptoService.decrypt(cipherData.ExpYear, key) : null; + dataObj.code = cipherData.Code && cipherData.Code !== '' ? cryptoService.decrypt(cipherData.Code, key) : null; + cipher.card = dataObj; + break; + case constants.cipherType.identity: + dataObj.firstName = cipherData.FirstName && cipherData.FirstName !== '' ? cryptoService.decrypt(cipherData.FirstName, key) : null; + dataObj.middleName = cipherData.MiddleName && cipherData.MiddleName !== '' ? cryptoService.decrypt(cipherData.MiddleName, key) : null; + dataObj.lastName = cipherData.LastName && cipherData.LastName !== '' ? cryptoService.decrypt(cipherData.LastName, key) : null; + cipher.identity = dataObj; + break; + default: + break; + } + } + + if (!encryptedCipher.Attachments) { + return cipher; + } + + cipher.attachments = []; + for (var i = 0; i < encryptedCipher.Attachments.length; i++) { + cipher.attachments.push(_service.decryptAttachment(key, encryptedCipher.Attachments[i])); + } + + return cipher; + }; + _service.decryptLoginPreview = function (encryptedCipher) { if (!encryptedCipher) throw "encryptedCipher is undefined or null"; @@ -87,6 +169,55 @@ angular return login; }; + _service.decryptCipherPreview = function (encryptedCipher) { + if (!encryptedCipher) throw "encryptedCipher is undefined or null"; + + var key = null; + if (encryptedCipher.OrganizationId) { + key = cryptoService.getOrgKey(encryptedCipher.OrganizationId); + } + + var cipher = { + id: encryptedCipher.Id, + organizationId: encryptedCipher.OrganizationId, + collectionIds: encryptedCipher.CollectionIds || [], + folderId: encryptedCipher.FolderId, + favorite: encryptedCipher.Favorite, + edit: encryptedCipher.Edit, + organizationUseTotp: encryptedCipher.OrganizationUseTotp, + hasAttachments: !!encryptedCipher.Attachments && encryptedCipher.Attachments.length > 0 + }; + + var cipherData = encryptedCipher.Data; + if (cipherData) { + cipher.name = _service.decryptProperty(cipherData.Name, key, false); + + var dataObj = {}; + switch (cipher.type) { + case constants.cipherType.login: + cipher.subTitle = _service.decryptProperty(cipherData.Username, key, true); + cipher.password = _service.decryptProperty(cipherData.Password, key, true); + break; + case constants.cipherType.secureNote: + cipher.subTitle = 'secure note'; // TODO: what to do for this sub title? + break; + case constants.cipherType.card: + cipher.number = _service.decryptProperty(cipherData.Number, key, true); + var brand = _service.decryptProperty(cipherData.Brand, key, true); + cipher.subTitle = brand + ', *1234'; // TODO: last 4 of number + break; + case constants.cipherType.identity: + var firstName = _service.decryptProperty(cipherData.FirstName, key, true); + cipher.subTitle = firstName; + break; + default: + break; + } + } + + return login; + }; + _service.decryptAttachment = function (key, encryptedAttachment) { if (!encryptedAttachment) throw "encryptedAttachment is undefined or null"; @@ -272,6 +403,73 @@ angular return login; }; + _service.encryptCipher = function (unencryptedCipher, type, key, attachments) { + if (!unencryptedCipher) throw "unencryptedCipher is undefined or null"; + + if (unencryptedCipher.organizationId) { + key = key || cryptoService.getOrgKey(unencryptedCipher.organizationId); + } + + var cipher = { + id: unencryptedCipher.id, + 'type': type, + organizationId: unencryptedCipher.organizationId || null, + folderId: unencryptedCipher.folderId === '' ? null : unencryptedCipher.folderId, + favorite: unencryptedCipher.favorite !== null ? unencryptedCipher.favorite : false, + name: cryptoService.encrypt(unencryptedCipher.name, key), + notes: !unencryptedCipher.notes || unencryptedCipher.notes === '' ? null : cryptoService.encrypt(unencryptedCipher.notes, key), + fields: _service.encryptFields(unencryptedCipher.fields, key) + }; + + switch (cipher.type) { + case constants.cipherType.login: + var loginData = unencryptedCipher.login; + cipher.login = { + uri: !loginData.uri || loginData.uri === '' ? null : cryptoService.encrypt(loginData.uri, key), + username: !loginData.username || loginData.username === '' ? null : cryptoService.encrypt(loginData.username, key), + password: !loginData.password || loginData.password === '' ? null : cryptoService.encrypt(loginData.password, key), + totp: !loginData.totp || loginData.totp === '' ? null : cryptoService.encrypt(loginData.totp, key) + }; + break; + case constants.cipherType.secureNote: + cipher.secureNote = { + type: unencryptedCipher.secureNote.type + }; + break; + case constants.cipherType.card: + var cardData = unencryptedCipher.card; + cipher.card = { + cardholderName: !cardData.cardholderName || cardData.cardholderName === '' ? null : cryptoService.encrypt(cardData.cardholderName, key), + brand: !cardData.brand || cardData.brand === '' ? null : cryptoService.encrypt(cardData.brand, key), + number: !cardData.number || cardData.number === '' ? null : cryptoService.encrypt(cardData.number, key), + expMonth: !cardData.expMonth || cardData.expMonth === '' ? null : cryptoService.encrypt(cardData.expMonth, key), + expYear: !cardData.expYear || cardData.expYear === '' ? null : cryptoService.encrypt(cardData.expYear, key), + code: !cardData.code || cardData.code === '' ? null : cryptoService.encrypt(cardData.code, key), + }; + break; + case constants.cipherType.identity: + var identityData = unencryptedCipher.identity; + cipher.identity = { + firstName: !identityData.firstName || cardData.firstName === '' ? null : cryptoService.encrypt(cardData.firstName, key), + middleName: !identityData.middleName || cardData.middleName === '' ? null : cryptoService.encrypt(cardData.middleName, key), + lastName: !identityData.lastName || cardData.lastName === '' ? null : cryptoService.encrypt(cardData.lastName, key) + }; + break; + default: + break; + } + + if (unencryptedCipher.attachments && attachments) { + cipher.attachments = {}; + for (var i = 0; i < unencryptedCipher.attachments.length; i++) { + cipher.attachments[unencryptedCipher.attachments[i].id] = + cryptoService.encrypt(unencryptedCipher.attachments[i].fileName, key); + } + } + + return cipher; + }; + _service.encryptAttachmentFile = function (key, unencryptedFile) { var deferred = $q.defer();