implement re-encryption of the acl shared_key when changing vault password

This commit is contained in:
binsky 2023-04-23 18:31:50 +02:00
Родитель 6660985f88
Коммит 776ffe6ea1
7 изменённых файлов: 77 добавлений и 10 удалений

Просмотреть файл

@ -58,6 +58,7 @@ return [
['name' => 'share#getPendingRequests', 'url' => '/api/v2/sharing/pending', 'verb' => 'GET'],
['name' => 'share#deleteShareRequest', 'url' => '/api/v2/sharing/decline/{share_request_id}', 'verb' => 'DELETE'],
['name' => 'share#getVaultItems', 'url' => '/api/v2/sharing/vault/{vault_guid}/get', 'verb' => 'GET'],
['name' => 'share#getVaultAclEntries', 'url' => '/api/v2/sharing/vault/{vault_guid}/acl', 'verb' => 'GET'],
['name' => 'share#createPublicShare', 'url' => '/api/v2/sharing/public', 'verb' => 'POST'],
['name' => 'share#getPublicCredentialData', 'url' => '/api/v2/sharing/credential/{credential_guid}/public', 'verb' => 'GET'],
['name' => 'share#unshareCredential', 'url' => '/api/v2/sharing/credential/{item_guid}', 'verb' => 'DELETE'],
@ -67,6 +68,7 @@ return [
['name' => 'share#uploadFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file', 'verb' => 'POST'],
['name' => 'share#getFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file/{file_guid}', 'verb' => 'GET'],
['name' => 'share#updateSharedCredentialACL', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'PATCH'],
['name' => 'share#updateSharedCredentialACLSharedKey', 'url' => '/api/v2/sharing/credential/{item_guid}/acl/shared_key', 'verb' => 'PATCH'],
['name' => 'internal#getAppVersion', 'url' => '/api/v2/version', 'verb' => 'GET'],
//Settings

Просмотреть файл

@ -368,6 +368,20 @@ class ShareController extends ApiController {
}
}
/**
* Obtains the list of acl entries for credentials shared with this vault
*
* @NoAdminRequired
* @NoCSRFRequired
*/
public function getVaultAclEntries($vault_guid) {
try {
return new JSONResponse($this->shareService->getVaultAclList($this->userId->getUID(), $vault_guid));
} catch (\Exception $ex) {
return new NotFoundResponse();
}
}
/**
* @param $share_request_id
* @return JSONResponse
@ -557,4 +571,18 @@ class ShareController extends ApiController {
}
}
/**
* @param $item_guid
* @param $shared_key
* @return JSONResponse
* @NoAdminRequired
* @NoCSRFRequired
*/
public function updateSharedCredentialACLSharedKey($item_guid, $shared_key) {
/** @var SharingACL $acl */
$acl = $this->shareService->getACL($this->userId->getUID(), $item_guid);
$acl->setSharedKey($shared_key);
return new JSONResponse($this->shareService->updateCredentialACL($acl)->jsonSerialize());
}
}

Просмотреть файл

@ -78,13 +78,12 @@
}
_credential.tags_raw = _credential.tags;
} catch (e) {
NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
console.error(e);
//$rootScope.$broadcast('logout');
//SettingsService.setSetting('defaultVaultPass', null);
//.setSetting('defaultVault', null);
//$location.path('/')
}
_credentials[i] = _credential;
}

Просмотреть файл

@ -250,8 +250,10 @@
vault.private_sharing_key = EncryptService.decryptString(angular.copy(vault.private_sharing_key), oldVaultPass);
vault.private_sharing_key = EncryptService.encryptString(vault.private_sharing_key, newVaultPass);
VaultService.updateSharingKeys(vault).then(function () {
$rootScope.$broadcast('logout');
NotificationService.showNotification($translate.instant('login.new.pass'), 5000);
VaultService.reEncryptACLSharingKeys(vault, oldVaultPass, newVaultPass, EncryptService).then(function () {
$rootScope.$broadcast('logout');
NotificationService.showNotification($translate.instant('login.new.pass'), 5000);
});
});
}
};
@ -259,11 +261,12 @@
if (_selected_credentials[index].shared_key) {
// only re-encrypt the shared key, if the credential is shared and not encrypted with the vault key like default credentials
CredentialService.getCredential(_selected_credentials[index].guid).then((function (credential) {
let decrypted_shared_key = EncryptService.decryptString(angular.copy(credential.shared_key), oldVaultPass);
credential.set_share_key = true;
credential.skip_revision = true;
credential.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
CredentialService.updateCredential(credential, true).then(next_credential_callback);
const decrypted_shared_key = EncryptService.decryptString(angular.copy(credential.shared_key), oldVaultPass);
let _credential = angular.copy(credential);
_credential.set_share_key = true;
_credential.skip_revision = true;
_credential.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
CredentialService.updateCredential(_credential, true).then(next_credential_callback);
}));
} else {
CredentialService.reencryptCredential(_selected_credentials[index].guid, oldVaultPass, newVaultPass).progress(function (data) {

Просмотреть файл

@ -141,13 +141,13 @@
}
} catch (e) {
console.error('Error decrypting credential:', credential);
console.error('Error decrypting credential field:', field);
throw e;
}
try {
credential[field] = JSON.parse(field_decrypted_value);
} catch (e) {
console.warn('Field' + field + ' in ' + credential.label + ' could not be parsed! Value:' + fieldValue);
}
}

Просмотреть файл

@ -122,6 +122,30 @@
}
});
},
reEncryptACLSharingKeys: function (vault, oldVaultPass, newVaultPass, EncryptService) {
const queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault.guid + '/acl');
return $http.get(queryUrl).then(function (response) {
if (response.data) {
const updateACLSharingKey = function (index) {
let acl = response.data[index];
const decrypted_shared_key = EncryptService.decryptString(angular.copy(acl.shared_key), oldVaultPass);
acl.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
const patchUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + acl.item_guid + '/acl/shared_key');
$http.patch(patchUrl, {
shared_key: acl.shared_key
}).then(function () {
if (index < response.data.length - 1) {
return updateACLSharingKey(index + 1);
}
});
};
if (response.data[0]) {
return updateACLSharingKey(0);
}
}
});
},
deleteVault: function (vault, file_ids) {
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid);
var deleteFilesUrl = OC.generateUrl('apps/passman/api/v2/files/delete');

Просмотреть файл

@ -273,6 +273,17 @@ class ShareService {
return $this->sharingACL->getCredentialAclList($item_guid);
}
/**
* Get the access control list by vault guid
*
* @param string $user_id
* @param string $vault_guid
* @return Entity[]
*/
public function getVaultAclList(string $user_id, string $vault_guid) {
return $this->sharingACL->getVaultEntries($user_id, $vault_guid);
}
/**
* @param string $item_guid
* @return Entity[]