padloc/security.md

902 lines
52 KiB
Markdown
Raw Permalink Normal View History

2019-04-07 06:32:48 +00:00
# Padloc Security Whitepaper
This document provides a high level overview of the security design and
architecture of the **Padloc** application.
## Security Principles
### Simplicity
While the secure processing, storage and sharing of sensitive data necessarily
involves a certain degree of complexity, Padloc tries to hide this complexity
from the end user as much as possible. In other words, users should be able to
use the application securely without understanding (or even being aware of) the
underlying security principles. At the same time, the applications inner
workings and security mechanisms should be easily verifiable by those who have
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.
2019-04-07 06:32:48 +00:00
### 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
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
## Encryption
Robust data encryption is the foundation of Padlocs security architecture.
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.
2019-04-07 06:32:48 +00:00
#### 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`
2019-04-07 06:32:48 +00:00
4. Store `c`, `iv` and `a` in the container `C`
```
┌───────────┐ ┏━━━━━━━━━━━━━━━━┓
========= │ │ ┃Simple Container┃ ╔═══════════╗
== key ==─────┘ ▼ ┃ ┃ ║ encrypted ║
========= ┌─────────┐ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ ╚═══════════╝
│ encrypt │ ┃ encryption │┃ ┌ ─ ─ ─ ─ ─ ┐
┌────▶│ (AES) │────────────▶│ parameters ┃ plain
│ └─────────┘ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ └ ─ ─ ─ ─ ─ ┘
============== │ │ ┃╔══════════════╗┃ =============
= plain text =────┘ └─────────────────▶║encrypted data║┃ = ephemeral =
============== ┃╚══════════════╝┃ =============
┗━━━━━━━━━━━━━━━━┛
```
#### Decryption
1. Let `k` be the key used for encryption.
2. Retrieve `iv`, `a` and `c` from `C`
3. Generate the plain text `p = AES_decrypt(k, c, iv, a)`
### 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
2019-04-07 06:32:48 +00:00
[PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) key derivation function.
#### Encryption
1. Choose a password `p`
2. Choose an iteration count `i` and random salt `s`
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`
2019-04-07 06:32:48 +00:00
6. Store `s`, `i`, `c`, `iv` and `a` in the container `C`
```
============ ┌────────┐ ┏━━━━━━━━━━━━━━━━┓
= password =──────────▶│ PBKDF2 │───────┐ ┃ Password-Based ┃
============ └────────┘ │ ┃ Container ┃
│ │ ┃ ┃
│ │ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
▼ │ ┃ PBKDF2 │┃
========= └──────▶│ parameters ┃
== key == ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
========= ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
│ ┃ encryption │┃
▼ ┌──────▶│ parameters ┃
┌─────────┐ │ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
============== │ encrypt │ │ ┃╔══════════════╗┃
= plain text =─────────▶│ (AES) │──────┘┌─────▶║encrypted data║┃
============== └─────────┘ │ ┃╚══════════════╝┃
│ │ ┗━━━━━━━━━━━━━━━━┛
│ │
└────────────┘
```
#### Decryption
1. Let `p` be the password used for encryption
2. Retrieve `s`, `i` from `C`
3. Generate `k = PBDKF2(p, s, i)`
4. Retrieve `iv`, `a` and `c` from `C`
5. Generate the plain text `p = AES_decrypt(k, c, iv, a)`
### 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.
2019-04-07 06:32:48 +00:00
#### 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.
2019-04-07 06:32:48 +00:00
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`
2019-04-07 06:32:48 +00:00
```
┏━━━━━━━━━━━━━━┓ ┌───────────────────────────────────────────────────────────┐
┃ Accessor A ┃ │ │
┃ ┃ ▼ ┏━━━━━━━━━━━━━━━━┓ │
┃┌ ─ ─ ─ ─ ─ ─ ┃ ┌─────────┐ ┃Shared Container┃ ============== │
┃ public key │─────┐ │ encrypt │ ┃ ┃ = plain text = │
┃└ ─ ─ ─ ─ ─ ─ ┃ └─────▶│ (RSA) │─────┐ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ ============== │
┃╔════════════╗┃ └─────────┘ │ ┃ encrypted │┃ │ │
┃║private key ║┃ └─────▶│ key (A) ┃ ▼ │
┃╚════════════╝┃ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ ┌─────────┐ │
┗━━━━━━━━━━━━━━┛ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ │ encrypt │ =========
┃ encrypted │┃ ┌───│ (AES) │◀────== key ==
┌─────▶│ key (B) ┃ │ └─────────┘ =========
│ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ │ │ │
┏━━━━━━━━━━━━━━┓ │ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃ │ │ │
┃ Accessor B ┃ │ ┃ encryption │┃ │ │ │
┃ ┃ │ ┃│ parameters ◀─┘ │ │
┃┌ ─ ─ ─ ─ ─ ─ ┃ ┌─────────┐ │ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃ │ │
┃ public key │─────┐ │ encrypt │ │ ┃╔══════════════╗┃ │ │
┃└ ─ ─ ─ ─ ─ ─ ┃ └─────▶│ (RSA) │─────┘ ┃║encrypted data║◀──────────┘ │
┃╔════════════╗┃ └─────────┘ ┃╚══════════════╝┃ │
┃║private key ║┃ ▲ ┗━━━━━━━━━━━━━━━━┛ │
┃╚════════════╝┃ │ │
┗━━━━━━━━━━━━━━┛ └───────────────────────────────────────────────────────────┘
```
#### Decryption
1. Let `id_n`, `priv_n` be the id and private key of one of the accessors used
during encryption.
2. Retrieve `K` from `C`, find the encrypted key `K_n` for `id_n`.
3. Generate `k = RSA_decrypt(priv_n, K_n)`
4. Retrieve `iv`, `a` and `c` from `C`
5. Generate the plain text `p = AES_decrypt(k, c, iv, a)`
```
┌─────────┐
┏━━━━━━━━━━━━━━┓ │ decrypt │ ┏━━━━━━━━━━━━━━━━┓
┃ Accessor A ┃ ┌─────────▶│ (RSA) │◀────────┐ ┃Shared Container┃
┃ ┃ │ └─────────┘ │ ┃ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │ │ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
┃ public key │┃ │ │ │ ┃ encrypted │┃
┃└ ─ ─ ─ ─ ─ ─ ┃ │ ========= │ └─────────│ key (A) ┃
┃╔════════════╗┃ │ == key ==◀─┘ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
┃║private key ║─────────┘ ========= ┌───────────┐ ┃┌ ─ ─ ─ ─ ─ ─ ─ ┃
┃╚════════════╝┃ │ │ │ ┃ encryption │┃
┗━━━━━━━━━━━━━━┛ │ ▼ └──────│ parameters ┃
│ ┌─────────┐ ┃ ─ ─ ─ ─ ─ ─ ─ ┘┃
│ │ decrypt │ ┃╔══════════════╗┃
└──────▶│ (AES) │◀────────────║encrypted data║┃
└─────────┘ ┃╚══════════════╝┃
│ ┗━━━━━━━━━━━━━━━━┛
==============
= plain text =
==============
```
## Client-Server Architecture And The Zero-Trust Principle
[[TODO]]
2019-04-07 06:32:48 +00:00
## The Account Object And Master Password
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.
2019-04-07 06:32:48 +00:00
- 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).
2019-04-07 06:32:48 +00:00
- A HMAC key used for signing and verifing organization details (see
[Organizations And Shared Vaults / Adding Members](#adding-members)
2019-04-07 06:32:48 +00:00
- 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.
2019-04-07 06:32:48 +00:00
```
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ Account ┃ ╔═══════════╗
┃ ┃ ║ encrypted ║
┃ ┌ ─ ┐┌ ─ ─ ┐┌ ─ ─ ┐ ┃ ╚═══════════╝
┃ id name email ┃ ┌ ─ ─ ─ ─ ─ ┐
┃ └ ─ ┘└ ─ ─ ┘└ ─ ─ ┘ ┃ plain
=================== ┃ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┃ └ ─ ─ ─ ─ ─ ┘
= Master Password =───────┐ ┃ public key ┃ =============
=================== │ ┃ └ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ┃ = ephemeral =
│ ┃ ╔═════════════════╗ ┃ =============
decrypts ┃ ║ ┌─────────────┐ ║ ┃
│ ┃ ║ │ private key │ ║ ┃
│ ┃ ║ └─────────────┘ ║ ┃
└───────▶║ ┌─────────────┐ ║ ┃
┃ ║ │ signing key │ ║ ┃
┃ ║ └─────────────┘ ║ ┃
┃ ╚═════════════════╝ ┃
┗━━━━━━━━━━━━━━━━━━━━━┛
```
## Vaults
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**.
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
```
┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓
┃ Account ┃ ┃ Vault ┃
┃ ┃ ┃ ┃
┃ ┌ ─ ─ ─ ─ ─ ┐ ┃ ┃ ╔══════════╗ ┃
┃ public key ──────encrypts──────▶║vault data║ ┃
┃ └ ─ ─ ─ ─ ─ ┘ ┃ ┃ ╚══════════╝ ┃
┃ ╔═══════════╗ ┃ ┃ ▲ ┃
┃ ║private key║──────decrypts─────────────┘ ┃
┃ ╚═══════════╝ ┃ ┃ ┃
┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━┛
```
Each Padloc user owns a private vault to which only they have access. In
addition to this, **Shared Vaults** can be used to share sensitive data between
multiple members within an **Organization**. For more details on this, see the
[Organizations And Shared Vaults](#organizations-and-shared-vaults) section.
## Organizations And Shared Vaults
**Shared Vaults** can be used to securely share sensitive data between multiple
users. These vaults are provisioned and managed as part of **Organizations**,
which deal with permission management as well as public key and identity
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.
2019-04-07 06:32:48 +00:00
The organisation structure depicted below determines which member shall have
access to a given vault. Members can either be assigned to a **Vault** directly
or indirectly via a **Group**.
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ │ ╱│ │╲ │ │
│ Account │┼─────────○─│ Membership │──┼────────┼│ Organization │
│ │ ╲│ │╱ │ │
└──────────────┘ └───┬──────┬───┘ └──────────────┘
╲│╱ ╲│╱ ┼
○ ○ ○
│ │ ╱│╲
│ │ ┌──────────────┐
│ │ ╱│ │
│ └──────────────○─│ Group │
│ ╲│ │
○ └──────────────┘
╱│╲ ╲│╱
┌──────────────┐ ○
│ │╲ │
│ Shared Vault │─○──────────────────────┘
│ │╱
└──────────────┘
```
Every time a **Vault** participant encrypts the vault data, they perform the
following steps:
2019-04-07 06:32:48 +00:00
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)
2019-04-07 06:32:48 +00:00
Each participating member can now access the Vault data using their own private
key.
### Metadata And Cryptographic Keys
In addition to Group and Member data, **Organizations** also hold the following
information:
- The organization **id** is a random, unique identier assigned to it by the
server
- 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.
2019-04-07 06:32:48 +00:00
- An AES key (in the following called "**invites key**") used to encrypt the
invite verification code during
[key exchange](#trustless-server-mediated-key-exchange)
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
```
┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━┓
┃ Organization ┃ ┃ Organization ┃
┃ Owner ┃ ┃ ┃
┃ ┃ ┃ ╔═══════════════╗ ┃
┃ ┌ ─ ─ ─ ─ ─ ┐ ┃ ┃ ║┌─────────────┐║ ┃
┃ public key ──────encrypts──────▶║│ private key │║ ┃
┃ └ ─ ─ ─ ─ ─ ┘ ┃ ┃ ║└─────────────┘║ ┃
┃ ╔═══════════╗ ┃ ┃ ║┌─────────────┐║ ┃
┃ ║private key║──────decrypts──────▶║│ invites key │║ ┃
┃ ╚═══════════╝ ┃ ┃ ║└─────────────┘║ ┃
┗━━━━━━━━━━━━━━━┛ ┃ ╚═══════════════╝ ┃
┗━━━━━━━━━━━━━━━━━━━━┛
```
### Public Key Exchange And Verification
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
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
#### Trustless Server-Mediated Key Exchange
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.
2019-04-07 06:32:48 +00:00
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.
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`**.
12. **`O`** verifies **`pub_i`** using **`sig_i`** and **`x`**.
2019-04-07 06:32:48 +00:00
```
┌─────────────┐ ┌──────────┐ ┌───────────┐
│Org Owner (O)│ │Server (S)│ │Invitee (I)│
└──────┬──────┘ └────┬─────┘ └─────┬─────┘
┌─────────────────────┐ │ │ │
│p = [passphrase] │ │ s, i, id, email, │ │
│s = [random salt] │ │ pub_o, sig_o │ id (via email) │
│i = [iteration count]│ │─────────────────▶│─────────────────▷│
│x = PBKDF2(p,s,i) │ │ │ │
│pub_o = [public key] │ │ │ id │
│sig_o = HMAC(x,pub_o)│ │ │◀─────────────────│
│id = [invite id] │ │ │ s, i, │
│email = [inv. email] │ │ │ pub_o, sig_o │
└─────────────────────┘ │ │─ ─ ─ ─ ─ ─ ─ ─ ─▶│
│ │ │
│ │ p (in person) │ ┌─────────────────────┐
│────────────────────────────────────▷│ │pub_i = [public key] │
│ │ │ │x = PBKDF2(p,s,i) │
┌─────────────────┐ │ pub_i, sig_i │ pub_i, sig_i │ │x => verify sig_o │
│x => verify sig_i│ │◀─────────────────│◀─────────────────│ │sig_i = HMAC(x,pub_i)│
└─────────────────┘ │ │ │ └─────────────────────┘
│ │ │
│ │ │
│ │ │
▼ ▼ ▼
```
##### Notes:
- In practice, the member's account id and email and the organization id are
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
- 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.
2019-04-07 06:32:48 +00:00
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
2019-04-07 06:32:48 +00:00
dedicated AES "invites key" which is only accessible to organization owners.
(See [Metadata and Cryptographic Keys](#metadata-and-cryptographic-keys).
#### Adding Members
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
```
┏━━━━━━━━━━━━━━┓
┃Member Account┃
┃ ┃ ┌────────┐
┃╔════════════╗┃ │ sign │
┃║signing key ║──────────▶│ (HMAC) │◀────┐
┃╚════════════╝┃ └────────┘ │
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │
┃ public key │─────────────┐ │ │
┃└ ─ ─ ─ ─ ─ ─ ┃ │ │ │
┗━━━━━━━━━━━━━━┛ │ │ │
│ │ │ ┏━━━━━━━━━━━━━━┓
┏━━━━━━━━━━━━━━┓ │ │ │ ┃ Organization ┃
┃ Membership ┃ │ │ │ ┃ ┃
┃ ┃ │ │ │ ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │ └───── public key │┃
┃ organization│┃ │ │ ┃└ ─ ─ ─ ─ ─ ─ ┃
┃│ signature ◀────────────│──┘ ┃╔════════════╗┃
┃ ─ ─ ─ ─ ─ ─ ┘┃ ▼ ┌─────║private key ║┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ ┌────────┐ │ ┃╚════════════╝┃
┃ member │┃ │ sign │ │ ┗━━━━━━━━━━━━━━┛
┃│ signature ◀──────────│ (RSA) │◀────┘
┃ ─ ─ ─ ─ ─ ─ ┘┃ └────────┘
┗━━━━━━━━━━━━━━┛
```
#### Verifying Members
Using the signatures described in the previous section, an organization member
can verify the public key of any other member as follows.
1. Verify the organizations public key using the organization signature created
with their own HMAC key
2. Verify the other member's public key using the organization's public key.
2019-04-07 06:32:48 +00:00
```
┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━┓
┃ Account A ┃ ┃ Org ┃ ┃ Account B ┃
┃ ┃ ┌────────┐ ┃ ┃ ┌────────┐ ┃ ┃
┃╔════════════╗┃ │ verify │ ┃┌ ─ ─ ─ ─ ─ ─ ┃ │ verify │ ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃║signing key ║────▶│ (HMAC) │◀──── public key │────▶│ (RSA) │◀─── public key │┃
┃╚════════════╝┃ └────────┘ ┃└ ─ ─ ─ ─ ─ ─ ┃ └────────┘ ┃└ ─ ─ ─ ─ ─ ─ ┃
┗━━━━━━━━━━━━━━┛ ▲ ┃╔════════════╗┃ ▲ ┗━━━━━━━━━━━━━━┛
│ ┃║private key ║┃ │ ┏━━━━━━━━━━━━━━┓
┏━━━━━━━━━━━━━━┓ │ ┃╚════════════╝┃ │ ┃ Membership B ┃
┃ Membership A ┃ │ ┗━━━━━━━━━━━━━━┛ │ ┃ ┃
┃ ┃ │ │ ┃┌ ─ ─ ─ ─ ─ ─ ┃
┃┌ ─ ─ ─ ─ ─ ─ ┃ │ │ ┃ member │┃
┃ organization│┃ │ └────────│ signature ┃
┃│ signature ┣─────────┘ ┃ ─ ─ ─ ─ ─ ─ ┘┃
┃ ─ ─ ─ ─ ─ ─ ┘┃ ┗━━━━━━━━━━━━━━┛
┗━━━━━━━━━━━━━━┛
```
#### Organization Roles and Privileges
There are three distinct organization roles: **Owner**, **Admin** and basic
**Member**. Each role comes with a different set of privileges. Some privileges
are enforced cryptographically while others are enforced solely by the server.
##### Basic Member
A basic organization member has the following privileges.
1. Read the public data of other members, including id, email, public key and
assigned vaults and groups.
2. Read vault data of assigned vaults
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).
2019-04-07 06:32:48 +00:00
##### Admin
In addition to the privileges granted to basic members, admins also have the
following privileges:
2019-04-07 06:32:48 +00:00
1. Create and delete Vaults
2. Assign vault access to groups and members directly
3. Create, delete and manage groups
##### Owner
In addition to the privileges granted to basic members and admins, organization
owners also have the following privileges:
1. Add/remove organization members
2. Update a members id, email, public key or role
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.
2019-04-07 06:32:48 +00:00
## 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.
2019-04-07 06:32:48 +00:00
### 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.
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
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)`**\*
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
```
┌──────────┐ ┌──────────┐
│Client (C)│ │Server (S)│
└─────┬────┘ └────┬─────┘
┌───────────────────┐ │ │
│u = [email address]│ │ u │
└───────────────────┘ │──────────────▶│ ┌───────────────────────┐
│ │ │c = [verification code]│
│ │ └───────────────────────┘
┌─────────────────────┐ │ c (via email) │
│p = [master password]│ │◁ ─ ─ ─ ─ ─ ─ ─│
│s = [random salt] │ │ │
│i = [iteration count]│ │ │
│x = PBKDF2(p,s,i) │ │ u, v, s, i, c │ ┌───────────────────┐
│v = v(x)* │ │──────────────▶│ │=> verify c │
└─────────────────────┘ │ │ │=> store u, v, s, i│
│ │ └───────────────────┘
│ │
▼ ▼
```
### Session Negotiation
In order to "log into" an existing account, a common session key needs to be
negotiated. This happens as follows:
1. Let **`u`** and **`p`** be the users **email address** and **master
password**, respectively.
2. The client **`C`** generates the random values **`a`** and **`A`**\*
3. **`C`** sends **`u`** and **`A`** to the Server `S`.
4. **`S`** looks up **`s`** and **`i`** based on **`u`** and generates the
random values **`b`** and **`B`**\*.
5. **`S`** sends **`s`**, **`i`** and **`B`** to **`C`**.
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')`**\*.
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
```
┌──────────┐ ┌──────────┐
│Client (C)│ │Server (S)│
└─────┬────┘ └────┬─────┘
┌───────────────────┐ │ │
│u = [email address]│ │ u, A │
│a, A = [random*] │ │──────────────▶│
└───────────────────┘ │ │ ┌────────────────┐
│ │ │b, B = [random*]│
┌───────────────────────┐ │ s, i, B │ └────────────────┘
│p = [master password] │ │◁ ─ ─ ─ ─ ─ ─ ─│
│x = PBKDF2(p,s,i) │ │ │
│K = K_client(x, a, B)* │ │ │
│M = M(A, B, K)* │ │ M │ ┌───────────────────────┐
└───────────────────────┘ │──────────────▶│ │K' = K_server(v, b, A)*│
│ │ │M' = M(A, B, K') │
│ │ │=> verify M == M' │
┌───────────────┐ │ sid │ │S = [session id] │
│=> store sid, K│ │◀ ─ ─ ─ ─ ─ ─ ─│ │=> store sid, K │
└───────────────┘ │ │ └───────────────────────┘
│ │
▼ ▼
```
### Request Authentication
Using the common session key **`K`** Client and Server can now authenticate each
request as follows:
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
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
verification fails, or if **`t2`** is older than a predetermined maximum
response age, the response is rejected.
```
┌──────────┐ ┌──────────┐
│Client (C)│ │Server (S)│
└─────┬────┘ └────┬─────┘
┌──────────────────────────┐ │ │
│req = [request body] │ │ req, sid, │
│t1 = [timestamp] │ │ t1, sig1 │ ┌──────────────────────────┐
│sig1 = HMAC(K, sid|t1|req)│ │──────────────▶│ │=> verify sig1 │
└──────────────────────────┘ │ │ │res = [response body] │
│ │ │t2 = [timestamp] │
┌──────────────┐ │ res, t2, sig2 │ │sig2 = HMAC(K, sid|t2|res)│
│=> verify sig2│ │◁ ─ ─ ─ ─ ─ ─ ─│ └──────────────────────────┘
└──────────────┘ │ │
│ │
▼ ▼
```
**\*** 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)
2019-04-07 06:32:48 +00:00
### 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.
2019-04-07 06:32:48 +00:00
- 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.
2019-04-07 06:32:48 +00:00
- 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.
- The described authentication mechanism not only allows for identity
verification, but also prevents tempering with the request/response body or
timestamp.
- Rejecting request and responses older than a certain age mitigates the risk
of replay attacks.
## Possible Attack Vectors and Mitigations
This section covers various possible attack vectors and mitigation steps taken.
2019-04-07 06:32:48 +00:00
### 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.
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
listening in on the connection or even trying to tamper with the messages
exchanged. Therefore, steps should be taken not only to mitigate the risk of a
successful MITM attack, but also to ensure that even in case of an insecure
connection, an attacker may never get access to any sensitive information or
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.
2019-04-07 06:32:48 +00:00
### 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.
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.
### 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.
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.
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.
[[TODO]]
### User Enumeration
[[TODO]]
### Password Spraying
[[TODO]]
### Denial Of Service
[[TODO]]
### Compromised Server
[[TODO]]
## Cryptographic Algorithms And Configurations
### 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
of **256 bits**.
**Areas of use:**
- [Simple Symmetric Encryption](#simple-symmetric-encryption)
- [Password-Based Encryption](#password-based-encryption)
- [Shared-Key Encryption](#shared-key-encryption)
### Asymmetric Encryption
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).
**Areas of use:**
- [Shared-Key Encryption](#shared-key-encryption)
### 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).
**Areas of use:**
- [Request Authentication](#request-authentication)
- [Adding Members](#adding-members)
- [Verifying Members](#verying-members)
- [Trustless Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange).
### 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).
**Areas of use:**
- [Adding Members](#adding-members)
- [Verifying Members](#verying-members)
### Password-Based Key Derivation
2019-04-07 06:32:48 +00:00
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.
2019-04-07 06:32:48 +00:00
**Areas of use:**
2019-04-07 06:32:48 +00:00
- [Password-Based Encryption](#password-based-encryption)
- [User Signup](#user-signup)
- [Session Negotiation](#session-negotiation)
- [Trustless Server-Mediated Key Exchange](#trustless-server-mediated-key-exchange).