Add encryption key fetch from bucket (#2159)
This commit is contained in:
@@ -259,8 +259,15 @@ export async function vaultCodecCanonicalizeFromSqlite(input: CodecCanonicalizeI
|
||||
* emitting it, so unknown newer-client data survives the round trip inside the vault DB itself.
|
||||
*/
|
||||
export async function vaultCodecMaterializeAsSqlite(manifest: CodecManifest, dataBuckets: CodecDataBucket[], schemaColumns?: Record<string, string[]>): Promise<CodecMaterialized> {
|
||||
/**
|
||||
* Extract the primary encryption-key row (the user's asymmetric keypair) from the decrypted
|
||||
* `EncryptionKeys` data bucket — the small, independently-decryptable bucket the keypair now lives in.
|
||||
* Used to unwrap shared-folder VEKs during pull without materializing the full root manifest.
|
||||
* Returns null when the bucket carries no primary key.
|
||||
*/
|
||||
export async function vaultCodecExtractPrimaryEncryptionKeyFromBucket(bucket: CodecDataBucket): Promise<Record<string, unknown> | null> {
|
||||
await initRustCore();
|
||||
return core.vaultCodecMaterializeAsSqlite({ manifest, dataBuckets, schemaColumns }) as CodecMaterialized;
|
||||
return (core.vaultCodecExtractPrimaryEncryptionKeyFromBucket(bucket) ?? null) as Record<string, unknown> | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -271,6 +271,16 @@ pub unsafe extern "C" fn vault_codec_validate_data_bucket_ffi(input_json: *const
|
||||
codec_json_ffi(input_json, "input_json", crate::vault_codec::validate_data_bucket_json)
|
||||
}
|
||||
|
||||
/// Extract the primary encryption-key row from the decrypted `EncryptionKeys` data bucket.
|
||||
/// Input: `DataBucket` JSON. Output: the `EncryptionKeys` row JSON object, or `null` when absent.
|
||||
///
|
||||
/// # Safety
|
||||
/// `input_json` must be a valid null-terminated C string; free the result with `free_string`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn vault_codec_extract_primary_encryption_key_from_bucket_ffi(input_json: *const c_char) -> *mut c_char {
|
||||
codec_json_ffi(input_json, "input_json", crate::vault_codec::extract_primary_encryption_key_from_bucket_json)
|
||||
}
|
||||
|
||||
/// The bucket layout: `[{ category, tables: [<name>] }]` JSON.
|
||||
///
|
||||
/// # Safety
|
||||
|
||||
@@ -28,7 +28,7 @@ pub use vault_codec::{
|
||||
extract_bucket, generate_user_salt, unpack_payload, materialize_as_sqlite, pack_payload,
|
||||
validate_manifest, validate_data_bucket, BlobEntry,
|
||||
CanonicalizeInput, CanonicalizedVault, CodecRecord, CodecTableData, DataBucket, Manifest,
|
||||
MaterializeInput, MaterializedTables, ValidationResult,
|
||||
MaterializeInput, MaterializedTables, SharedFolderSpec, SharedVault, ValidationResult,
|
||||
};
|
||||
pub use vault_pruner::{
|
||||
prune_vault, PruneInput, PruneOutput, PruneStats,
|
||||
|
||||
@@ -135,6 +135,14 @@ pub fn validate_data_bucket(b: &DataBucket) -> ValidationResult {
|
||||
validate::validate_data_bucket(b)
|
||||
}
|
||||
|
||||
/// Extract the primary encryption-key row from the decrypted `EncryptionKeys` data bucket — used to
|
||||
/// unwrap shared-folder VEKs during pull, decrypting only the small keypair bucket rather than the
|
||||
/// full root manifest.
|
||||
pub fn extract_primary_encryption_key_from_bucket_json(bucket_json: &str) -> VaultResult<String> {
|
||||
let b: DataBucket = serde_json::from_str(bucket_json)?;
|
||||
Ok(serde_json::to_string(&extract_primary_encryption_key_from_bucket(&b))?)
|
||||
}
|
||||
|
||||
/// SHA-256 (lowercase hex) of a base64 ciphertext string — storage-layer integrity.
|
||||
pub fn compute_ciphertext_hash(base64_ciphertext: &str) -> String {
|
||||
match BASE64.decode(base64_ciphertext) {
|
||||
|
||||
@@ -214,6 +214,15 @@ pub fn vault_codec_compute_ciphertext_hash_js(base64_ciphertext: &str) -> String
|
||||
vault_codec::compute_ciphertext_hash(base64_ciphertext)
|
||||
}
|
||||
|
||||
/// Extract the primary encryption-key row from the decrypted `EncryptionKeys` data bucket.
|
||||
/// Input: `DataBucket`. Output: the `EncryptionKeys` row object, or null when the bucket has none.
|
||||
#[wasm_bindgen(js_name = vaultCodecExtractPrimaryEncryptionKeyFromBucket)]
|
||||
pub fn vault_codec_extract_primary_encryption_key_from_bucket_js(bucket: JsValue) -> Result<JsValue, JsValue> {
|
||||
let b: DataBucket = serde_wasm_bindgen::from_value(bucket)
|
||||
.map_err(|e| JsValue::from_str(&format!("Failed to parse data bucket: {}", e)))?;
|
||||
codec_to_js(&vault_codec::extract_primary_encryption_key_from_bucket(&b))
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
// Credential Matcher WASM Bindings
|
||||
// ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user