rings_core/session/
model.rs1use serde::Deserialize;
2use serde::Serialize;
3
4use super::Account;
5use crate::dht::Did;
6use crate::ecc::keys::AccountVerifier;
7use crate::ecc::keys::VerificationPublicKey;
8use crate::ecc::signers;
9use crate::ecc::PublicKey;
10use crate::error::Error;
11use crate::error::Result;
12use crate::utils;
13
14pub(super) fn pack_session(session_id: Did, ts_ms: u128, ttl_ms: u64) -> String {
15 format!("{session_id}\n{ts_ms}\n{ttl_ms}")
16}
17
18#[derive(Deserialize, Serialize, PartialEq, Eq, Debug, Clone)]
20pub struct Session {
21 pub(super) session_id: Did,
23 pub(super) account: Account,
25 pub(super) ttl_ms: u64,
27 pub(super) ts_ms: u128,
29 pub(super) sig: Vec<u8>,
31}
32
33impl Session {
34 pub fn pack(&self) -> Vec<u8> {
36 pack_session(self.session_id, self.ts_ms, self.ttl_ms)
37 .as_bytes()
38 .to_vec()
39 }
40
41 pub fn session_did(&self) -> Did {
43 self.session_id
44 }
45
46 pub fn is_expired(&self) -> bool {
48 let now = utils::get_epoch_ms();
49 now > self.ts_ms + self.ttl_ms as u128
50 }
51
52 pub fn verify_self(&self) -> Result<()> {
54 if self.is_expired() {
55 return Err(Error::SessionExpired);
56 }
57
58 let auth_bytes = self.pack();
59 if !self
60 .account
61 .account_verifier()
62 .verify(&auth_bytes, &self.sig)
63 {
64 return Err(Error::VerifySignatureFailed);
65 }
66 Ok(())
67 }
68
69 pub fn verify(&self, msg: &[u8], sig: impl AsRef<[u8]>) -> Result<()> {
71 self.verify_self()?;
72 if !signers::secp256k1::verify(msg, &self.session_id, sig) {
73 return Err(Error::VerifySignatureFailed);
74 }
75 Ok(())
76 }
77
78 pub fn account_pubkey(&self) -> Result<PublicKey<33>> {
82 match self.account_verification_pubkey()? {
83 VerificationPublicKey::Secp256k1(pk)
84 | VerificationPublicKey::Eip191(pk)
85 | VerificationPublicKey::Bip137(pk) => Ok(pk),
86 VerificationPublicKey::Secp256r1(_)
87 | VerificationPublicKey::Ed25519(_)
88 | VerificationPublicKey::Bls12381(_) => Err(Error::UnknownAccount),
89 }
90 }
91
92 pub fn account_verification_pubkey(&self) -> Result<VerificationPublicKey> {
94 self.account
95 .account_verifier()
96 .verification_key_from_signature(&self.pack(), &self.sig)
97 }
98
99 pub fn account_verifier(&self) -> AccountVerifier {
101 self.account.account_verifier()
102 }
103
104 pub fn account_did(&self) -> Did {
106 self.account.account_verifier().did()
107 }
108}