v0.2.5-pre.009

This commit is contained in:
2026-08-20 09:24:10 +02:00
parent 1125ade4c1
commit e91bf36e9e
83 changed files with 2467 additions and 1801 deletions

View File

@@ -1,9 +1,9 @@
// file: crates/ksp-wallet-lib/unit_tests/capability.rs
// version: 1
// version: 2
#[test]
fn capability_variants_are_distinct_and_stable() {
assert_ne!(super::WalletCapability::View, super::WalletCapability::Owner);
assert_eq!(format!("{:?}", super::WalletCapability::View), "View");
assert_eq!(format!("{:?}", super::WalletCapability::Owner), "Owner");
assert_ne!(crate::WalletCapability::View, crate::WalletCapability::Owner);
assert_eq!(format!("{:?}", crate::WalletCapability::View), "View");
assert_eq!(format!("{:?}", crate::WalletCapability::Owner), "Owner");
}

View File

@@ -1,7 +1,7 @@
// file: crates/ksp-wallet-lib/unit_tests/crypto.rs
// version: 1
// version: 2
use base64::Engine as _;
use base64::Engine; // rust-rules: derive-import
const VECTOR: &[u8] = include_bytes!("../tests/fixtures/kspwallet_v1_crypto_vectors.json");
@@ -70,15 +70,15 @@ fn deterministic_argon2id_and_xchacha_wrap_vector_matches_external_canary() -> k
};
assert_eq!(derived.as_bytes(), &expected_derived);
let content = super::SecretKeyV1::from_bytes(content_key);
let wrapped_result = super::wrap_key(&derived, &content, &nonce, aad.as_slice());
let content = crate::SecretKeyV1::from_bytes(content_key);
let wrapped_result = crate::wrap_key(&derived, &content, &nonce, aad.as_slice());
let wrapped = match wrapped_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(wrapped, expected_wrapped);
let unwrapped_result = super::unwrap_key(&derived, &nonce, aad.as_slice(), wrapped.as_slice());
let unwrapped_result = crate::unwrap_key(&derived, &nonce, aad.as_slice(), wrapped.as_slice());
let unwrapped = match unwrapped_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -89,16 +89,16 @@ fn deterministic_argon2id_and_xchacha_wrap_vector_matches_external_canary() -> k
#[test]
fn xchacha_tampering_is_reported_as_generic_authentication_failure() -> ksp_core_lib::Result<()> {
let key = super::SecretKeyV1::from_bytes([0x11_u8; 32]);
let key = crate::SecretKeyV1::from_bytes([0x11_u8; 32]);
let nonce = [0x22_u8; crate::KSPWALLET_V1_XCHACHA_NONCE_BYTES];
let plaintext = [0x33_u8; 32];
let encrypted_result = super::encrypt_bytes(&key, &nonce, b"kspwallet-test-aad", plaintext.as_slice());
let encrypted_result = crate::encrypt_bytes(&key, &nonce, b"kspwallet-test-aad", plaintext.as_slice());
let mut encrypted = match encrypted_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
encrypted[0] ^= 1;
let result = super::decrypt_bytes(&key, &nonce, b"kspwallet-test-aad", encrypted.as_slice());
let result = crate::decrypt_bytes(&key, &nonce, b"kspwallet-test-aad", encrypted.as_slice());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -110,12 +110,12 @@ fn xchacha_tampering_is_reported_as_generic_authentication_failure() -> ksp_core
#[test]
fn secret_key_debug_is_redacted_and_random_sources_are_callable() -> ksp_core_lib::Result<()> {
let key_result = super::SecretKeyV1::random();
let key_result = crate::SecretKeyV1::random();
let key = match key_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let nonce_result = super::random_nonce();
let nonce_result = crate::random_nonce();
let nonce = match nonce_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-wallet-lib/unit_tests/metadata.rs
// version: 1
// version: 2
fn test_pubkey() -> ksp_core_lib::Pubkey {
return ksp_core_lib::PRGIDPK_SOLANA_SYSTEM;
@@ -7,8 +7,8 @@ fn test_pubkey() -> ksp_core_lib::Pubkey {
#[test]
fn authorized_info_exposes_metadata_after_authorization() {
let note = super::WalletNote { id: std::string::String::from("purpose"), text: std::string::String::from("devnet test wallet") };
let info = super::WalletInfo {
let note = crate::WalletNote { id: std::string::String::from("purpose"), text: std::string::String::from("devnet test wallet") };
let info = crate::WalletInfo {
format_version: 1,
capability: crate::WalletCapability::View,
pubkey: test_pubkey(),
@@ -25,11 +25,11 @@ fn authorized_info_exposes_metadata_after_authorization() {
#[test]
fn authorized_info_debug_redacts_alias_and_note_text() {
let note = super::WalletNote {
let note = crate::WalletNote {
id: std::string::String::from("NOTE-ID-CANARY"),
text: std::string::String::from("NOTE-SECRET-CANARY"),
};
let info = super::WalletInfo {
let info = crate::WalletInfo {
format_version: 1,
capability: crate::WalletCapability::Owner,
pubkey: test_pubkey(),
@@ -46,7 +46,7 @@ fn authorized_info_debug_redacts_alias_and_note_text() {
#[test]
fn locked_info_does_not_carry_authorized_identity_or_metadata() {
let info = super::LockedWalletInfo { format_version: 1, view_enabled: true };
let info = crate::LockedWalletInfo { format_version: 1, view_enabled: true };
assert_eq!(info.format_version(), 1);
assert!(info.view_enabled());
let rendered = format!("{info:?}");

View File

@@ -1,9 +1,9 @@
// file: crates/ksp-wallet-lib/unit_tests/password.rs
// version: 1
// version: 2
#[test]
fn view_password_debug_is_redacted() {
let password = super::ViewPassword::new(std::string::String::from("VIEW-SECRET-CANARY"));
let password = crate::ViewPassword::new(std::string::String::from("VIEW-SECRET-CANARY"));
let rendered = format!("{password:?}");
assert_eq!(rendered, "ViewPassword(<redacted>)");
assert!(!rendered.contains("VIEW-SECRET-CANARY"));
@@ -11,7 +11,7 @@ fn view_password_debug_is_redacted() {
#[test]
fn owner_password_debug_is_redacted() {
let password = super::OwnerPassword::new(std::string::String::from("OWNER-SECRET-CANARY"));
let password = crate::OwnerPassword::new(std::string::String::from("OWNER-SECRET-CANARY"));
let rendered = format!("{password:?}");
assert_eq!(rendered, "OwnerPassword(<redacted>)");
assert!(!rendered.contains("OWNER-SECRET-CANARY"));
@@ -19,6 +19,6 @@ fn owner_password_debug_is_redacted() {
#[test]
fn password_wrappers_require_drop_for_zeroization() {
assert!(std::mem::needs_drop::<super::ViewPassword>());
assert!(std::mem::needs_drop::<super::OwnerPassword>());
assert!(std::mem::needs_drop::<crate::ViewPassword>());
assert!(std::mem::needs_drop::<crate::OwnerPassword>());
}

View File

@@ -1,7 +1,7 @@
// file: crates/ksp-wallet-lib/unit_tests/payload.rs
// version: 1
// version: 2
use base64::Engine as _;
use base64::Engine; // rust-rules: derive-import
#[test]
fn metadata_payload_rejects_duplicate_note_identifiers() -> ksp_core_lib::Result<()> {
@@ -18,7 +18,7 @@ fn metadata_payload_rejects_duplicate_note_identifiers() -> ksp_core_lib::Result
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return std::result::Result::Err(test_error("test metadata payload could not be serialized")),
};
let result = super::decode_metadata_payload(encoded.as_slice());
let result = crate::decode_metadata_payload(encoded.as_slice());
let error = match result {
std::result::Result::Ok(_) => return std::result::Result::Err(test_error("duplicate note identifiers unexpectedly parsed")),
std::result::Result::Err(error) => error,

View File

@@ -0,0 +1,86 @@
// file: crates/ksp-wallet-lib/unit_tests/security.rs
// version: 2
//! Adversarial security canaries for native `.kspwallet` V1.
use base64::Engine; // rust-rules: derive-import
const FULL_VECTOR: &[u8] = include_bytes!("../tests/fixtures/kspwallet_v1_full_vector.json");
#[test]
fn owner_signed_regions_reject_canonical_tampering_before_unlock() {
for pointer in [
"/key_slots/0/kdf/salt",
"/key_slots/0/wrap/ciphertext",
"/owner_control/ciphertext",
"/metadata/ciphertext",
"/secret/ciphertext",
"/state_signature/signature",
] {
let tampered = tamper_base64url_field(FULL_VECTOR, pointer);
let error = crate::inspect_locked_wallet_v1(tampered.as_slice()).expect_err("OWNER-signed canonical tampering must be rejected");
assert_eq!(error.code(), crate::ERROR_CODE_AUTHENTICATION_FAILED, "unexpected error code for tampered field {pointer}");
}
}
#[test]
fn owner_signature_verification_precedes_owner_and_view_password_kdf() {
let tampered = tamper_base64url_field(FULL_VECTOR, "/metadata/ciphertext");
let runtime = runtime();
let owner = runtime.block_on(crate::open_wallet_owner_v1(tampered.as_slice(), crate::OwnerPassword::new(std::string::String::new())));
assert_eq!(owner.expect_err("tampered state must fail before an empty OWNER password reaches Argon2").code(), crate::ERROR_CODE_AUTHENTICATION_FAILED);
let view = runtime.block_on(crate::open_wallet_view_v1(tampered.as_slice(), crate::ViewPassword::new(std::string::String::new())));
assert_eq!(view.expect_err("tampered state must fail before an empty VIEW password reaches Argon2").code(), crate::ERROR_CODE_AUTHENTICATION_FAILED);
}
#[test]
fn view_credential_tampering_does_not_forge_owner_state_and_cannot_unlock_view() {
let tampered = tamper_base64url_field(FULL_VECTOR, "/key_slots/1/wrap/ciphertext");
let locked = crate::inspect_locked_wallet_v1(tampered.as_slice()).expect("VIEW wrapping credentials are intentionally outside the OWNER state transcript");
assert!(locked.view_enabled());
let runtime = runtime();
let owner =
runtime.block_on(crate::open_wallet_owner_v1(tampered.as_slice(), crate::OwnerPassword::new(std::string::String::from("pre005-owner-password"))));
assert!(owner.is_ok(), "VIEW credential tampering must not invalidate OWNER unlock");
let view = runtime.block_on(crate::open_wallet_view_v1(tampered.as_slice(), crate::ViewPassword::new(std::string::String::from("pre005-view-password"))));
assert_eq!(view.expect_err("tampered VIEW wrapping must not unlock metadata").code(), crate::ERROR_CODE_VIEW_UNLOCK_FAILED);
}
#[test]
fn unlock_failures_do_not_echo_password_material() {
let owner_canary = "OWNER-PASSWORD-LEAK-CANARY";
let view_canary = "VIEW-PASSWORD-LEAK-CANARY";
let runtime = runtime();
let owner = runtime.block_on(crate::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(std::string::String::from(owner_canary))));
let owner_error = owner.expect_err("wrong OWNER password must fail");
assert_eq!(owner_error.code(), crate::ERROR_CODE_OWNER_UNLOCK_FAILED);
assert!(!owner_error.to_string().contains(owner_canary));
assert!(!format!("{owner_error:?}").contains(owner_canary));
let view = runtime.block_on(crate::open_wallet_view_v1(FULL_VECTOR, crate::ViewPassword::new(std::string::String::from(view_canary))));
let view_error = view.expect_err("wrong VIEW password must fail");
assert_eq!(view_error.code(), crate::ERROR_CODE_VIEW_UNLOCK_FAILED);
assert!(!view_error.to_string().contains(view_canary));
assert!(!format!("{view_error:?}").contains(view_canary));
}
fn tamper_base64url_field(source: &[u8], pointer: &str) -> std::vec::Vec<u8> {
let mut value: serde_json::Value = serde_json::from_slice(source).expect("security fixture must be valid JSON");
let target = value.pointer_mut(pointer).expect("security fixture pointer must exist");
let encoded = target.as_str().expect("security fixture target must be a Base64url string");
let mut decoded = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(encoded.as_bytes()).expect("security fixture Base64url must decode");
let first = decoded.first_mut().expect("security fixture Base64url field must not be empty");
*first ^= 0x01;
*target = serde_json::Value::String(base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(decoded.as_slice()));
zeroize::Zeroize::zeroize(decoded.as_mut_slice());
return serde_json::to_vec(&value).expect("tampered security fixture must serialize");
}
fn runtime() -> tokio::runtime::Runtime {
return tokio::runtime::Builder::new_current_thread().build().expect("security test runtime must be creatable");
}

View File

@@ -1,7 +1,7 @@
// file: crates/ksp-wallet-lib/unit_tests/transcript.rs
// version: 1
// version: 2
use base64::Engine as _;
use base64::Engine; // rust-rules: derive-import
const FIXTURE: &[u8] = include_bytes!("../tests/fixtures/kspwallet_v1_wire_only.json");

View File

@@ -1,7 +1,9 @@
// file: crates/ksp-wallet-lib/unit_tests/transfer.rs
// version: 1
// version: 2
use zeroize::Zeroize as _;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt; // rust-rules: derive-import
use zeroize::Zeroize; // rust-rules: derive-import
fn runtime() -> tokio::runtime::Runtime {
return tokio::runtime::Builder::new_current_thread().build().expect("Wallet transfer test runtime must build");
@@ -234,7 +236,6 @@ fn owner_transfer_file_export_is_no_clobber() {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt as _;
let mode = std::fs::metadata(export_path.as_path()).expect("export metadata must be readable").permissions().mode() & 0o777;
assert_eq!(mode, 0o600);
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-wallet-lib/unit_tests/wallet.rs
// version: 2
// version: 3
const FULL_VECTOR: &[u8] = include_bytes!("../tests/fixtures/kspwallet_v1_full_vector.json");
const FULL_VECTOR_META: &[u8] = include_bytes!("../tests/fixtures/kspwallet_v1_full_vector_meta.json");
@@ -26,7 +26,7 @@ fn externally_generated_full_vector_opens_view_and_owner_independently() -> ksp_
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let view_result = runtime.block_on(super::open_wallet_view_v1(FULL_VECTOR, crate::ViewPassword::new(vector.view_password_utf8)));
let view_result = runtime.block_on(crate::open_wallet_view_v1(FULL_VECTOR, crate::ViewPassword::new(vector.view_password_utf8)));
let view = match view_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -36,7 +36,7 @@ fn externally_generated_full_vector_opens_view_and_owner_independently() -> ksp_
assert_eq!(view.alias(), std::option::Option::Some(vector.expected_alias.as_str()));
assert_note_texts(view.notes(), vector.expected_notes.as_slice());
let owner_result = runtime.block_on(super::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(vector.owner_password_utf8)));
let owner_result = runtime.block_on(crate::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(vector.owner_password_utf8)));
let owner = match owner_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -59,21 +59,21 @@ fn wrong_passwords_do_not_cross_unlock_capabilities() -> ksp_core_lib::Result<()
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let wrong_view = runtime.block_on(super::open_wallet_view_v1(FULL_VECTOR, crate::ViewPassword::new(std::string::String::from("wrong-view-password"))));
let wrong_view = runtime.block_on(crate::open_wallet_view_v1(FULL_VECTOR, crate::ViewPassword::new(std::string::String::from("wrong-view-password"))));
let wrong_view_error = match wrong_view {
std::result::Result::Ok(_) => return std::result::Result::Err(test_error("wrong VIEW password unexpectedly unlocked Wallet")),
std::result::Result::Err(error) => error,
};
assert_eq!(wrong_view_error.code(), crate::ERROR_CODE_VIEW_UNLOCK_FAILED);
let wrong_owner = runtime.block_on(super::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(std::string::String::from("wrong-owner-password"))));
let wrong_owner = runtime.block_on(crate::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(std::string::String::from("wrong-owner-password"))));
let wrong_owner_error = match wrong_owner {
std::result::Result::Ok(_) => return std::result::Result::Err(test_error("wrong OWNER password unexpectedly unlocked Wallet")),
std::result::Result::Err(error) => error,
};
assert_eq!(wrong_owner_error.code(), crate::ERROR_CODE_OWNER_UNLOCK_FAILED);
let view_as_owner = runtime.block_on(super::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(vector.view_password_utf8)));
let view_as_owner = runtime.block_on(crate::open_wallet_owner_v1(FULL_VECTOR, crate::OwnerPassword::new(vector.view_password_utf8)));
let view_as_owner_error = match view_as_owner {
std::result::Result::Ok(_) => return std::result::Result::Err(test_error("VIEW password unexpectedly unlocked OWNER")),
std::result::Result::Err(error) => error,
@@ -88,7 +88,7 @@ fn owner_signed_metadata_tampering_is_rejected_before_unlock() -> ksp_core_lib::
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let inspect_result = super::inspect_locked_wallet_v1(tampered.as_slice());
let inspect_result = crate::inspect_locked_wallet_v1(tampered.as_slice());
let error = match inspect_result {
std::result::Result::Ok(_) => return std::result::Result::Err(test_error("tampered OWNER-signed metadata unexpectedly verified")),
std::result::Result::Err(error) => error,
@@ -107,7 +107,7 @@ fn view_wrap_can_change_without_breaking_owner_authenticated_state() -> ksp_core
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let inspected = match super::inspect_locked_wallet_v1(tampered.as_slice()) {
let inspected = match crate::inspect_locked_wallet_v1(tampered.as_slice()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -117,12 +117,12 @@ fn view_wrap_can_change_without_breaking_owner_authenticated_state() -> ksp_core
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let owner_result = runtime.block_on(super::open_wallet_owner_v1(tampered.as_slice(), crate::OwnerPassword::new(vector.owner_password_utf8)));
let owner_result = runtime.block_on(crate::open_wallet_owner_v1(tampered.as_slice(), crate::OwnerPassword::new(vector.owner_password_utf8)));
if let std::result::Result::Err(error) = owner_result {
return std::result::Result::Err(error);
}
let view_result = runtime.block_on(super::open_wallet_view_v1(tampered.as_slice(), crate::ViewPassword::new(vector.view_password_utf8)));
let view_result = runtime.block_on(crate::open_wallet_view_v1(tampered.as_slice(), crate::ViewPassword::new(vector.view_password_utf8)));
let view_error = match view_result {
std::result::Result::Ok(_) => return std::result::Result::Err(test_error("modified VIEW wrapping unexpectedly unlocked metadata")),
std::result::Result::Err(error) => error,
@@ -147,7 +147,7 @@ fn locked_full_vector_contains_no_authorized_identity_or_metadata_plaintext() ->
for note in vector.expected_notes {
assert!(!document.contains(note.as_str()));
}
let locked = match super::inspect_locked_wallet_v1(FULL_VECTOR) {
let locked = match crate::inspect_locked_wallet_v1(FULL_VECTOR) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -181,7 +181,7 @@ fn create_uses_calibrated_defaults_and_keeps_locked_projection_private() -> ksp_
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let owner_result = runtime.block_on(super::create_wallet_v1(
let owner_result = runtime.block_on(crate::create_wallet_v1(
crate::OwnerPassword::new(std::string::String::from("pre005-create-owner-password")),
std::option::Option::None,
metadata,

View File

@@ -1,18 +1,18 @@
// file: crates/ksp-wallet-lib/unit_tests/wire.rs
// version: 2
// version: 3
const FIXTURE: &[u8] = include_bytes!("../tests/fixtures/kspwallet_v1_wire_only.json");
#[test]
fn strict_v1_fixture_parses_and_round_trips_semantically() -> ksp_core_lib::Result<()> {
let parsed = match super::KspWalletEnvelopeV1::parse_json(FIXTURE) {
let parsed = match crate::KspWalletEnvelopeV1::parse_json(FIXTURE) {
std::result::Result::Ok(parsed) => parsed,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
assert_eq!(parsed.format_version(), crate::KSPWALLET_FORMAT_VERSION_V1);
assert!(parsed.view_descriptor().enabled());
assert_eq!(parsed.owner_slot().role(), super::WalletKeySlotRoleV1::Owner);
assert_eq!(parsed.view_slot().map(super::WalletKeySlotV1::role), std::option::Option::Some(super::WalletKeySlotRoleV1::View));
assert_eq!(parsed.owner_slot().role(), crate::WalletKeySlotRoleV1::Owner);
assert_eq!(parsed.view_slot().map(crate::WalletKeySlotV1::role), std::option::Option::Some(crate::WalletKeySlotRoleV1::View));
assert_eq!(parsed.owner_control().payload_version(), 1);
assert_eq!(parsed.metadata().payload_version(), 1);
assert_eq!(parsed.secret().payload_version(), 1);
@@ -21,7 +21,7 @@ fn strict_v1_fixture_parses_and_round_trips_semantically() -> ksp_core_lib::Resu
std::result::Result::Ok(serialized) => serialized,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let reparsed = match super::KspWalletEnvelopeV1::parse_json(serialized.as_slice()) {
let reparsed = match crate::KspWalletEnvelopeV1::parse_json(serialized.as_slice()) {
std::result::Result::Ok(reparsed) => reparsed,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -32,7 +32,7 @@ fn strict_v1_fixture_parses_and_round_trips_semantically() -> ksp_core_lib::Resu
#[test]
fn unknown_format_version_is_rejected_before_v1_shape_validation() {
let source = std::string::String::from_utf8_lossy(FIXTURE).replace("\"format_version\": 1", "\"format_version\": 2");
let result = super::KspWalletEnvelopeV1::parse_json(source.as_bytes());
let result = crate::KspWalletEnvelopeV1::parse_json(source.as_bytes());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -44,7 +44,7 @@ fn unknown_format_version_is_rejected_before_v1_shape_validation() {
#[test]
fn unknown_top_level_field_is_rejected() {
let source = std::string::String::from_utf8_lossy(FIXTURE).replacen("{", "{\n \"unexpected\": true,", 1);
let result = super::KspWalletEnvelopeV1::parse_json(source.as_bytes());
let result = crate::KspWalletEnvelopeV1::parse_json(source.as_bytes());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -57,7 +57,7 @@ fn unknown_top_level_field_is_rejected() {
fn padded_or_noncanonical_base64url_is_rejected() {
let source = std::string::String::from_utf8_lossy(FIXTURE)
.replace("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8\"", "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=\"");
let result = super::KspWalletEnvelopeV1::parse_json(source.as_bytes());
let result = crate::KspWalletEnvelopeV1::parse_json(source.as_bytes());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -70,7 +70,7 @@ fn padded_or_noncanonical_base64url_is_rejected() {
fn enabled_view_descriptor_must_match_the_view_slot() {
let source =
std::string::String::from_utf8_lossy(FIXTURE).replacen("\"slot_id\": \"ICEiIyQlJicoKSorLC0uLw\"", "\"slot_id\": \"EBESExQVFhcYGRobHB0eHw\"", 1);
let result = super::KspWalletEnvelopeV1::parse_json(source.as_bytes());
let result = crate::KspWalletEnvelopeV1::parse_json(source.as_bytes());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -82,7 +82,7 @@ fn enabled_view_descriptor_must_match_the_view_slot() {
#[test]
fn zero_or_pathological_kdf_parameters_are_rejected_before_crypto() {
let zero_source = std::string::String::from_utf8_lossy(FIXTURE).replacen("\"memory_kib\": 65536", "\"memory_kib\": 0", 1);
let zero_result = super::KspWalletEnvelopeV1::parse_json(zero_source.as_bytes());
let zero_result = crate::KspWalletEnvelopeV1::parse_json(zero_source.as_bytes());
assert!(zero_result.is_err());
let zero_error = match zero_result {
std::result::Result::Err(error) => error,
@@ -91,7 +91,7 @@ fn zero_or_pathological_kdf_parameters_are_rejected_before_crypto() {
assert_eq!(zero_error.code(), crate::ERROR_CODE_CRYPTO_PARAMETERS_INVALID);
let high_source = std::string::String::from_utf8_lossy(FIXTURE).replacen("\"memory_kib\": 65536", "\"memory_kib\": 1048577", 1);
let high_result = super::KspWalletEnvelopeV1::parse_json(high_source.as_bytes());
let high_result = crate::KspWalletEnvelopeV1::parse_json(high_source.as_bytes());
assert!(high_result.is_err());
let high_error = match high_result {
std::result::Result::Err(error) => error,
@@ -107,7 +107,7 @@ fn argon2_memory_must_cover_all_lanes_before_crypto() {
"\"parallelism\": 2",
1,
);
let result = super::KspWalletEnvelopeV1::parse_json(source.as_bytes());
let result = crate::KspWalletEnvelopeV1::parse_json(source.as_bytes());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -119,7 +119,7 @@ fn argon2_memory_must_cover_all_lanes_before_crypto() {
#[test]
fn oversized_document_is_rejected_before_json_or_crypto() {
let oversized = std::vec![b' '; crate::KSPWALLET_MAX_FILE_BYTES + 1];
let result = super::KspWalletEnvelopeV1::parse_json(oversized.as_slice());
let result = crate::KspWalletEnvelopeV1::parse_json(oversized.as_slice());
assert!(result.is_err());
let error = match result {
std::result::Result::Err(error) => error,
@@ -130,7 +130,7 @@ fn oversized_document_is_rejected_before_json_or_crypto() {
#[test]
fn envelope_debug_does_not_render_ciphertext_contents() -> ksp_core_lib::Result<()> {
let parsed = match super::KspWalletEnvelopeV1::parse_json(FIXTURE) {
let parsed = match crate::KspWalletEnvelopeV1::parse_json(FIXTURE) {
std::result::Result::Ok(parsed) => parsed,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};