Automatically wrap lines in markdown files at 80 characters
This commit is contained in:
parent
051f47598a
commit
2b5b957a58
|
@ -4,5 +4,13 @@
|
|||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"bracketSpacing": true,
|
||||
"proseWrap": "always"
|
||||
}
|
||||
"overrides": [
|
||||
{
|
||||
"files": "**/*.md",
|
||||
"options": {
|
||||
"printWidth": 80,
|
||||
"proseWrap": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4,5 +4,7 @@
|
|||
"*.svg": "html"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"csscomb.formatOnSave": true
|
||||
"csscomb.formatOnSave": true,
|
||||
"prettier.prettierPath": "./node_modules/prettier",
|
||||
"files.insertFinalNewline": true
|
||||
}
|
||||
|
|
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -3,7 +3,8 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
and this project adheres to
|
||||
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 3.1.2
|
||||
|
||||
|
@ -22,18 +23,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Improved flow for creating a vault item
|
||||
- If a vault filter is active, preselect that vault during vault item creation
|
||||
- Prefill field names with sensible default when adding new field
|
||||
- Automated account migration if legacy account is detected during login/signup
|
||||
- Automated account migration if legacy account is detected during
|
||||
login/signup
|
||||
- "Login" vault item template is now called "Website / App"
|
||||
- Added new vault item template "Computer"
|
||||
- [DESKTOP] Ctrl/cmd + Shift + F to search all items (resetting any active filters)
|
||||
- [DESKTOP] Ctrl/cmd + Shift + F to search all items (resetting any active
|
||||
filters)
|
||||
- [ANDROID] Allow reordering fields via drag and drop on Android
|
||||
- [SERVER] Option to enable secure connection when sending emails, enabled via `PL_EMAIL_SECURE` environment variable
|
||||
- [SERVER] Option to enable secure connection when sending emails, enabled via
|
||||
`PL_EMAIL_SECURE` environment variable
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Sometimes the app would show a blank screen directly after unlocking.
|
||||
- Changes made to a vault item directly after creating it would sometimes be discarded.
|
||||
- Changes made to a vault item directly after creating it would sometimes be
|
||||
discarded.
|
||||
|
||||
## 3.0.0
|
||||
|
||||
Initial release of Padloc 3 (changes before 3.0.0 are not included in this change log).
|
||||
Initial release of Padloc 3 (changes before 3.0.0 are not included in this
|
||||
change log).
|
||||
|
|
108
README.md
108
README.md
|
@ -8,24 +8,26 @@ Simple, secure password and data management for individuals and teams.
|
|||
|
||||
This repo is split into multiple packages:
|
||||
|
||||
| Package Name | Description |
|
||||
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [@padloc/core](packages/core) | Core Logic |
|
||||
| [@padloc/app](packages/app) | Web-based UI components |
|
||||
| [@padloc/server](packages/server) | The Backend Server |
|
||||
| [@padloc/pwa](packages/pwa) | The Web Client, a [Progressive Web App](https://developers.google.com/web/progressive-web-apps) built on top of the `@padloc/app` package |
|
||||
| [@padloc/locale](packages/locale) | Package containing translations and other localization-related things |
|
||||
| [@padloc/electron](packages/electron) | The Desktop App, built with Electron |
|
||||
| [@padloc/cordova](packages/cordova) | Cordova project for building iOS and Android app. |
|
||||
| [@padloc/tauri](packages/tauri) | Cross-platform native app builder for Padloc, powered by [Tauri](https://github.com/tauri-apps/tauri) |
|
||||
| [@padloc/extension](packages/extension) | Padloc browser extension |
|
||||
| Package Name | Description |
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| [@padloc/core](packages/core) | Core Logic |
|
||||
| [@padloc/app](packages/app) | Web-based UI components |
|
||||
| [@padloc/server](packages/server) | The Backend Server |
|
||||
| [@padloc/pwa](packages/pwa) | The Web Client, a [Progressive Web App](https://developers.google.com/web/progressive-web-apps). |
|
||||
| [@padloc/locale](packages/locale) | Package containing translations and other localization-related things |
|
||||
| [@padloc/electron](packages/electron) | The Desktop App, built with Electron |
|
||||
| [@padloc/cordova](packages/cordova) | Cordova project for building iOS and Android app. |
|
||||
| [@padloc/tauri](packages/tauri) | Cross-platform native app, powered by [Tauri](https://github.com/tauri-apps/tauri) |
|
||||
| [@padloc/extension](packages/extension) | Padloc browser extension |
|
||||
|
||||
## How to use
|
||||
|
||||
As you can see in the [About](#about) section, there are lots of different components to play with! But at a minimum, in
|
||||
order to set up and use your own instance of Padloc you'll need to install and configure the [Server](packages/server)
|
||||
and [Web Client](packages/pwa). In practice, there a few different ways to do this, but if you just want to install and
|
||||
test Padloc locally, doing so is really quite easy:
|
||||
As you can see in the [About](#about) section, there are lots of different
|
||||
components to play with! But at a minimum, in order to set up and use your own
|
||||
instance of Padloc you'll need to install and configure the
|
||||
[Server](packages/server) and [Web Client](packages/pwa). In practice, there a
|
||||
few different ways to do this, but if you just want to install and test Padloc
|
||||
locally, doing so is really quite easy:
|
||||
|
||||
```sh
|
||||
git clone git@github.com:padloc/padloc.git
|
||||
|
@ -36,8 +38,9 @@ npm start
|
|||
|
||||
The web client is now available at `http://localhost:8080`!
|
||||
|
||||
In-depth guides on how to host your own "productive" version of Padloc and how to build and distribute your own versions
|
||||
of the desktop and mobile apps are coming soon!
|
||||
In-depth guides on how to host your own "productive" version of Padloc and how
|
||||
to build and distribute your own versions of the desktop and mobile apps are
|
||||
coming soon!
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -49,16 +52,20 @@ If you want to **report a bug or have a feature request**, please
|
|||
If you **have question, feedback or would just like to chat**, head over to the
|
||||
[discussions](https://github.com/padloc/padloc/discussions) section.
|
||||
|
||||
If you want to **contribute to Padloc directly** by implementing a new feature or fixing an existing issue, feel free to
|
||||
[create a pull request](https://github.com/padloc/padloc/pulls)! However if you plan to work on anything non-trivial,
|
||||
please do talk to us first, either by commenting on an existing issue, creating a new issue or by pinging us in the
|
||||
If you want to **contribute to Padloc directly** by implementing a new feature
|
||||
or fixing an existing issue, feel free to
|
||||
[create a pull request](https://github.com/padloc/padloc/pulls)! However if you
|
||||
plan to work on anything non-trivial, please do talk to us first, either by
|
||||
commenting on an existing issue, creating a new issue or by pinging us in the
|
||||
dissusions section!
|
||||
|
||||
To learn how to get started working on Padloc, refer to the [Development](#development) section of the readme.
|
||||
To learn how to get started working on Padloc, refer to the
|
||||
[Development](#development) section of the readme.
|
||||
|
||||
## Security
|
||||
|
||||
For a security design overview, check out the [security whitepaper](security.md).
|
||||
For a security design overview, check out the
|
||||
[security whitepaper](security.md).
|
||||
|
||||
## Development
|
||||
|
||||
|
@ -82,23 +89,27 @@ To start "dev mode", simply run
|
|||
npm run dev
|
||||
```
|
||||
|
||||
from the root of the project. This will start the backend server (by default listening on port `3000`), as well as the
|
||||
PWA (available on `http://localhost:8080`) by default.
|
||||
from the root of the project. This will start the backend server (by default
|
||||
listening on port `3000`), as well as the PWA (available on
|
||||
`http://localhost:8080`) by default.
|
||||
|
||||
The server and PWA port can be changed vie the `PL_TRANSPORT_HTTP_PORT` and `PL_PWA_PORT` environvent variables,
|
||||
respectively. For more configuration options, check out the **Conguration** section of the
|
||||
The server and PWA port can be changed vie the `PL_TRANSPORT_HTTP_PORT` and
|
||||
`PL_PWA_PORT` environvent variables, respectively. For more configuration
|
||||
options, check out the **Conguration** section of the
|
||||
[server](packages/server#configuration) and [pwa](packages/pwa#configuration).
|
||||
|
||||
### Formatting
|
||||
|
||||
This project is formatted with [Prettier](https://prettier.io/). To re-format all files using our
|
||||
[.prettierrc.json](.prettierrc.json) specification, run the following from the root of the project.
|
||||
This project is formatted with [Prettier](https://prettier.io/). To re-format
|
||||
all files using our [.prettierrc.json](.prettierrc.json) specification, run the
|
||||
following from the root of the project.
|
||||
|
||||
```sh
|
||||
npm run format
|
||||
```
|
||||
|
||||
To simply check whether everything is formatted correctly, you can use the following command:
|
||||
To simply check whether everything is formatted correctly, you can use the
|
||||
following command:
|
||||
|
||||
```sh
|
||||
npm run format:check
|
||||
|
@ -126,8 +137,9 @@ npm run test:e2e:dev
|
|||
|
||||
### Adding / removing dependencies
|
||||
|
||||
Since this is a monorepo consisting of multiple packages, adding/removing to/from a single package can be less than
|
||||
straightforward. The following commands are meant to make this easier.
|
||||
Since this is a monorepo consisting of multiple packages, adding/removing
|
||||
to/from a single package can be less than straightforward. The following
|
||||
commands are meant to make this easier.
|
||||
|
||||
To add a dependency to a package, run:
|
||||
|
||||
|
@ -141,22 +153,25 @@ And to remove one:
|
|||
scope=[package_name] npm run remove [dependency]
|
||||
```
|
||||
|
||||
For example, here is how you would add `typescript` to the `@padloc/server` package:
|
||||
For example, here is how you would add `typescript` to the `@padloc/server`
|
||||
package:
|
||||
|
||||
```sh
|
||||
scope=server npm run add typescript
|
||||
```
|
||||
|
||||
**Note**: We're trying to keep the number and size of third-party dependencies to a minumum, so before you add a
|
||||
dependency, please think twice if it is really needed! Pull requests with unnecessary dependencies will very likely be
|
||||
**Note**: We're trying to keep the number and size of third-party dependencies
|
||||
to a minumum, so before you add a dependency, please think twice if it is really
|
||||
needed! Pull requests with unnecessary dependencies will very likely be
|
||||
rejected.
|
||||
|
||||
### Updating The Version
|
||||
|
||||
The Padloc project consists of many different subpackages. To simplify versioning, we use a global version for all them.
|
||||
This means that when releasing a new version, the version of all subpackages needs to be updated, regardless of whether
|
||||
there have been changes in them or not. To update the global version accross the project, you can use the following
|
||||
command:
|
||||
The Padloc project consists of many different subpackages. To simplify
|
||||
versioning, we use a global version for all them. This means that when releasing
|
||||
a new version, the version of all subpackages needs to be updated, regardless of
|
||||
whether there have been changes in them or not. To update the global version
|
||||
accross the project, you can use the following command:
|
||||
|
||||
```sh
|
||||
npm run version [semver_version]
|
||||
|
@ -164,15 +179,20 @@ npm run version [semver_version]
|
|||
|
||||
### Deployment / Publishing
|
||||
|
||||
Padloc has a lot of different components that all need to be built/released/published in different ways. To manage this
|
||||
complexitiy, we have compiled all deployment steps for all components in a single Github Workflow. To release a new
|
||||
version, simply:
|
||||
Padloc has a lot of different components that all need to be
|
||||
built/released/published in different ways. To manage this complexitiy, we have
|
||||
compiled all deployment steps for all components in a single Github Workflow. To
|
||||
release a new version, simply:
|
||||
|
||||
1. [Update project version](#updating-the-version)
|
||||
2. Commit and push.
|
||||
3. Run the [`Publish Release`](https://github.com/padloc/padloc/actions?workflow=Publish+Release) action.
|
||||
3. Run the
|
||||
[`Publish Release`](https://github.com/padloc/padloc/actions?workflow=Publish+Release)
|
||||
action.
|
||||
|
||||
## Licensing
|
||||
|
||||
This software is published under the [GNU Affero General Public License](LICENSE). If you wish to acquire a commercial
|
||||
license, please contact us as [sales@padloc.app](mailto:sales@padloc.app?subject=Padloc%20Commercial%20License).
|
||||
This software is published under the
|
||||
[GNU Affero General Public License](LICENSE). If you wish to acquire a
|
||||
commercial license, please contact us as
|
||||
[sales@padloc.app](mailto:sales@padloc.app?subject=Padloc%20Commercial%20License).
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
# Padloc Localization Package
|
||||
|
||||
This package contains translations, word lists and various localization tools for the Padloc app.
|
||||
This package contains translations, word lists and various localization tools
|
||||
for the Padloc app.
|
||||
|
||||
## How To Contribute
|
||||
|
||||
### Translations
|
||||
|
||||
One of the easiest ways to contribute to this project is to help create or improve translations in your
|
||||
language. Translations are stored as simple [JSON](https://www.json.org/) files in the following format:
|
||||
One of the easiest ways to contribute to this project is to help create or
|
||||
improve translations in your language. Translations are stored as simple
|
||||
[JSON](https://www.json.org/) files in the following format:
|
||||
|
||||
```json
|
||||
[
|
||||
|
@ -22,16 +24,18 @@ language. Translations are stored as simple [JSON](https://www.json.org/) files
|
|||
]
|
||||
```
|
||||
|
||||
To add or update a translation for a given text, simply locate the translation file for your language
|
||||
in the [translations directory](packages/locale/res/translations/), find the text you want to translate
|
||||
and insert your translation below. If no translation file for you language
|
||||
exists yet, you can start from scratch, using [this empty translations
|
||||
file](packages/locale/res/translations/_template.json). Simply copy it and name
|
||||
it
|
||||
`xx.json`, replacing "xx" with the appropriate lowercase [country
|
||||
code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements).
|
||||
To add or update a translation for a given text, simply locate the translation
|
||||
file for your language in the
|
||||
[translations directory](packages/locale/res/translations/), find the text you
|
||||
want to translate and insert your translation below. If no translation file for
|
||||
you language exists yet, you can start from scratch, using
|
||||
[this empty translations file](packages/locale/res/translations/_template.json).
|
||||
Simply copy it and name it `xx.json`, replacing "xx" with the appropriate
|
||||
lowercase
|
||||
[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements).
|
||||
|
||||
### Word Lists
|
||||
|
||||
Word lists are used to generate random passphrases from a list of commonly used words from a given language.
|
||||
You can find all existing word lists [here](packages/locale/res/wordlists/).
|
||||
Word lists are used to generate random passphrases from a list of commonly used
|
||||
words from a given language. You can find all existing word lists
|
||||
[here](packages/locale/res/wordlists/).
|
||||
|
|
|
@ -4,8 +4,8 @@ This package contains the Padloc backend server component.
|
|||
|
||||
## How to use
|
||||
|
||||
Currently the `@padloc/server` package is meant to run from within a copy of the [Padloc monorepo](../../README.md). A
|
||||
standalone npm package is coming soon!
|
||||
Currently the `@padloc/server` package is meant to be run from within the
|
||||
[Padloc monorepo](../../README.md). A standalone npm package is coming soon!
|
||||
|
||||
First, clone and install the monorepo:
|
||||
|
||||
|
@ -28,45 +28,54 @@ cd packages/server
|
|||
npm start
|
||||
```
|
||||
|
||||
By default, the server will listen on port `3000`. To can set a different port via the `PL_TRANSPORT_HTTP_PORT`
|
||||
environment variable:
|
||||
By default, the server will listen on port `3000`. To can set a different port
|
||||
via the `PL_TRANSPORT_HTTP_PORT` environment variable:
|
||||
|
||||
```sh
|
||||
PL_TRANSPORT_HTTP_PORT=3001 npm start
|
||||
```
|
||||
|
||||
For more configuration options, please consult the [Configuration](#configuration) section of this readme.
|
||||
For more configuration options, please consult the
|
||||
[Configuration](#configuration) section of this readme.
|
||||
|
||||
## Configuration
|
||||
|
||||
Padloc comes with a lot of configuration options, most of which deal with selecting and configuring backends for certain
|
||||
aspects of the software.
|
||||
Padloc comes with a lot of configuration options, most of which deal with
|
||||
selecting and configuring backends for certain aspects of the software.
|
||||
|
||||
All configuration options for the `@padloc/server` package are defined in the [src/config](src/config.ts) moule, and
|
||||
while we'll be discussing the most important ones here, looking at the source can be a great way to understand how
|
||||
configuration options are structured and parsed, and to familiarise yourself with some of the more advanced
|
||||
configuration options.
|
||||
All configuration options for the `@padloc/server` package are defined in the
|
||||
[src/config](src/config.ts) moule, and while we'll be discussing the most
|
||||
important ones here, looking at the source can be a great way to understand how
|
||||
configuration options are structured and parsed, and to familiarise yourself
|
||||
with some of the more advanced configuration options.
|
||||
|
||||
Most of Padloc's configuration happens through environment variables, and because there are a lot of options and
|
||||
therefore a lot of different variables, we've come up with a simple naming scheme that's based on the hierarchical
|
||||
nature of Padloc's configuration. This means that most of the time, you'll be able to guess the environment variable
|
||||
name simply by looking at the structure defined in [src/config](src/config.ts).
|
||||
Most of Padloc's configuration happens through environment variables, and
|
||||
because there are a lot of options and therefore a lot of different variables,
|
||||
we've come up with a simple naming scheme that's based on the hierarchical
|
||||
nature of Padloc's configuration. This means that most of the time, you'll be
|
||||
able to guess the environment variable name simply by looking at the structure
|
||||
defined in [src/config](src/config.ts).
|
||||
|
||||
The generall pattern is that in order to configure a certain aspect, you'll first choose which backend you want to use.
|
||||
Then, you'll provide the configuration options required by that specific backend by setting the corresponding
|
||||
environment variables, which are name-spaced with the backend's name.
|
||||
The generall pattern is that in order to configure a certain aspect, you'll
|
||||
first choose which backend you want to use. Then, you'll provide the
|
||||
configuration options required by that specific backend by setting the
|
||||
corresponding environment variables, which are name-spaced with the backend's
|
||||
name.
|
||||
|
||||
For example, you can choose which backend to use for data storage by setting the `PL_DATA_BACKEND` variable. By default,
|
||||
Padloc uses LevelDB for data storage on the server side. To use PostgresSQL instead, simply set the `PL_DATA_BACKEND`
|
||||
For example, you can choose which backend to use for data storage by setting the
|
||||
`PL_DATA_BACKEND` variable. By default, Padloc uses LevelDB for data storage on
|
||||
the server side. To use PostgreSQL instead, simply set the `PL_DATA_BACKEND`
|
||||
variable to `postgres`.
|
||||
|
||||
```sh
|
||||
PL_DATA_BACKEND=postgres
|
||||
```
|
||||
|
||||
Naturally, Padloc now needs to know where to reach the Postgres server, so you'll need to set the corresponding
|
||||
environment variables. Our naming scheme dictates that all postgres-related configuration options are prefixed with
|
||||
`PL_DATA_POSTGRES_*`. An exampe for a full postgres configuration might look as follows:
|
||||
Naturally, Padloc now needs to know where to reach the Postgres server, so
|
||||
you'll need to set the corresponding environment variables. Our naming scheme
|
||||
dictates that all postgres-related configuration options are prefixed with
|
||||
`PL_DATA_POSTGRES_*`. An exampe for a full postgres configuration might look as
|
||||
follows:
|
||||
|
||||
```sh
|
||||
PL_DATA_BACKEND=postgres
|
||||
|
@ -77,30 +86,35 @@ PL_DATA_POSTGRES_PASSWORD=somepassword
|
|||
PL_DATA_POSTGRES_DATABASE=padloc
|
||||
```
|
||||
|
||||
Padloc is designed to be extremely modular, so you'll find that most aspects of the software can be configured to use
|
||||
different backends. And if your technology of choice isn't supported, it's usually fairly straightforward to implement
|
||||
the required backend. [Pull requests welcome](../../README.md#contributing)!
|
||||
Padloc is designed to be extremely modular, so you'll find that most aspects of
|
||||
the software can be configured to use different backends. And if your technology
|
||||
of choice isn't supported, it's usually fairly straightforward to implement the
|
||||
required backend. [Pull requests welcome](../../README.md#contributing)!
|
||||
|
||||
### Setting Environment Variables
|
||||
|
||||
Environment variables can be set either the traditional way (consult the documentation of your operating system) or via
|
||||
a [`.env`](https://www.npmjs.com/package/dotenv) file. By default, Padloc will look for a file named `.env` in the
|
||||
current working directory, but you can also specifiy the path to a different file using the `--env` flag:
|
||||
Environment variables can be set either the traditional way (consult the
|
||||
documentation of your operating system) or via a
|
||||
[`.env`](https://www.npmjs.com/package/dotenv) file. By default, Padloc will
|
||||
look for a file named `.env` in the current working directory, but you can also
|
||||
specifiy the path to a different file using the `--env` flag:
|
||||
|
||||
```sh
|
||||
npm start -- --env=/path/to/env/file/.env
|
||||
```
|
||||
|
||||
Note that by default, environment variables set through other means take preference over the ones defined in your `.env`
|
||||
file. If you want your `.env` file to override any variables set elsewhere, use the `--env-override` flag:
|
||||
Note that by default, environment variables set through other means take
|
||||
preference over the ones defined in your `.env` file. If you want your `.env`
|
||||
file to override any variables set elsewhere, use the `--env-override` flag:
|
||||
|
||||
```sh
|
||||
npm start -- --env=/path/to/env/file/.env --env-override
|
||||
```
|
||||
|
||||
For your convenience, we've compiled **all** available environment variables in a
|
||||
[`sample .env file`](resources/example.env). Simply copy the file to wherever you want to keep it and the uncomment and
|
||||
edit any options you want to set (more info about the most important configuration options below).
|
||||
For your convenience, we've compiled **all** available environment variables in
|
||||
a [`sample .env file`](resources/example.env). Simply copy the file to wherever
|
||||
you want to keep it and the uncomment and edit any options you want to set (more
|
||||
info about the most important configuration options below).
|
||||
|
||||
### Data Transport
|
||||
|
||||
|
@ -132,6 +146,7 @@ TBD
|
|||
|
||||
## Licensing
|
||||
|
||||
This software is published under the [GNU Affero General Public License](../../LICENSE). If you wish to acquire a
|
||||
This software is published under the
|
||||
[GNU Affero General Public License](../../LICENSE). If you wish to acquire a
|
||||
commercial license, please contact us as
|
||||
[sales@padloc.app](mailto:sales@padloc.app?subject=Padloc%20Commercial%20License).
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
# @padloc/tauri (experimental)
|
||||
|
||||
Cross-platform native app builder for Padloc, powered by [Tauri](https://github.com/tauri-apps/tauri).
|
||||
Cross-platform native app builder for Padloc, powered by
|
||||
[Tauri](https://github.com/tauri-apps/tauri).
|
||||
|
||||
## How To Use
|
||||
|
||||
1. Follow the steps described in the [Getting
|
||||
Started](https://github.com/padloc/padloc/blob/master/README.md#getting-started)
|
||||
1. Follow the steps described in the
|
||||
[Getting Started](https://github.com/padloc/padloc/blob/master/README.md#getting-started)
|
||||
section of repo readme.
|
||||
|
||||
2. Follow Tauri's [setup guide](https://tauri.studio/docs/getting-started/intro/#setting-up-your-environment) for your platform.
|
||||
2. Follow Tauri's
|
||||
[setup guide](https://tauri.studio/docs/getting-started/intro/#setting-up-your-environment)
|
||||
for your platform.
|
||||
|
||||
3. Build the app:
|
||||
|
||||
|
@ -17,8 +20,8 @@ Cross-platform native app builder for Padloc, powered by [Tauri](https://github.
|
|||
npm run build
|
||||
```
|
||||
|
||||
Don't forget to set the server url [configuration
|
||||
variable](https://github.com/padloc/padloc/blob/master/README.md#configuration).
|
||||
Don't forget to set the server url
|
||||
[configuration variable](https://github.com/padloc/padloc/blob/master/README.md#configuration).
|
||||
For example, if you want the app to connect to the official Padloc server:
|
||||
|
||||
```sh
|
||||
|
@ -29,12 +32,21 @@ Cross-platform native app builder for Padloc, powered by [Tauri](https://github.
|
|||
|
||||
Initial tests look very promising. Some things that still need figuring out.
|
||||
|
||||
- [ ] **Persistent Storage**: Using IndexedDB doesn't work here for various reasons. Best option is
|
||||
probably writing a simple storage backend using Tauri's [file system api](https://tauri.studio/docs/api/js#file-system).
|
||||
- [ ] **Copy & Paste**: Doesn't work out of the box. Figure out steps to make it work.
|
||||
- [ ] **Auto-updating**: Must-have feature for desktop apps at least those not distributed through app stores or package managers. Not available in Tauri yet, but apparently on the roadmap.
|
||||
- [ ] **Persistent Storage**: Using IndexedDB doesn't work here for various
|
||||
reasons. Best option is probably writing a simple storage backend using
|
||||
Tauri's [file system api](https://tauri.studio/docs/api/js#file-system).
|
||||
- [ ] **Copy & Paste**: Doesn't work out of the box. Figure out steps to make
|
||||
it work.
|
||||
- [ ] **Auto-updating**: Must-have feature for desktop apps at least those not
|
||||
distributed through app stores or package managers. Not available in
|
||||
Tauri yet, but apparently on the roadmap.
|
||||
- [ ] **Code-signing**: Also on Tauri's roadmap, but not available yet
|
||||
- [ ] **Run without the embedded web server**: Would be the safer choice security-wise but doesn't seem to work as-is. Need to figure out what changes are needed to make it work.
|
||||
- [ ] **Mobile**: Waiting for Tauri to support Android and iOS builds, which could potentially replace Cordova.
|
||||
- [ ] **Biometric Authentication**: This is a must-have on mobile but it would be nice to have it on desktop as well
|
||||
- [ ] **Secure Enclave / Key Store**: Along with biometric authentication, this is a requirement for biometric unlock.
|
||||
- [ ] **Run without the embedded web server**: Would be the safer choice
|
||||
security-wise but doesn't seem to work as-is. Need to figure out what
|
||||
changes are needed to make it work.
|
||||
- [ ] **Mobile**: Waiting for Tauri to support Android and iOS builds, which
|
||||
could potentially replace Cordova.
|
||||
- [ ] **Biometric Authentication**: This is a must-have on mobile but it would
|
||||
be nice to have it on desktop as well
|
||||
- [ ] **Secure Enclave / Key Store**: Along with biometric authentication,
|
||||
this is a requirement for biometric unlock.
|
||||
|
|
389
security.md
389
security.md
|
@ -17,26 +17,26 @@ the technical knowledge to do so, which brings us to...
|
|||
|
||||
### Transparency
|
||||
|
||||
It is a widely know fact among security experts that [Security through
|
||||
Obscurity](https://en.wikipedia.org/wiki/security_through_obscurity) is not
|
||||
only ineffective, but can in fact be harmful if used to cover up otherwise
|
||||
sloppy security practices. We believe that full transparency is not only the
|
||||
best foundation for trust, but also allows us and other independent reviewers
|
||||
to discover and fix any potential security flaws and efficiently as quickly as
|
||||
possible.
|
||||
It is a widely know fact among security experts that
|
||||
[Security through Obscurity](https://en.wikipedia.org/wiki/security_through_obscurity)
|
||||
is not only ineffective, but can in fact be harmful if used to cover up
|
||||
otherwise sloppy security practices. We believe that full transparency is not
|
||||
only the best foundation for trust, but also allows us and other independent
|
||||
reviewers to discover and fix any potential security flaws and efficiently as
|
||||
quickly as possible.
|
||||
|
||||
### No Trust Required
|
||||
|
||||
While Padlocs open source nature is helpful in uncovering unintended
|
||||
vulnerabilities in the source code, it is, by itself, insufficient for
|
||||
verifying that the code actually deployed in production is not altered in a way
|
||||
that may compromise the security of the application either intentionally or
|
||||
vulnerabilities in the source code, it is, by itself, insufficient for verifying
|
||||
that the code actually deployed in production is not altered in a way that may
|
||||
compromise the security of the application either intentionally or
|
||||
unintentionally. This is why we take additional steps to make sure that some
|
||||
parts of the architecture can in fact be verified in production, while others
|
||||
do not need to be verified by design (see [Possible Attack-Vectors And
|
||||
Mitigations](#possible-attach-vectors-and-mitigations)). This means that unlike
|
||||
other products, Padloc does not require explicit trust between the end user
|
||||
and the host.
|
||||
parts of the architecture can in fact be verified in production, while others do
|
||||
not need to be verified by design (see
|
||||
[Possible Attack-Vectors And Mitigations](#possible-attach-vectors-and-mitigations)).
|
||||
This means that unlike other products, Padloc does not require explicit trust
|
||||
between the end user and the host.
|
||||
|
||||
## Encryption
|
||||
|
||||
|
@ -46,18 +46,19 @@ Padloc utilizes three basic encryption schemes.
|
|||
### Simple Symmetric Encryption
|
||||
|
||||
This is the most basic encryption scheme used in Padloc. Simple encryption
|
||||
employs a symmetric cipher to encrypt the provided data with
|
||||
a randomly generated key. The encrypted data, along with the encryption
|
||||
parameters needed for decryption, is stored in a container object, which
|
||||
can then be stored or transmitted securely. Padloc currently uses the AES
|
||||
cipher in GCM mode, but other options may be added in the future.
|
||||
employs a symmetric cipher to encrypt the provided data with a randomly
|
||||
generated key. The encrypted data, along with the encryption parameters needed
|
||||
for decryption, is stored in a container object, which can then be stored or
|
||||
transmitted securely. Padloc currently uses the AES cipher in GCM mode, but
|
||||
other options may be added in the future.
|
||||
|
||||
#### Encryption
|
||||
|
||||
1. Choose a random encryption key `k`
|
||||
2. Choose a random initialization vector `iv` and additional data `a` (for
|
||||
authenticated encryption modes)
|
||||
3. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain text `p`
|
||||
3. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain
|
||||
text `p`
|
||||
4. Store `c`, `iv` and `a` in the container `C`
|
||||
|
||||
```
|
||||
|
@ -82,9 +83,9 @@ cipher in GCM mode, but other options may be added in the future.
|
|||
|
||||
### Password-Based Encryption
|
||||
|
||||
In the password-based encryption scheme (based on the [PBES2
|
||||
standard](https://tools.ietf.org/html/rfc2898#section-6.2)) an encryption key
|
||||
is derived from a user password using the
|
||||
In the password-based encryption scheme (based on the
|
||||
[PBES2 standard](https://tools.ietf.org/html/rfc2898#section-6.2)) an encryption
|
||||
key is derived from a user password using the
|
||||
[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) key derivation function.
|
||||
|
||||
#### Encryption
|
||||
|
@ -94,7 +95,8 @@ is derived from a user password using the
|
|||
3. Generate `k = PBDKF2(p, s, i)`
|
||||
4. Choose a random initialization vector `iv` and additional data `a` (for
|
||||
authenticated encryption modes)
|
||||
5. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain text `p`
|
||||
5. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain
|
||||
text `p`
|
||||
6. Store `s`, `i`, `c`, `iv` and `a` in the container `C`
|
||||
|
||||
```
|
||||
|
@ -128,25 +130,28 @@ is derived from a user password using the
|
|||
|
||||
### Shared-Key Encryption
|
||||
|
||||
Shared-key encryption is used to securely share sensitive data between
|
||||
a number of independent accessors without the need for them to share a
|
||||
common password. This encryption scheme is loosely based on the [JSON Web
|
||||
Encryption](https://tools.ietf.org/html/rfc7516) specification where a shared
|
||||
symmetric encryption key is individually encrypted with each accessors public
|
||||
key and stored alongside the encrypted data. Accessors can then access the data
|
||||
by using their private key to decrypt the AES encryption key which is in turn
|
||||
used to decrypt the original data.
|
||||
Shared-key encryption is used to securely share sensitive data between a number
|
||||
of independent accessors without the need for them to share a common password.
|
||||
This encryption scheme is loosely based on the
|
||||
[JSON Web Encryption](https://tools.ietf.org/html/rfc7516) specification where a
|
||||
shared symmetric encryption key is individually encrypted with each accessors
|
||||
public key and stored alongside the encrypted data. Accessors can then access
|
||||
the data by using their private key to decrypt the AES encryption key which is
|
||||
in turn used to decrypt the original data.
|
||||
|
||||
#### Encryption
|
||||
|
||||
1. Generate a random encryption key `k`
|
||||
2. Choose a random initialization vector `iv` and additional data `a` (for
|
||||
authenticated encryption modes)
|
||||
3. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain text `p`
|
||||
4. Let `[A_1, A_2, ..., A_n], A_n = { id_n, pub_n }` be a number of desired accessors
|
||||
where `pub_n` is the accessors public key and `id_n` a unique identifier.
|
||||
3. Generate the encrypted data `c = AES_encrypt(k, p, iv, a)` from the plain
|
||||
text `p`
|
||||
4. Let `[A_1, A_2, ..., A_n], A_n = { id_n, pub_n }` be a number of desired
|
||||
accessors where `pub_n` is the accessors public key and `id_n` a unique
|
||||
identifier.
|
||||
5. For each accessor, generate `K_n = RSA_encrypt(pub_n, k)`
|
||||
6. Store `c`, `iv`, `a`, and `K = [{ id_1, K_1}, ..., {id_n, K_n}]` in container `C`
|
||||
6. Store `c`, `iv`, `a`, and `K = [{ id_1, K_1}, ..., {id_n, K_n}]` in container
|
||||
`C`
|
||||
|
||||
```
|
||||
┏━━━━━━━━━━━━━━┓ ┌───────────────────────────────────────────────────────────┐
|
||||
|
@ -216,22 +221,22 @@ The **Account** object represents an individual Padloc user and is central to
|
|||
Padlocs encryption and authentication mechanisms. Each **Account** holds the
|
||||
following information:
|
||||
|
||||
- The user's **email address** is not only used as a communication channel but,
|
||||
more importantly, serves as a unique, human-verifiable identifier for each
|
||||
Padloc user.
|
||||
- The user's **email address** is not only used as a communication channel
|
||||
but, more importantly, serves as a unique, human-verifiable identifier for
|
||||
each Padloc user.
|
||||
- A RSA **private key** and **public key** pair is used in places where a user
|
||||
needs to be granted access to data protected via the [Shared-Key Encryption
|
||||
Scheme](#shared-key-encryption).
|
||||
needs to be granted access to data protected via the
|
||||
[Shared-Key Encryption Scheme](#shared-key-encryption).
|
||||
- A HMAC key used for signing and verifing organization details (see
|
||||
[Organizations And Shared Vaults / Adding Members](#adding-members)
|
||||
- A unique, immutable id
|
||||
- A (display) name
|
||||
|
||||
The Accounts **private key** and **organization signing key** are considered
|
||||
secret and should only ever be accessible to the Account owner themselves.
|
||||
They are therefore encrypted at rest using the [Password-Based Encryption
|
||||
Scheme](#password-based-encryption) with the users [**Master Password**](#the-master-password)
|
||||
serving as the secret passphrase.
|
||||
secret and should only ever be accessible to the Account owner themselves. They
|
||||
are therefore encrypted at rest using the
|
||||
[Password-Based Encryption Scheme](#password-based-encryption) with the users
|
||||
[**Master Password**](#the-master-password) serving as the secret passphrase.
|
||||
|
||||
```
|
||||
┏━━━━━━━━━━━━━━━━━━━━━┓
|
||||
|
@ -258,13 +263,13 @@ serving as the secret passphrase.
|
|||
|
||||
A password managers core functionality is the secure storage of sensitive data
|
||||
like passwords, credit card details and or any other kind or data a user may
|
||||
want to protect from prying eyes. In Padloc, this data is stored within so-called
|
||||
**Vaults**.
|
||||
want to protect from prying eyes. In Padloc, this data is stored within
|
||||
so-called **Vaults**.
|
||||
|
||||
A Vault is basically a container object that employs the [Shared-Key
|
||||
Encryption Scheme](#shared-key-encryption) to encrypt and store sensitive data
|
||||
in a way that makes it accessible to only a number of specific users, represented
|
||||
by their corresponding **Account** objects.
|
||||
A Vault is basically a container object that employs the
|
||||
[Shared-Key Encryption Scheme](#shared-key-encryption) to encrypt and store
|
||||
sensitive data in a way that makes it accessible to only a number of specific
|
||||
users, represented by their corresponding **Account** objects.
|
||||
|
||||
```
|
||||
┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓
|
||||
|
@ -294,9 +299,9 @@ verification.
|
|||
### Vault Access Management
|
||||
|
||||
The previous sections describe how Vault data can be shared securely between
|
||||
multiple known accounts. An additional challenge lies in deciding who shall
|
||||
have access to a given vault as well as obtaining and verifying each accessors
|
||||
public key before encryption.
|
||||
multiple known accounts. An additional challenge lies in deciding who shall have
|
||||
access to a given vault as well as obtaining and verifying each accessors public
|
||||
key before encryption.
|
||||
|
||||
The organisation structure depicted below determines which member shall have
|
||||
access to a given vault. Members can either be assigned to a **Vault** directly
|
||||
|
@ -324,13 +329,14 @@ or indirectly via a **Group**.
|
|||
└──────────────┘
|
||||
```
|
||||
|
||||
Every time a **Vault** participant encrypts the vault data, they perform
|
||||
the following steps:
|
||||
Every time a **Vault** participant encrypts the vault data, they perform the
|
||||
following steps:
|
||||
|
||||
1. Determine accessors based on organization structure.
|
||||
2. Verify each accessor's identity and public key (see [Verifying
|
||||
Members](#verifying-members))
|
||||
3. Encrypt the data using the steps outlined in [Shared-Key Encryption](#shared-key-encryption)
|
||||
2. Verify each accessor's identity and public key (see
|
||||
[Verifying Members](#verifying-members))
|
||||
3. Encrypt the data using the steps outlined in
|
||||
[Shared-Key Encryption](#shared-key-encryption)
|
||||
|
||||
Each participating member can now access the Vault data using their own private
|
||||
key.
|
||||
|
@ -345,17 +351,17 @@ information:
|
|||
- The organization **name** is chosen by the organization owner and is mainly
|
||||
used for display purposes
|
||||
- A RSA **public key** and **private key** pair that is used to sign and
|
||||
verify public keys and identifying information of its members. See [Signing
|
||||
Member Information](#adding-members) and [Verifying
|
||||
Members](#verifying-members) for details.
|
||||
verify public keys and identifying information of its members. See
|
||||
[Signing Member Information](#adding-members) and
|
||||
[Verifying Members](#verifying-members) for details.
|
||||
- An AES key (in the following called "**invites key**") used to encrypt the
|
||||
invite verification code during [key
|
||||
exchange](#trustless-server-mediated-key-exchange)
|
||||
invite verification code during
|
||||
[key exchange](#trustless-server-mediated-key-exchange)
|
||||
|
||||
The organization's **private key** and **invites key** are considered secret
|
||||
and need therefore be encrypted at rest. For this, the organization acts as a
|
||||
[Shared Crypto Container](#shared-key-encryption) with the [organization
|
||||
owners](#owner) acting as accessors.
|
||||
The organization's **private key** and **invites key** are considered secret and
|
||||
need therefore be encrypted at rest. For this, the organization acts as a
|
||||
[Shared Crypto Container](#shared-key-encryption) with the
|
||||
[organization owners](#owner) acting as accessors.
|
||||
|
||||
```
|
||||
┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━┓
|
||||
|
@ -378,18 +384,19 @@ As with all cryptographic schemes that involve public-key encryption, a major
|
|||
challenge when dealing with shared vaults is securely exchanging and verifying
|
||||
the public keys and associated identities of all involved parties. This
|
||||
undertaking is complicated further by the fact that, although all communication
|
||||
and data transfer is generally mediated by a central server, Padlocs [Zero-Trust
|
||||
Principle](#no-trust-required) requires that this server (or any party
|
||||
potentially listening in on the connection) is never in the position to
|
||||
and data transfer is generally mediated by a central server, Padlocs
|
||||
[Zero-Trust Principle](#no-trust-required) requires that this server (or any
|
||||
party potentially listening in on the connection) is never in the position to
|
||||
directly access any sensitive data or trick a participant into granting them
|
||||
access either directly or indirectly.
|
||||
|
||||
Instead of exchanging keys between all organization members directly, Padloc
|
||||
uses a simple verification chain where the public keys and identfying
|
||||
information of all members are signed and verified with a dedicated RSA key
|
||||
pair owned by the organization (see [Metadata and Cryptographic
|
||||
Keys](#metadata-and-cryptographic-keys)). The corresponding public key must in
|
||||
turn be signed and verified by each member using their individual, dedicated HMAC key.
|
||||
information of all members are signed and verified with a dedicated RSA key pair
|
||||
owned by the organization (see
|
||||
[Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys)). The
|
||||
corresponding public key must in turn be signed and verified by each member
|
||||
using their individual, dedicated HMAC key.
|
||||
|
||||
#### Trustless Server-Mediated Key Exchange
|
||||
|
||||
|
@ -397,22 +404,28 @@ Before a new member can be added to an Organization, a key exchange has to take
|
|||
place between the organization (represented by the organization owner) and the
|
||||
new member. The key exchange is performed as follows:
|
||||
|
||||
1. The **organization owner `O`** chooses a **random passphrase `p`**, a **random salt `s`**
|
||||
and an **iteration count `i`** as well as a random, unique exchange id.
|
||||
2. **`p`**, **`s`** and **`i`** are used to generate the **HMAC key `x = PBKDF2(p, s, i)`**.
|
||||
3. **`O`** signs the **organizations public key `pub_o`** with **`x`**: **`sig_o = HMAC(x, pub_o)`**
|
||||
4. **`O`** sends **`s`**, **`i`**, **`pub_o`** and **`sig_o`** to the server **`S`**, along with the
|
||||
exchange id and the recipients email address.
|
||||
1. The **organization owner `O`** chooses a **random passphrase `p`**, a
|
||||
**random salt `s`** and an **iteration count `i`** as well as a random,
|
||||
unique exchange id.
|
||||
2. **`p`**, **`s`** and **`i`** are used to generate the **HMAC key
|
||||
`x = PBKDF2(p, s, i)`**.
|
||||
3. **`O`** signs the **organizations public key `pub_o`** with **`x`**:
|
||||
**`sig_o = HMAC(x, pub_o)`**
|
||||
4. **`O`** sends **`s`**, **`i`**, **`pub_o`** and **`sig_o`** to the server
|
||||
**`S`**, along with the exchange id and the recipients email address.
|
||||
5. The server stores the received values and sends the invitation link (which
|
||||
includes the exchange id) to **`I`** via email.
|
||||
6. **`I`** uses the exchange id to request **`s`**, **`i`**, **`pub_o`** and **`sig_o`** from **`S`**.
|
||||
7. **`I`** requests **`p`** from **`O`** via a separate (and optimally secure) channel of their
|
||||
choice. This can be in person, via phone or any by other means.
|
||||
6. **`I`** uses the exchange id to request **`s`**, **`i`**, **`pub_o`** and
|
||||
**`sig_o`** from **`S`**.
|
||||
7. **`I`** requests **`p`** from **`O`** via a separate (and optimally secure)
|
||||
channel of their choice. This can be in person, via phone or any by other
|
||||
means.
|
||||
8. **`I`** generates **`x = PBKDF2(p, s, i)`** using the obtained information.
|
||||
9. **`I`** verifies **`pub_o`** using **`x`** and **`sig_o`**.
|
||||
10. Upon successful verification, **`I`** signs their own **public key `pub_i`** using
|
||||
**`x`**: **`sig_i = HMAC(x, pub_i)`**
|
||||
11. **`I`** sends **`pub_i`** and **`sig_i`** to **`S`**, which forwards them to **`O`**.
|
||||
10. Upon successful verification, **`I`** signs their own **public key `pub_i`**
|
||||
using **`x`**: **`sig_i = HMAC(x, pub_i)`**
|
||||
11. **`I`** sends **`pub_i`** and **`sig_i`** to **`S`**, which forwards them to
|
||||
**`O`**.
|
||||
12. **`O`** verifies **`pub_i`** using **`sig_i`** and **`x`**.
|
||||
|
||||
```
|
||||
|
@ -448,31 +461,32 @@ new member. The key exchange is performed as follows:
|
|||
included in the respective signatures to protect these from tempering as
|
||||
well.
|
||||
|
||||
- Since `p` needs to be sufficiently short to be conveniently entered by
|
||||
hand, it can potentially be guessed by eavesdroppers which would allow them
|
||||
to successfully perform a man-in-the-middle attack by injecting their own
|
||||
public key. This is mitigated by using a sufficiently large iteration count `i`
|
||||
and invalidating key exchanges after a certain amount of time.
|
||||
- Since `p` needs to be sufficiently short to be conveniently entered by hand,
|
||||
it can potentially be guessed by eavesdroppers which would allow them to
|
||||
successfully perform a man-in-the-middle attack by injecting their own
|
||||
public key. This is mitigated by using a sufficiently large iteration count
|
||||
`i` and invalidating key exchanges after a certain amount of time.
|
||||
|
||||
- Using a separate, direct communication channel for communicating the secret
|
||||
passphrase not only mitigates the risk of man-in-the-middle attacks but
|
||||
also means that the server `S` does not need to be explicitly trusted.
|
||||
passphrase not only mitigates the risk of man-in-the-middle attacks but also
|
||||
means that the server `S` does not need to be explicitly trusted.
|
||||
Furthermore, the risk of phishing attacks by a third party (including a
|
||||
malicious server admin) is greatly reduced since a direct, personal
|
||||
interaction between the parties is required.
|
||||
|
||||
- Since some time may pass between steps **1.** and **7.**, **`p`** needs to be
|
||||
stored securely for later reference. This is done by encrypting it with a
|
||||
- Since some time may pass between steps **1.** and **7.**, **`p`** needs to
|
||||
be stored securely for later reference. This is done by encrypting it with a
|
||||
dedicated AES "invites key" which is only accessible to organization owners.
|
||||
(See [Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys).
|
||||
|
||||
#### Adding Members
|
||||
|
||||
Once the new member and organization have successfully exchanged public keys,
|
||||
these need to be stored in a way that allows both parties to be verify them later.
|
||||
The invitees public key (along with their identifying information) is signed
|
||||
by the organizations private key (only available to the organization owner) while
|
||||
the organizations public key is signed by the invitees own, dedicated HMAC key.
|
||||
these need to be stored in a way that allows both parties to be verify them
|
||||
later. The invitees public key (along with their identifying information) is
|
||||
signed by the organizations private key (only available to the organization
|
||||
owner) while the organizations public key is signed by the invitees own,
|
||||
dedicated HMAC key.
|
||||
|
||||
```
|
||||
┏━━━━━━━━━━━━━━┓
|
||||
|
@ -544,15 +558,16 @@ A basic organization member has the following privileges.
|
|||
3. Update vault data of assigned vaults where write permissions have been
|
||||
granted explicitly
|
||||
|
||||
All of these privileges are enforced by the server (e.g. a vaults encrypted
|
||||
data will only be provided to a member if they are assigned to that vault)
|
||||
while access to the plain text data stored in vaults is also restricted
|
||||
cryptographically through the encryption mechanism described in [Vaults](#vaults).
|
||||
All of these privileges are enforced by the server (e.g. a vaults encrypted data
|
||||
will only be provided to a member if they are assigned to that vault) while
|
||||
access to the plain text data stored in vaults is also restricted
|
||||
cryptographically through the encryption mechanism described in
|
||||
[Vaults](#vaults).
|
||||
|
||||
##### Admin
|
||||
|
||||
In addition to the privileges granted to basic members, admins also have the following
|
||||
privileges:
|
||||
In addition to the privileges granted to basic members, admins also have the
|
||||
following privileges:
|
||||
|
||||
1. Create and delete Vaults
|
||||
2. Assign vault access to groups and members directly
|
||||
|
@ -568,35 +583,39 @@ owners also have the following privileges:
|
|||
3. Update the organizations public/private key pair
|
||||
|
||||
As described in a [previous section](#adding-members), adding a new member to
|
||||
the organization requires access to the organizations private key. As described in
|
||||
[Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys), this access
|
||||
is restricted cryptographically to organization owners.
|
||||
the organization requires access to the organizations private key. As described
|
||||
in [Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys), this
|
||||
access is restricted cryptographically to organization owners.
|
||||
|
||||
## Authentication And Data Transfer
|
||||
|
||||
Even though all sensitive information in **padloc** is end-to-end encrypted and
|
||||
theoretically secure even in case of an insecure connection or even a
|
||||
compromised server, **padloc** still uses a robust authentication scheme to limit
|
||||
access to user data, ensure payload integrity and enforce user permissions.
|
||||
A variation of the [Secure Remote
|
||||
Password](https://tools.ietf.org/html/rfc2945) protocol is used to authenticate
|
||||
users and establish a secure connection between client and server without
|
||||
exposing the user's master password.
|
||||
compromised server, **padloc** still uses a robust authentication scheme to
|
||||
limit access to user data, ensure payload integrity and enforce user
|
||||
permissions. A variation of the
|
||||
[Secure Remote Password](https://tools.ietf.org/html/rfc2945) protocol is used
|
||||
to authenticate users and establish a secure connection between client and
|
||||
server without exposing the user's master password.
|
||||
|
||||
### User Signup
|
||||
|
||||
Whenever a user creates a Padloc account, the following steps take place:
|
||||
|
||||
1. Let **`u`** and **`p`** be the user's **email address** and **master password**, respectively.
|
||||
1. Let **`u`** and **`p`** be the user's **email address** and **master
|
||||
password**, respectively.
|
||||
2. The **client `C`** sends **`u`** to the server **`S`**.
|
||||
3. The server sends an email **verification code `c`** to the user's email address.
|
||||
3. The server sends an email **verification code `c`** to the user's email
|
||||
address.
|
||||
4. **`C`** chooses a **random salt `s`** and **iteration count `i`**
|
||||
5. **`C`** generates **`x = PBKDF2(p, s, i)`** and the **password verifier `v = v(x)`**\*
|
||||
5. **`C`** generates **`x = PBKDF2(p, s, i)`** and the **password verifier
|
||||
`v = v(x)`**\*
|
||||
6. **`C`** sends **`u`**, **`v`**, **`s`**, **`i`** and **`c`** to **`S`**
|
||||
7. **`S`** verifies **`c`** and, if successful, stores **`u`**, **`v`**, **`s`** and **`i`** for later use.
|
||||
7. **`S`** verifies **`c`** and, if successful, stores **`u`**, **`v`**, **`s`**
|
||||
and **`i`** for later use.
|
||||
|
||||
The signup process is now complete and the stored values can be used to
|
||||
verify the users identity and to negotiate a common session key.
|
||||
The signup process is now complete and the stored values can be used to verify
|
||||
the users identity and to negotiate a common session key.
|
||||
|
||||
```
|
||||
┌──────────┐ ┌──────────┐
|
||||
|
@ -634,15 +653,16 @@ negotiated. This happens as follows:
|
|||
6. **`C`** generates **`x = PBKDF2(p, s, i)`**, **`K = K_client(x, a, B)`** and
|
||||
**`M = M(A, B, K)`**\*.
|
||||
7. **`C`** sends **`M`** to **`S`**.
|
||||
8. **`S`** generates its own **`K' = K_server(v, b, A)`** and **`M' = M(A, B, K')`**\*.
|
||||
8. **`S`** generates its own **`K' = K_server(v, b, A)`** and
|
||||
**`M' = M(A, B, K')`**\*.
|
||||
9. **`S`** verifies that **`M == M'`** and therefore **`K == K'`**. If
|
||||
verification fails, the session negotiation is aborted.
|
||||
10. If successful, **`S`** stores **`K`** under the session id **`sid`**.
|
||||
11. **`S`** sends **`sid`** to **`C`**, which also stores it along with **`K`**
|
||||
for later use.
|
||||
|
||||
Client and server now have a common and secret session key **`K`** which
|
||||
can be used for authenticating subsequent requests.
|
||||
Client and server now have a common and secret session key **`K`** which can be
|
||||
used for authenticating subsequent requests.
|
||||
|
||||
```
|
||||
┌──────────┐ ┌──────────┐
|
||||
|
@ -670,19 +690,19 @@ can be used for authenticating subsequent requests.
|
|||
|
||||
### Request Authentication
|
||||
|
||||
Using the common session key **`K`** Client and Server can now authenticate
|
||||
each request as follows:
|
||||
Using the common session key **`K`** Client and Server can now authenticate each
|
||||
request as follows:
|
||||
|
||||
1. Let **`sid`** and **`K`** be the previously negotiated session id and key.
|
||||
2. Let **`req`** be the intended request body and **`t1`** the time stamp at
|
||||
the time of the request.
|
||||
2. Let **`req`** be the intended request body and **`t1`** the time stamp at the
|
||||
time of the request.
|
||||
3. **`C`** generates the signature **`sig1 = HMAC(K, sid|t1|req)`**.
|
||||
4. **`C`** sends **`req`**, **`sid`**, **`t1`** and **`sig1`** to **`S`**.
|
||||
5. **`S`** verifies **`req`**, **`sid`** and **`t1`** using **`sig1`**. If
|
||||
verification fails, or if **`t1`** is older than a predetermined maximum
|
||||
request age, the request is rejected.
|
||||
6. Let **`res`** be the response body and **`t2`** the time stamp at the time
|
||||
of the response.
|
||||
6. Let **`res`** be the response body and **`t2`** the time stamp at the time of
|
||||
the response.
|
||||
7. **`S`** generates **`sig2 = HMAC(K, sid|t2|res)`**.
|
||||
8. **`S`** sends **`res`**, **`t2`** and **`sig2`** to **`C`**.
|
||||
9. **`C`** verifies **`res`**, **`sid`** and **`t2`** using **`sig2`**. If
|
||||
|
@ -707,22 +727,23 @@ each request as follows:
|
|||
```
|
||||
|
||||
**\*** For details on how **`v`**, **`a`**, **`A`**, **`b`**, **`B`**, **`K`**
|
||||
and **`M`** are generated, refer to [the SRP
|
||||
specification](https://tools.ietf.org/html/rfc2945#section-3)
|
||||
and **`M`** are generated, refer to
|
||||
[the SRP specification](https://tools.ietf.org/html/rfc2945#section-3)
|
||||
|
||||
### Notes
|
||||
|
||||
- Even though **`v`** is based on **`p`**, it can not be used to guess the password in
|
||||
case someone eavesdrops on the connection or if the server is compromised.
|
||||
See [section 4 of the SRP
|
||||
specification](https://tools.ietf.org/html/rfc2945#section-4) for details.
|
||||
- The session key **`K`** cannot be sniffed out since it is never transmitted. It
|
||||
could theoretically be guessed from the request signature but with a key size
|
||||
of 256 bits this is not really feasible either.
|
||||
- Even though **`v`** is based on **`p`**, it can not be used to guess the
|
||||
password in case someone eavesdrops on the connection or if the server is
|
||||
compromised. See
|
||||
[section 4 of the SRP specification](https://tools.ietf.org/html/rfc2945#section-4)
|
||||
for details.
|
||||
- The session key **`K`** cannot be sniffed out since it is never transmitted.
|
||||
It could theoretically be guessed from the request signature but with a key
|
||||
size of 256 bits this is not really feasible either.
|
||||
- The salt and iteration count used for generating **`x`** as well as the
|
||||
resulting authentication key are completely independent of the
|
||||
corresponding values used for encrypting the accounts private key, even though
|
||||
the derivation scheme and base passphrase are the same.
|
||||
resulting authentication key are completely independent of the corresponding
|
||||
values used for encrypting the accounts private key, even though the
|
||||
derivation scheme and base passphrase are the same.
|
||||
- Request authentication works both ways. Not only can the server verify the
|
||||
users identity and knowledge of their master password, the client can also
|
||||
verify the identity of the server.
|
||||
|
@ -738,10 +759,11 @@ This section covers various possible attack vectors and mitigation steps taken.
|
|||
|
||||
### Man-In-The-Middle Attacks
|
||||
|
||||
A [man-in-the-middle
|
||||
attack](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) is an attack
|
||||
where the attacker secretly relays the communication between two parties in
|
||||
order to eavesdrop on the connection and/or temper with messages in transit.
|
||||
A
|
||||
[man-in-the-middle attack](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)
|
||||
is an attack where the attacker secretly relays the communication between two
|
||||
parties in order to eavesdrop on the connection and/or temper with messages in
|
||||
transit.
|
||||
|
||||
MITM attacks may be launched in a multitude of ways, and even with technlogies
|
||||
like TLS, it is very hard to completely rule out that other parties may be
|
||||
|
@ -754,41 +776,44 @@ compromise the security of the application in any other way.
|
|||
- Communication between the Padloc client and server is always secured through
|
||||
[Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security).
|
||||
- No sensitive information is ever transmitted in plain text.
|
||||
- Transmitted data is protected from tampering through Padloc's strong [Authentication Mechanism](#authentication-and-data-transfer).
|
||||
- Padloc's [Key Exchange Mechanism](#trustless-server-mediated-key-exchange) is designed to be secure even over an untrusted connection.
|
||||
- Transmitted data is protected from tampering through Padloc's strong
|
||||
[Authentication Mechanism](#authentication-and-data-transfer).
|
||||
- Padloc's [Key Exchange Mechanism](#trustless-server-mediated-key-exchange)
|
||||
is designed to be secure even over an untrusted connection.
|
||||
|
||||
### Phishing
|
||||
|
||||
With the addition of [Organizations And Shared
|
||||
Vaults](#organizations-and-shared-vaults) in Padloc 3, phishing has become a
|
||||
potential attack vector as well. Attackers may try to lure Padloc users into
|
||||
sharing sensitive information by inviting them to misleadingly named
|
||||
organizations which can be mistaken for an employer or friend. Users could then
|
||||
accidentally share data within vaults assigned to them.
|
||||
With the addition of
|
||||
[Organizations And Shared Vaults](#organizations-and-shared-vaults) in Padloc 3,
|
||||
phishing has become a potential attack vector as well. Attackers may try to lure
|
||||
Padloc users into sharing sensitive information by inviting them to misleadingly
|
||||
named organizations which can be mistaken for an employer or friend. Users could
|
||||
then accidentally share data within vaults assigned to them.
|
||||
|
||||
However, the procedure for inviting and adding a new member to an organization
|
||||
is designed in a way that makes this very hard to accomplish, since it requires
|
||||
direct, personal coordination between both parties. See [Trustless
|
||||
Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange) for more
|
||||
details.
|
||||
direct, personal coordination between both parties. See
|
||||
[Trustless Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange)
|
||||
for more details.
|
||||
|
||||
### Guessing Master Passwords
|
||||
|
||||
Padloc uses a combination of various [strong encryption
|
||||
algorithms](#cryptographic-primitives-and-parameters) to protect all sensitive
|
||||
data and cryptographic keys both at rest and during transmission. The **master
|
||||
password** acts as a universal key for this encryption scheme.
|
||||
Padloc uses a combination of various
|
||||
[strong encryption algorithms](#cryptographic-primitives-and-parameters) to
|
||||
protect all sensitive data and cryptographic keys both at rest and during
|
||||
transmission. The **master password** acts as a universal key for this
|
||||
encryption scheme.
|
||||
|
||||
Master passwords are never stored anywhere and should only ever be known by the
|
||||
Padloc user themself. Unfortunately, since this means that in the majority of
|
||||
use cases the user will have to commit this password to memory, the "key space" of
|
||||
feasible passwords is relatively limited. Additionally, since master passwords
|
||||
are ultimately chosen by the user, no guarantee can be made to the strength or
|
||||
randomness of these passwords.
|
||||
use cases the user will have to commit this password to memory, the "key space"
|
||||
of feasible passwords is relatively limited. Additionally, since master
|
||||
passwords are ultimately chosen by the user, no guarantee can be made to the
|
||||
strength or randomness of these passwords.
|
||||
|
||||
This means that master password are a prime-target for guessing attacks of all
|
||||
sorts and steps should be taken to make these attacks either infeasible or, at
|
||||
a very minimum, too costly to be worthwhile.
|
||||
sorts and steps should be taken to make these attacks either infeasible or, at a
|
||||
very minimum, too costly to be worthwhile.
|
||||
|
||||
[[TODO]]
|
||||
|
||||
|
@ -812,9 +837,9 @@ a very minimum, too costly to be worthwhile.
|
|||
|
||||
### Symmetric Encryption
|
||||
|
||||
For all symmetric encryption operations, the [AES
|
||||
Cipher](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is used in
|
||||
[GCM mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode) with a key size
|
||||
For all symmetric encryption operations, the
|
||||
[AES Cipher](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is used
|
||||
in [GCM mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode) with a key size
|
||||
of **256 bits**.
|
||||
|
||||
**Areas of use:**
|
||||
|
@ -827,8 +852,8 @@ of **256 bits**.
|
|||
|
||||
For asymmetric encryption operations, the
|
||||
[RSA-OAEP](https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding)
|
||||
algorithm is used with a **modulus length** of **2048 bits** and the [SHA-256 hash
|
||||
function](https://en.wikipedia.org/wiki/SHA-2).
|
||||
algorithm is used with a **modulus length** of **2048 bits** and the
|
||||
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2).
|
||||
|
||||
**Areas of use:**
|
||||
|
||||
|
@ -836,8 +861,10 @@ function](https://en.wikipedia.org/wiki/SHA-2).
|
|||
|
||||
### Symmetric Signature Schemes
|
||||
|
||||
For symmetric signature creation and verification, the [HMAC](https://en.wikipedia.org/wiki/HMAC) algorithm is used with a **key length** of **256 bits** and the [SHA-256 hash
|
||||
function](https://en.wikipedia.org/wiki/SHA-2).
|
||||
For symmetric signature creation and verification, the
|
||||
[HMAC](https://en.wikipedia.org/wiki/HMAC) algorithm is used with a **key
|
||||
length** of **256 bits** and the
|
||||
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2).
|
||||
|
||||
**Areas of use:**
|
||||
|
||||
|
@ -848,9 +875,11 @@ function](https://en.wikipedia.org/wiki/SHA-2).
|
|||
|
||||
### Asymmetric Signature Schems
|
||||
|
||||
For asymmetric signature creation and verification, the [RSA-PSS](https://en.wikipedia.org/wiki/Probabilistic_signature_scheme) algorithm is
|
||||
used with a **modulus length** of **2048 bits**, a **salt length** of **256 bits** and the [SHA-256 hash
|
||||
function](https://en.wikipedia.org/wiki/SHA-2).
|
||||
For asymmetric signature creation and verification, the
|
||||
[RSA-PSS](https://en.wikipedia.org/wiki/Probabilistic_signature_scheme)
|
||||
algorithm is used with a **modulus length** of **2048 bits**, a **salt length**
|
||||
of **256 bits** and the
|
||||
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2).
|
||||
|
||||
**Areas of use:**
|
||||
|
||||
|
@ -861,8 +890,8 @@ function](https://en.wikipedia.org/wiki/SHA-2).
|
|||
|
||||
For password-based key derivation, the
|
||||
[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) algorithm is used with the
|
||||
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2) and a **salt length**
|
||||
of **128 bits**. The iteration count varies by area of use.
|
||||
[SHA-256 hash function](https://en.wikipedia.org/wiki/SHA-2) and a **salt
|
||||
length** of **128 bits**. The iteration count varies by area of use.
|
||||
|
||||
**Areas of use:**
|
||||
|
||||
|
|
Loading…
Reference in New Issue