Skip to content

Bug 2075563 - Integrate EncryptorDecryptor into the autofill database - #7573

Open
theidkamp wants to merge 4 commits into
mozilla:mainfrom
theidkamp:fxcm-2281-integrate-encryptor
Open

theidkamp wants to merge 4 commits into
mozilla:mainfrom
theidkamp:fxcm-2281-integrate-encryptor

Conversation

@theidkamp

@theidkamp theidkamp commented Sep 2, 2026 •

Copy link
Copy Markdown
Collaborator

What

https://bugzilla.mozilla.org/show_bug.cgi?id=2075563

Four commits:

1. The autofill store owns its encryption context. Store::new() takes an EncryptorDecryptor (from the shared db-crypto crate) and hands it to the database; every access to the encrypted column uses it. autofill/src/encryption.rs is gone, and factory functions matching the logins API cover the UniFFI/JS trait gap: create_static_key_manager, create_managed_encdec, create_autofill_store_with_static_key_manager, and - behind the new keydb feature - create_autofill_store_with_nss_keymanager (key name as-autofill-key). Both store factories return ApiResult, so a broken database surfaces as a catchable error rather than a panic.

2. Credit card numbers are transparent in the API - like logins, the client does not notice these fields are encrypted. UpdatableCreditCardFields takes cc_number in cleartext (the store encrypts it and derives cc_number_last_4 itself, also for the bulk-import APIs), and CreditCard.cc_number comes back decrypted - empty for a scrubbed card, while a value the key cannot read fails the read (per review: errors propagate instead of being swallowed). An empty cc_number is stored as an empty cc_number_enc rather than as a ciphertext of "" (per review: a card may be saved without a number, and the empty ciphertext is what marks a scrubbed card for Sync). Values written before this change decrypt unchanged (test_reads_pre_transparency_ciphertext pins that), so there is nothing to migrate.

3. A --profile option for the autofill-utils example (as requested in review). Opens a Firefox profile's autofill.db with the NSS-managed key, prompting for the primary password in the terminal - like sync-pass does for logins. First consumer of create_autofill_store_with_nss_keymanager outside desktop.

4. Bug 2075560: The key-based encrypt_string / decrypt_string namespace functions are removed - with transparent card numbers no consumer handles ciphertext, so nothing needs them. create_autofill_key() stays; for canaries use db_crypto.create_canary / check_canary (format-compatible).

Breaking changes

  • Store::new() takes the encryptor; use the factories. Store construction: Desktop RustAutofillStore.sys.mjs, Android AutofillCreditCardsAddressesStorage.kt, iOS RustAutofill.swift.
  • scrub_undecryptable_credit_card_data_for_remote_replacement() no longer takes a key (iOS is its only caller).
  • encrypt_string(key, ...) / decrypt_string(key, ...) removed (Android AutofillCrypto.kt & iOS RustAutofill.swift/RustKeychain.swift; Desktop never used these).
  • The credit-card dictionaries changed shape: cc_number (cleartext) replaces cc_number_enc in both directions, and UpdatableCreditCardFields no longer takes cc_number_last_4. Consumers stop encrypting/decrypting values entirely - this removes code on all three platforms. Consumer patches are being reworked to this model and will be linked here before landing.

Not breaking: the key passed to the sync manager via local_encryption_keys is accepted but ignored (set_local_encryption_key logs a warning); removal is tracked in Bug 2075562.

Pull Request checklist

  • Breaking changes: This PR follows our breaking change policy
  • Quality: This PR builds and tests run cleanly
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • Changelog: This PR includes a changelog entry in CHANGELOG.md or an explanation of why it does not need one
    • Any breaking changes to Swift or Kotlin binding APIs are noted explicitly
  • Dependencies: This PR follows our dependency management guidelines

@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from cbfbb17 to 516027a Compare September 10, 2026 20:42
@theidkamp
theidkamp changed the base branch from main to db-crypto September 14, 2026 13:44
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch 4 times, most recently from 503e4c4 to c37bde5 Compare September 15, 2026 07:34
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from c37bde5 to 57f41f7 Compare September 18, 2026 13:08
@theidkamp
theidkamp marked this pull request as ready for review September 22, 2026 13:49
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from 57f41f7 to 5574c93 Compare September 22, 2026 13:54
@theidkamp
theidkamp changed the base branch from db-crypto to main September 23, 2026 08:36
@theidkamp
theidkamp requested review from DimiDL and jo September 24, 2026 11:26
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from 5574c93 to b6d4ceb Compare September 25, 2026 08:30

@jo jo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks really clean and well done. A thousand thanks, Tessa - a really great first patch for Application Services! 🎉

Next, we’ll need to work through the Pull Request Checklist, in particular, the corresponding consumer patches should ideally be linked. I think that will be https://phabricator.services.mozilla.com/D325372; I still need to take a look at it. It’s possible that this one is also based on #7576. In that case, we’d need to make sure we merge them one after the other, or better yet, base #7576 against this one.

Comment thread components/autofill/src/lib.rs Outdated
Comment thread components/autofill/Cargo.toml Outdated
anyhow = "1.0"
error-support = { path = "../support/error" }
interrupt-support = { path = "../support/interrupt" }
db-crypto = { path = "../support/db-crypto" }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we should set default-features = false here

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, and changed.

Comment thread components/autofill/src/db/credit_cards.rs
Comment thread components/autofill/src/sync/engine.rs
Comment thread components/autofill/src/lib.rs Outdated
//
// Note this is only temporarily needed until a bug with UniFFI and JavaScript is fixed, which
// prevents passing around traits in JS
pub fn create_autofill_store_with_static_key_manager(path: String, key: String) -> Arc<Store> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is what logins does, but ApiResult<Arc<Store>> might be better to not panic on initialization.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, both store factories return ApiResult<Arc> now ([Throws=AutofillApiError] in the UDL).

@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch 2 times, most recently from 1405cb1 to 835f79e Compare September 25, 2026 11:31
@theidkamp theidkamp changed the title FXCM-2281: Integrate EncryptorDecryptor into the autofill database Bug 2075563 - Integrate EncryptorDecryptor into the autofill database Sep 25, 2026
@theidkamp
theidkamp marked this pull request as draft September 25, 2026 15:56
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch 3 times, most recently from 6cc54e8 to cec147e Compare September 28, 2026 11:59
@theidkamp
theidkamp marked this pull request as ready for review September 28, 2026 12:15
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from cec147e to e893ad6 Compare September 28, 2026 12:16
@theidkamp
theidkamp requested a review from jo September 28, 2026 16:08
Comment thread components/autofill/src/db/models/credit_card.rs
jo
jo previously requested changes Oct 1, 2026

@jo jo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the require_number sanitation, because it changes the API, and I also think the scrubbed cc number is not used as a marker. Also, we are discussion if we can align scrubbing between logins and autofill, and make the latter also delete the entire record.

//
// Note this is only temporarily needed until a bug with UniFFI and JavaScript is fixed, which
// prevents passing around traits in JS
pub fn create_autofill_store_with_static_key_manager(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if this would validate the key, eg via canary:

let canary = encdec.encrypt(b"tschilp".to_vec())?;
encdec.decrypt(canary)?;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I added the validation.

@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from 6156f4a to 637e469 Compare October 2, 2026 08:52
@mergify
mergify Bot dismissed jo’s stale review October 2, 2026 08:53

The pull request has been modified, dismissing previous reviews.

@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from 637e469 to 5071768 Compare October 2, 2026 08:56
Move autofill's credit-card encryption onto the shared db-crypto crate and let
AutofillDb own the encryptor, as logins' LoginDb does. The consumer supplies it
when building the store, so no key is passed into individual calls or down
through the sync layers.
The consumer passes cc_number in cleartext and gets it back decrypted;
encryption is internal to the store, which also derives the last-4 digits.
A scrubbed card - or one the key cannot read, which the scrub-and-resync
flow replaces - comes back with an empty number. Values written before
this change decrypt unchanged, so there is nothing to migrate.
Open a Firefox profile's autofill.db with the NSS-managed key, prompting
for the primary password in the terminal - like sync-pass does for logins.
With transparent card numbers no consumer handles ciphertext, so the
namespace functions that took a key have no callers left.
create_autofill_key() stays for consumers that manage a static key.
@theidkamp
theidkamp force-pushed the fxcm-2281-integrate-encryptor branch from 5071768 to 54fc561 Compare October 2, 2026 09:53

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants