Watch
1
0
Fork
You've already forked vaultwarden
0
mirror of https://github.com/dani-garcia/vaultwarden.git synced 2026-11-09 23:59:17 -05:00

Compare commits

..
Author SHA1 Message Date
Daniel García
a8e4fe1ec4
Move the v2 upgrade token migration to its own version
Diesel identifies a migration by the date in its folder name alone, and silently drops one of two folders that share it. The Custom Roles migration uses the same date.
2026-11-04 22:13:23 +01:00
Daniel García
2bb9035940
Remove the v2 upgrade feature flags
With force-upgrade-v2-encryption on, the clients loop on any v1 account that stays v1 on a vault route: the migration check runs fullSync(false), which writes lastSync, which triggers the scheduler again. No server response stops it, so don't serve the flag until the clients fix it.

pm-30144-sdk-key-rotation and pm-31050-no-logout-key-upgrade-rotation only serve that upgrade, so they go too.
2026-11-04 22:13:23 +01:00
Daniel García
f07f99fcb4
Document the v2 encryption feature flags 2026-11-04 22:13:23 +01:00
Daniel García
9c6357a9fd
Gate v2 logins on upstream's v2 encryption check 2026-11-04 22:13:23 +01:00
Daniel García
acd40b1705
Save the signature key pair before the v2 account state 2026-11-04 22:13:23 +01:00
Daniel García
90993c92be
Refuse key ids that aren't 32 lowercase hex characters, like upstream 2026-11-04 22:13:23 +01:00
Daniel García
aaa8f240d6
Clear user key ids left stale by key rotations 2026-11-04 22:13:23 +01:00
Daniel García
6dd49a7cf9
Implement V2 key rotation support 2026-11-04 22:13:23 +01:00
Daniel García
de40d7de29
Implement V2 registration support 2026-11-04 22:13:12 +01:00
Daniel García
c218e0200c
Support blob-encrypted ciphers and match upstream's key id checks 2026-11-04 22:13:12 +01:00
44 changed files with 1960 additions and 431 deletions

View file

@ -411,6 +411,9 @@
## - "biometrics-sdk-ipc": Enable biometric unlock over the SDK IPC framework (Desktop >= 2026.9.0, Browser >= 2026.9.0) ## - "biometrics-sdk-ipc": Enable biometric unlock over the SDK IPC framework (Desktop >= 2026.9.0, Browser >= 2026.9.0)
## - "windows-native-credential-sync": Register the desktop app as a passkey provider in Windows, so passkeys in the vault can be used by other apps and browsers. ## - "windows-native-credential-sync": Register the desktop app as a passkey provider in Windows, so passkeys in the vault can be used by other apps and browsers.
## Requires the Microsoft Store (appx) build of the desktop app. Stable releases up to and including 2026.9.1 lack the required plugin registration, so it has no effect there yet. ## Requires the Microsoft Store (appx) build of the desktop app. Stable releases up to and including 2026.9.1 lack the required plugin registration, so it has no effect there yet.
## - "pm-27278-v2-password-registration": Register new accounts with v2 encryption. (Web >= 2026.6.4, Desktop/Browser/CLI >= 2026.7.0, Android >= 2026.4.1, iOS >= 2026.5.1)
## - "enable-account-encryption-v2-jit-password-registration": Give SSO users who set their master password on their first login v2 encryption. (Web >= 2026.1.1, Desktop/Browser/CLI >= 2026.1.0, Android >= 2026.4.1, iOS >= 2026.6.0)
## These two flags can't be undone: a v2 account stays v2, and it can only log in from clients that are 2025.11.0 or newer and send their version, which rules out some older and third-party clients.
# EXPERIMENTAL_CLIENT_FEATURE_FLAGS= # EXPERIMENTAL_CLIENT_FEATURE_FLAGS=
## Require new device emails. When a user logs in an email is required to be sent. ## Require new device emails. When a user logs in an email is required to be sent.

View file

@ -14,9 +14,8 @@ extend-ignore-re = [
# In SMTP it's called HELO, so ignore it # In SMTP it's called HELO, so ignore it
"(?i)helo_name", "(?i)helo_name",
"Server name sent during.+HELO", "Server name sent during.+HELO",
# COSE Is short for CBOR Object Signing and Encryption, ignore these specific items # COSE Is short for CBOR Object Signing and Encryption
"COSEKey", "(?i)cose",
"COSEAlgorithm",
# Ignore this specific string as it's valid # Ignore this specific string as it's valid
"Ensure they are valid OTPs", "Ensure they are valid OTPs",
# This word is misspelled upstream # This word is misspelled upstream

View file

@ -107,7 +107,7 @@ serde = { version = "1.0.229", features = ["derive"] }
serde_json = "1.0.154" serde_json = "1.0.154"
# A safe, extensible ORM and Query builder # A safe, extensible ORM and Query builder
diesel = { version = "2.3.14", features = ["chrono", "r2d2", "numeric"] } diesel = { version = "2.3.14", features = ["chrono", "r2d2", "numeric", "64-column-tables"] }
diesel_migrations = "2.3.2" diesel_migrations = "2.3.2"
derive_more = { version = "2.1.1", features = [ derive_more = { version = "2.1.1", features = [

View file

@ -0,0 +1,3 @@
-- A blob-encrypted cipher keeps all of its content in `data`, up to 500,000 characters, so the
-- 64 KiB of TEXT is too small. Like upstream, which uses LONGTEXT.
ALTER TABLE ciphers MODIFY data LONGTEXT NOT NULL;

View file

@ -0,0 +1,5 @@
DROP TABLE IF EXISTS user_signature_key_pairs;
ALTER TABLE users DROP COLUMN signed_public_key;
ALTER TABLE users DROP COLUMN security_state;
ALTER TABLE users DROP COLUMN security_version;

View file

@ -0,0 +1,14 @@
ALTER TABLE users ADD COLUMN signed_public_key TEXT;
ALTER TABLE users ADD COLUMN security_state TEXT;
ALTER TABLE users ADD COLUMN security_version INTEGER;
CREATE TABLE user_signature_key_pairs (
uuid CHAR(36) NOT NULL PRIMARY KEY,
user_uuid CHAR(36) NOT NULL UNIQUE,
signature_algorithm INTEGER NOT NULL, -- 0 = ed25519, 1 = mldsa44
signing_key TEXT NOT NULL,
verifying_key TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
FOREIGN KEY (user_uuid) REFERENCES users (uuid) ON DELETE CASCADE
);

View file

@ -0,0 +1,4 @@
-- Key rotations before this kept the id of the old user key, so every new
-- cipher was refused from then on. Stale ids can't be told apart, so clear
-- all of them; clients record their current key's id again when it's empty.
UPDATE users SET key_id = NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE users DROP COLUMN v2_upgrade_token;
ALTER TABLE users_organizations DROP COLUMN v2_upgrade_token;

View file

@ -0,0 +1,2 @@
ALTER TABLE users ADD COLUMN v2_upgrade_token TEXT;
ALTER TABLE users_organizations ADD COLUMN v2_upgrade_token TEXT;

View file

@ -0,0 +1,3 @@
-- TEXT has no size limit here, only MySQL needed the change.
-- PostgreSQL rejects a migration that is only comments ("Received an empty query"), hence the no-op.
SELECT 1;

View file

@ -0,0 +1,5 @@
DROP TABLE IF EXISTS user_signature_key_pairs;
ALTER TABLE users DROP COLUMN signed_public_key;
ALTER TABLE users DROP COLUMN security_state;
ALTER TABLE users DROP COLUMN security_version;

View file

@ -0,0 +1,13 @@
ALTER TABLE users ADD COLUMN signed_public_key TEXT;
ALTER TABLE users ADD COLUMN security_state TEXT;
ALTER TABLE users ADD COLUMN security_version INTEGER;
CREATE TABLE user_signature_key_pairs (
uuid CHAR(36) NOT NULL PRIMARY KEY,
user_uuid CHAR(36) NOT NULL UNIQUE REFERENCES users (uuid) ON DELETE CASCADE,
signature_algorithm INTEGER NOT NULL, -- 0 = ed25519, 1 = mldsa44
signing_key TEXT NOT NULL,
verifying_key TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);

View file

@ -0,0 +1,4 @@
-- Key rotations before this kept the id of the old user key, so every new
-- cipher was refused from then on. Stale ids can't be told apart, so clear
-- all of them; clients record their current key's id again when it's empty.
UPDATE users SET key_id = NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE users DROP COLUMN v2_upgrade_token;
ALTER TABLE users_organizations DROP COLUMN v2_upgrade_token;

View file

@ -0,0 +1,2 @@
ALTER TABLE users ADD COLUMN v2_upgrade_token TEXT;
ALTER TABLE users_organizations ADD COLUMN v2_upgrade_token TEXT;

Some files were not shown because too many files have changed in this diff Show more