services_hardening_provider_verification.rs (5909B)
1 #![forbid(unsafe_code)] 2 3 use serde_json::json; 4 5 const CONTRACT: &str = 6 include_str!("../contracts/services_hardening/provider_verification.v1.json"); 7 const LIB_SOURCE: &str = include_str!("../src/lib.rs"); 8 const VERIFICATION_SOURCE: &str = include_str!("../src/provider_verification.rs"); 9 const TRANSPORT_SOURCE: &str = include_str!("../src/provider_local_signer.rs"); 10 11 #[test] 12 fn machine_contract_freezes_independent_provider_verification() { 13 let actual: serde_json::Value = serde_json::from_str(CONTRACT).expect("contract JSON"); 14 assert_eq!( 15 actual, 16 json!({ 17 "schema": "radroots.myc.provider-verification", 18 "schema_version": 1, 19 "provider_contract_version": 1, 20 "local_signer_transport_contract_version": 1, 21 "observation_time": { 22 "source": "injected", 23 "minimum_unix_ms": 1, 24 "maximum_unix_ms": 9223372036854775807_i64 25 }, 26 "verification_order": [ 27 "configured_binding", "absolute_deadline", "outer_correlation", 28 "response_envelope_binding", "result_shape", "semantic_result" 29 ], 30 "response_binding": [ 31 "contract_version", "provider_instance", "role", "operation_id", 32 "correlation_id", "absolute_deadline_unix_ms", "expected_identity", 33 "capability" 34 ], 35 "describe": { 36 "identity": "exact_expected", 37 "protocol_version": 1, 38 "capabilities": "closed_unique_contains_role_requirements", 39 "maximum_request_bytes": "exact_configured_limit" 40 }, 41 "public_identity": "exact_expected", 42 "sign_event": [ 43 "canonical_unsigned_json", "exact_unsigned_fields", "exact_expected_author", 44 "computed_event_id", "valid_schnorr_signature", "canonical_signed_json", 45 "retain_exact_verified_bytes" 46 ], 47 "nip04": { 48 "direction": "exact_result_tag", 49 "peer": "exact_echo", 50 "ciphertext": "canonical_base64_aes_cbc_shape", 51 "encrypt_length": "exact_plaintext_padding_length", 52 "decrypt_length": "less_than_ciphertext_block_capacity" 53 }, 54 "nip44": { 55 "direction": "exact_result_tag", 56 "peer": "exact_echo", 57 "version": 2, 58 "plaintext_max_bytes": 65_408, 59 "ciphertext": "canonical_base64_v2_shape", 60 "encrypt_length": "exact_v2_plaintext_padding_length", 61 "decrypt_length": "bounded_by_ciphertext_padding_capacity" 62 }, 63 "semantic_output_max_bytes": 1_048_576, 64 "verified_result_sealed": true, 65 "verified_result_serializable": false, 66 "safe_errors_source_free": true, 67 "late_result_usable": false, 68 "ambiguous_result_is_publication": false, 69 "signing_is_publication": false, 70 "database_transaction_allowed": false, 71 "provider_execution_allowed": false 72 }) 73 ); 74 } 75 76 #[test] 77 fn implementation_rebinds_every_response_before_semantic_use() { 78 for required in [ 79 "observed_at.get() > operation.deadline().get()", 80 "parts.outer_correlation_id.as_ref() != expected_correlation_id", 81 "response.operation_id != expected_operation_id", 82 "response.correlation_id != expected_correlation_id", 83 "response.expected_identity != operation.expected_identity().as_hex()", 84 "response.capability != WireCapability::from(operation.input().capability())", 85 "verify_peer(operation, &peer)?", 86 "event.verify().is_err()", 87 "canonical_event.as_slice() != payload.as_slice()", 88 "VerifiedProviderResult::SignedEvent(payload)", 89 "verify_nip04_ciphertext", 90 "verify_nip44_ciphertext", 91 ] { 92 assert!( 93 VERIFICATION_SOURCE.contains(required), 94 "missing verifier {required}" 95 ); 96 } 97 assert!(TRANSPORT_SOURCE.contains("pub(crate) struct LocalSignerUntrustedParts")); 98 } 99 100 #[test] 101 fn verified_boundary_is_sealed_redacted_and_not_publication() { 102 for required in [ 103 "pub struct MycVerifiedProviderResponse", 104 "pub struct MycProviderResponseObservedAtUnixMs", 105 "pub enum MycProviderVerificationErrorKind", 106 "pub struct MycProviderVerificationError", 107 ".field(\"result\", &\"[redacted]\")", 108 "impl Error for MycProviderVerificationError {}", 109 ] { 110 assert!(VERIFICATION_SOURCE.contains(required)); 111 } 112 for forbidden in [ 113 "pub result:", 114 "pub payload:", 115 "pub outer_correlation_id:", 116 "pub fn into_inner", 117 "pub fn raw_response", 118 "impl Serialize for MycVerifiedProviderResponse", 119 "pub const fn signed_event", 120 "ServiceSqliteTransaction", 121 "publish(", 122 "nostr_sdk", 123 ] { 124 assert!(!VERIFICATION_SOURCE.contains(forbidden)); 125 } 126 assert!(LIB_SOURCE.contains("mod provider_verification;")); 127 assert!(!LIB_SOURCE.contains("pub mod provider_verification")); 128 } 129 130 #[test] 131 fn peer_and_nip44_version_are_mandatory_response_evidence() { 132 let response = TRANSPORT_SOURCE 133 .split("pub(crate) enum WireProviderResult") 134 .nth(1) 135 .expect("response result enum"); 136 for variant in [ 137 "Nip04Encrypt", 138 "Nip04Decrypt", 139 "Nip44Encrypt", 140 "Nip44Decrypt", 141 ] { 142 assert!( 143 response.contains(&format!("{variant} {{\n peer: String,")), 144 "missing peer echo on {variant}" 145 ); 146 } 147 assert!(VERIFICATION_SOURCE.contains("version != requested_version.as_u8()")); 148 assert!(VERIFICATION_SOURCE.contains("decoded.first().copied() != Some(version.as_u8())")); 149 }