Expand description
FFI layer of Qualia2FA: exposes qualia2fa-core as UniFFI bindings.
§Responsibility of this crate
This crate only moves data: it converts the primitive types passed in from
Kotlin/Swift into core types, calls the core, and converts the results back.
Any cryptography, parsing or validation logic in this file is a design
regression — such logic must stay inside qualia2fa-core, the only layer
that is free of unsafe code and can be audited on its own.
A review of this crate has a single checklist item: has any core logic been moved in here?
uniffi::setup_scaffolding!() expands the unsafe code the FFI boundary needs
inside this crate (raw pointer dereferences, catch_unwind, transfer of string
ownership), so this crate is not forbid(unsafe_code). The safety boundary runs
between crates: the core is forbid(unsafe_code), and this crate is the
only place allowed to contain unsafe code, which must stay thin. Cargo.toml
sets unsafe_code to warn rather than allow, so new unsafe code is reported
at build time.
§Handling of secret material
The core’s OtpSecret deliberately implements neither Clone nor a raw
byte accessor, and its Debug does not even print the length. Across the FFI
boundary a seed is always represented as a Base32 string:
- inbound:
&str->OtpSecret::from_base32 - outbound:
OtpSecret::to_base32
Seed bytes therefore never cross the FFI boundary as a Vec<u8>, which would
leave one copy on each side outside the control of any erasure. Base32 is the
single narrow exit already chosen by the core, and this layer reuses it.
Known residual risk: on the Kotlin/Swift side a Base32 string is an
ordinary String, not protected by secrecy’s erasure, and it may be copied
by the garbage collector or stored in a string pool. That is an inherent
limitation of managed languages, so the client side must adopt its own
discipline: a seed’s Base32 exists only in the scope that needs it, is
dropped immediately afterwards, and is never logged or persisted.
Structs§
- FfiAuth
Bound KeyStore - The platform auth-bound key store used by
master.key.bio. - FfiConflict
- One disagreement a human has to settle.
- FfiConflict
Side - One side of a conflict, as far as it can be shown.
- FfiCore
Error - Summary of a core error, carried across the FFI boundary.
- FfiDirect
Master KeyStore - The application’s master key held directly by the platform key store.
- FfiDropped
Summary - What was dropped or assumed across a whole export.
- FfiEntry
Icon - The picture an entry shows beside its name.
- FfiFrame
Collector - Collects the codes of a multi-frame payload, in any order and with repeats.
- FfiFrame
Step - What one read code was, and what it did to the set it belongs to.
- FfiGroup
- A group: its name and the ordered list of its children.
- FfiImport
- One export, read and waiting for a decision.
- FfiImport
Applied - What an applied import did.
- FfiImport
Choice - One answer, keyed by the position the entry had in the export.
- FfiImport
Match - What the vault already holds that relates to one imported entry.
- FfiImport
Problem - One entry of an export that could not be read.
- FfiImported
Entry - One entry an export holds, as the preview shows it.
- FfiImported
Group - A group the export defined.
- FfiJoiner
- The joiner of a login: a new device that does not have the master key yet.
- FfiLan
Channel - The LAN channel: one endpoint on this network segment, and the peers it sends to.
- FfiLan
Lobby - The lobby: which devices are announcing themselves on this network segment.
- FfiLan
Peer - One device the lobby has heard announcing itself on this network segment.
- FfiLogin
- The initiator of a login: a device that is already logged in and holds the master key.
- FfiOrdering
Conflict - Two arrangements of the same group, for the user to choose between.
- FfiOtp
Auth - A parsed
otpauth://entry. - FfiPlatform
Keys - The device identity key store of the current platform, exported to the host side.
- FfiPortable
Restore - What opening a portable vault file produced.
- FfiQr
Frame - One image of a payload that needs more than one code.
- FfiQr
Image - A rendered QR code, as pixels the host can draw.
- FfiReceived
Message - One message taken off a channel, together with the sender the channel claims.
- FfiResponder
- The responder: holds the master key and proves it to the verifier.
- FfiSync
Outcome - The result of one receive.
- FfiSync
Session - One synchronization session against one channel.
- FfiTransport
Capabilities - What a channel can do.
- FfiVault
- An unlocked vault.
- FfiVault
Entry - A 2FA entry, as represented across the FFI boundary.
- FfiVerifier
- The verifier: confirms that the other side actually holds the master key.
- FfiWrapped
Master KeyStore - The application’s master key held wrapped by a key-encryption key inside the platform key store.
- UniFfi
Trait Vtable FfiDevice Keys - UniFfi
Trait Vtable FfiPlatform Sealer - UniFfi
Trait Vtable FfiSecure Store - UniFfi
Trait Vtable FfiTransport
Enums§
- FfiAlgorithm
- Hash algorithm selection passed in over FFI.
- FfiAuth
Availability - What the platform’s auth-bound key store can do, asked before offering the path.
- FfiDecision
- What the user decided about one conflict.
- FfiDigits
- Number of digits in a generated code.
- FfiEc
Level - The error correction level of a code, named by what it survives.
- FfiEntry
Kind - The kind of an entry, with the parameters that belong to it.
- FfiError
- Errors originating in the FFI boundary itself.
- FfiExport
Format - An export format the host side can choose.
- FfiGroup
Carrying - How much of the group tree an export format carries.
- FfiGroup
Child - One child of a group: an entry or another group.
- FfiIcon
Mime - The image format of an
FfiEntryIcon. - FfiImport
Decision - What to do with one imported entry.
- FfiImport
Format - An export format the host side can name.
- FfiPayload
Kind - What a payload asks the peer to do.
- FfiPortable
Kind - What a
.q2fafile turned out to be, judged by its magic. - FfiRecipient
- The recipient of one message.
- FfiRoster
- How many parties take part in one sync.
- FfiShare
Plan - Which route one share takes.
Traits§
- FfiDevice
Keys - Source of the device identity key pair: forwarded by the host side to the platform hardware key store.
- FfiPlatform
Sealer - The platform half of
master.key.bio, implemented by the host application. - FfiSecure
Store - Where the master key is persisted: forwarded by the host side to the platform hardware key store.
- FfiTransport
- A channel that can move sync payloads.
Functions§
- codes_
match - Compares two code strings for equality in constant time.
- conflict_
kind - Names the shape of a conflict, in the form the host side branches on.
- core_
error_ kind - Maps a core error to a stable machine-readable identifier.
- core_
version - The core library version, for compatibility checks and diagnostics.
- detect_
import_ format - Guesses the format of an export from its content.
- detect_
portable_ file - Recognizes a portable vault file without opening it.
- export_
format_ carries_ groups - Whether this format carries the groups at all.
- export_
format_ extension - The file name extension for this format, without the dot.
- export_
format_ group_ carrying - How much of the group tree this format carries.
- export_
format_ needs_ password - Whether this format is written with a password.
- export_
recovery_ key_ from_ master - Opens a vault with the master key held by an
FfiVault. - generate_
secret_ base32 - Generates a random 256-bit secret and returns its Base32 representation.
- hotp_
code - Computes an HOTP code.
- import_
recovery_ key - Recovers the master key from a recovery key file with a passphrase and writes it into the platform key store.
- is_
lock_ marker - Whether
bytesare a validlock.marker. - is_
lock_ password_ wrap - Whether
bytesare a structurally valid password wrap, without running Argon2id. - is_
lock_ pending - Whether
bytesare a validlock.pending. - is_
secret_ shorter_ than_ recommended - Reports whether the secret is shorter than the recommended length.
- lock_
marker - Builds the
lock.markercontents. - lock_
pending - Builds the
lock.pendingcontents. - lock_
wrap_ len - Length of a password-wrapped master key (
master.key.pw). - max_
group_ depth - The deepest a named group may be nested; the top group is depth zero.
- open_
portable_ file - Restores an account from a portable
.q2fafile. - parse_
otpauth_ uri - Parses an
otpauth://URI. - qr_
decode - Reads the text back out of a grayscale image.
- qr_
decode_ text - Reads any text out of a grayscale image, whichever application drew the code.
- qr_
encode - Encodes
textinto a single QR code and renders it as grayscale pixels. - qr_
encode_ frames - Draws a payload as a sequence of codes, for payloads that one code cannot carry.
- qr_
frame_ capacity - What one code of a multi-frame payload holds, in bytes.
- qr_
unwrap_ text - Takes the envelope off a single-frame code, answering with what was put in.
- recommended_
min_ secret_ len - Recommended minimum secret length in bytes for the given algorithm.
- secret_
byte_ len - The byte length of the secret (not the Base32 string length).
- serialize_
otpauth_ uri - Serializes an
FfiOtpAuthback into anotpauth://URI. - steam_
guard_ code - Computes a Steam Guard code (5 characters, custom alphabet).
- store_
master_ key - Writes a master key into the platform key store.
- totp_
code - Computes a TOTP code.
- uniffi_
qualia2fa_ ffi_ fn_ init_ callback_ vtable_ ffidevicekeys - uniffi_
qualia2fa_ ffi_ fn_ init_ callback_ vtable_ ffiplatformsealer - uniffi_
qualia2fa_ ffi_ fn_ init_ callback_ vtable_ ffisecurestore - uniffi_
qualia2fa_ ffi_ fn_ init_ callback_ vtable_ ffitransport - unwrap_
master_ key_ with_ password - Opens a password-wrapped master key and returns the 32-byte key.
- verify_
code_ with_ drift - Verifies a user-supplied code, allowing for clock drift.
- wrap_
master_ key_ with_ password - Wraps a 32-byte master key with the unlock password.