Fix DID derivation and signature generation. #1

fix: fix did derivation and signature generation.

This fixes two bugs that were affecting did derivation and signature generation.

  • The UnsignedOperation and Operation types were not serializing prev as null and were instead skipping serialization when it was None.
  • The DID was being calculated from the hash of the JSON encoding instead of the CBOR encoding.

Note that there is still an issue with using p256 keys. For some reason the did:key serialization for p256 keys is the wrong length.

Changed files
+6 -8
src
+3 -3
src/builder.rs
··· 3 3 use crate::crypto::SigningKey; 4 4 use crate::did::Did; 5 5 use crate::document::ServiceEndpoint; 6 - use crate::encoding::{base32_encode, sha256}; 6 + use crate::encoding::{base32_encode, dag_cbor_encode, sha256}; 7 7 use crate::error::{PlcError, Result}; 8 8 use crate::operations::{Operation, UnsignedOperation}; 9 9 use crate::validation::{ ··· 229 229 230 230 // The DID is derived from the CID by taking the hash portion 231 231 // For simplicity, we'll hash the entire serialized operation 232 - let serialized = serde_json::to_vec(operation) 233 - .map_err(|e| PlcError::DagCborError(e.to_string()))?; 232 + let serialized = 233 + dag_cbor_encode(operation).map_err(|e| PlcError::DagCborError(e.to_string()))?; 234 234 235 235 let hash = sha256(&serialized); 236 236 let encoded = base32_encode(&hash);
+3 -5
src/operations.rs
··· 30 30 services: HashMap<String, ServiceEndpoint>, 31 31 32 32 /// Previous operation CID (null for genesis) 33 - #[serde(skip_serializing_if = "Option::is_none")] 34 33 prev: Option<String>, 35 34 36 35 /// Base64url-encoded signature ··· 193 192 services: services.clone(), 194 193 prev: prev.clone(), 195 194 }, 196 - Operation::PlcTombstone { prev, .. } => UnsignedOperation::PlcTombstone { 197 - prev: prev.clone(), 198 - }, 195 + Operation::PlcTombstone { prev, .. } => { 196 + UnsignedOperation::PlcTombstone { prev: prev.clone() } 197 + } 199 198 Operation::LegacyCreate { 200 199 signing_key, 201 200 recovery_key, ··· 247 246 services: HashMap<String, ServiceEndpoint>, 248 247 249 248 /// CID of previous operation (None for genesis) 250 - #[serde(skip_serializing_if = "Option::is_none")] 251 249 prev: Option<String>, 252 250 }, 253 251