A library for ATProtocol identities.

feature: updating record signature and verification to reflect current proposal

Signed-off-by: Nick Gerakines <nick.gerakines@gmail.com>

Changed files
+18 -11
crates
atproto-record
+1 -1
Cargo.lock
··· 259 259 dependencies = [ 260 260 "anyhow", 261 261 "atproto-identity", 262 + "base64", 262 263 "chrono", 263 264 "clap", 264 265 "ecdsa", 265 266 "k256", 266 - "multibase", 267 267 "p256", 268 268 "serde", 269 269 "serde_ipld_dagcbor",
+4 -4
crates/atproto-record/Cargo.toml
··· 19 19 test = false 20 20 bench = false 21 21 doc = true 22 - required-features = ["clap"] 22 + required-features = ["clap", "tokio"] 23 23 24 24 [[bin]] 25 25 name = "atproto-record-verify" 26 26 test = false 27 27 bench = false 28 28 doc = true 29 - required-features = ["clap"] 29 + required-features = ["clap", "tokio"] 30 30 31 31 [dependencies] 32 32 atproto-identity.workspace = true ··· 34 34 anyhow.workspace = true 35 35 ecdsa.workspace = true 36 36 k256.workspace = true 37 - multibase.workspace = true 37 + base64.workspace = true 38 38 p256.workspace = true 39 39 serde_ipld_dagcbor.workspace = true 40 40 serde_json.workspace = true ··· 42 42 thiserror.workspace = true 43 43 tracing.workspace = true 44 44 45 - tokio = {workspace = true} 45 + tokio = { workspace = true, optional = true } 46 46 chrono = {version = "0.4.41", default-features = false, features = ["std", "now"]} 47 47 clap = { workspace = true, optional = true } 48 48
+1 -1
crates/atproto-record/src/errors.rs
··· 112 112 #[error("error-atproto-record-verification-10 Signature decoding failed: {error}")] 113 113 SignatureDecodingFailed { 114 114 /// The underlying multibase decoding error 115 - error: multibase::Error, 115 + error: base64::DecodeError, 116 116 }, 117 117 118 118 /// Error when cryptographic signature validation fails.
+12 -5
crates/atproto-record/src/signature.rs
··· 5 5 6 6 use atproto_identity::key::{KeyData, sign, validate}; 7 7 use serde_json::json; 8 + use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD}; 8 9 9 10 use crate::errors::VerificationError; 10 11 ··· 59 60 if let Some(record_map) = sig.as_object_mut() { 60 61 record_map.insert("repository".to_string(), json!(repository)); 61 62 record_map.insert("collection".to_string(), json!(collection)); 63 + record_map.insert("$type".to_string(), json!("community.lexicon.attestation.signature")); 62 64 } 63 65 64 66 // Create a copy of the record with the $sig object for signing. ··· 69 71 record_map.insert("$sig".to_string(), sig); 70 72 } 71 73 74 + { 75 + let thing = serde_json::to_string_pretty(&signing_record).expect("yeah"); 76 + println!("{}", &thing); 77 + } 78 + 72 79 // Create a signature. 73 80 let serialized_signing_record = serde_ipld_dagcbor::to_vec(&signing_record)?; 74 81 75 - let signature = sign(key_data, &serialized_signing_record)?; 76 - let encoded_signature = multibase::encode(multibase::Base::Base64Url, &signature); 82 + let signature: Vec<u8> = sign(key_data, &serialized_signing_record)?; 83 + let encoded_signature = URL_SAFE_NO_PAD.encode(&signature); 77 84 78 85 // Compose the proof object 79 86 let mut proof = signature_object.clone(); 80 87 if let Some(record_map) = proof.as_object_mut() { 81 88 record_map.remove("repository"); 82 89 record_map.remove("collection"); 83 - record_map.insert("signature".to_string(), json!(encoded_signature)); 90 + record_map.insert("signature".to_string(), json!({"$bytes": json!(encoded_signature)})); 91 + record_map.insert("$type".to_string(), json!("community.lexicon.attestation.signature")); 84 92 } 85 93 86 94 // Add the signature to the original record ··· 176 184 let serialized_record = serde_ipld_dagcbor::to_vec(&signed_record) 177 185 .map_err(|error| VerificationError::RecordSerializationFailed { error })?; 178 186 179 - let (_, signature_bytes) = multibase::decode(signature_value) 180 - .map_err(|error| VerificationError::SignatureDecodingFailed { error })?; 187 + let signature_bytes = URL_SAFE_NO_PAD.decode(&signature_value).map_err(|error| VerificationError::SignatureDecodingFailed { error })?; 181 188 182 189 validate(key_data, &signature_bytes, &serialized_record) 183 190 .map_err(|error| VerificationError::CryptographicValidationFailed { error })?;