Implemented message decoding

This commit is contained in:
Daniel Sanchez Quiros 2022-10-07 13:09:31 +02:00
parent 7cecb74224
commit c8a1d42308
4 changed files with 87 additions and 2 deletions

63
waku/src/decrypt.rs Normal file
View File

@ -0,0 +1,63 @@
// std
use std::ffi::{CStr, CString};
// crates
use aes_gcm::{Aes256Gcm, Key};
use libsecp256k1::SecretKey;
// internal
use crate::general::{DecodedPayload, JsonResponse, Result, WakuMessage};
/// Decrypt a message using a symmetric key
///
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_decode_symmetricchar-messagejson-char-symmetrickey)
pub fn waku_decode_symmetric(
message: &WakuMessage,
symmetric_key: &Key<Aes256Gcm>,
) -> Result<DecodedPayload> {
let symk = hex::encode(symmetric_key.as_slice());
let result = unsafe {
CStr::from_ptr(waku_sys::waku_decode_symmetric(
CString::new(
serde_json::to_string(&message)
.expect("WakuMessages should always be able to success serializing"),
)
.expect("CString should build properly from the serialized waku message")
.into_raw(),
CString::new(symk)
.expect("CString should build properly from hex encoded symmetric key")
.into_raw(),
))
}
.to_str()
.expect("Response should always succeed to load to a &str");
let response: JsonResponse<DecodedPayload> =
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
response.into()
}
/// Decrypt a message using a symmetric key
///
/// As per the [specification](extern char* waku_decode_asymmetric(char* messageJson, char* privateKey))
pub fn waku_decode_asymmetric(
message: &WakuMessage,
asymmetric_key: &SecretKey,
) -> Result<DecodedPayload> {
let sk = hex::encode(asymmetric_key.serialize());
let result = unsafe {
CStr::from_ptr(waku_sys::waku_decode_asymmetric(
CString::new(
serde_json::to_string(&message)
.expect("WakuMessages should always be able to success serializing"),
)
.expect("CString should build properly from the serialized waku message")
.into_raw(),
CString::new(sk)
.expect("CString should build properly from hex encoded symmetric key")
.into_raw(),
))
}
.to_str()
.expect("Response should always succeed to load to a &str");
let response: JsonResponse<DecodedPayload> =
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
response.into()
}

View File

@ -4,9 +4,12 @@
use std::fmt::{Display, Formatter};
use std::str::FromStr;
// crates
use aes_gcm::{Aes256Gcm, Key};
use libsecp256k1::SecretKey;
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use sscanf::{scanf, RegexRepresentation};
// internal
use crate::decrypt::{waku_decode_asymmetric, waku_decode_symmetric};
pub type WakuMessageVersion = usize;
/// Base58 encoded peer id
@ -36,7 +39,7 @@ impl<T> From<JsonResponse<T>> for Result<T> {
}
}
/// JsonMessage, Waku message in JSON format.
/// Waku message in JSON format.
/// as per the [specification](https://rfc.vac.dev/spec/36/#jsonmessage-type)
#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -50,7 +53,25 @@ pub struct WakuMessage {
timestamp: usize,
}
impl WakuMessage {
/// Try decode the message with an expected symmetric key
///
/// wrapper around [`crate::decrypt::waku_decode_symmetric`]
pub fn try_decode_symmetric(&self, symmetric_key: &Key<Aes256Gcm>) -> Result<DecodedPayload> {
waku_decode_symmetric(self, symmetric_key)
}
/// Try decode the message with an expected asymmetric key
///
/// wrapper around [`crate::decrypt::waku_decode_asymmetric`]
pub fn try_decode_asymmentric(&self, asymmetric_key: &SecretKey) -> Result<DecodedPayload> {
waku_decode_asymmetric(self, asymmetric_key)
}
}
/// A payload once decoded, used when a received Waku Message is encrypted
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DecodedPayload {
/// Public key that signed the message (optional), hex encoded with 0x prefix
public_key: Option<String>,

View File

@ -1,3 +1,4 @@
mod decrypt;
mod events;
mod general;
mod node;

View File

@ -7,7 +7,7 @@ use std::time::Duration;
// internal
use crate::general::Result;
use crate::general::{FilterSubscription, JsonResponse, MessageId, PeerId};
use crate::general::{FilterSubscription, JsonResponse, PeerId};
/// Creates a subscription in a lightnode for messages that matches a content filter and optionally a [`WakuPubSubTopic`](`crate::general::WakuPubSubTopic`)
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_filter_subscribechar-filterjson-char-peerid-int-timeoutms)