Skip to main content

bsv/auth/
types.rs

1//! Core types for the auth module.
2//!
3//! Defines AuthMessage, MessageType, PeerSession, protocol constants,
4//! and the RequestedCertificateSet type alias.
5
6use std::collections::HashMap;
7
8// ---------------------------------------------------------------------------
9// Protocol Constants
10// ---------------------------------------------------------------------------
11
12/// Auth protocol version.
13pub const AUTH_VERSION: &str = "0.1";
14
15/// Protocol ID used for signing auth messages.
16pub const AUTH_PROTOCOL_ID: &str = "auth message signature";
17
18/// Protocol ID used for signing certificates.
19pub const CERTIFICATE_SIGNATURE_PROTOCOL: &str = "certificate signature";
20
21/// Protocol ID used for encrypting certificate fields.
22pub const CERTIFICATE_FIELD_ENCRYPTION_PROTOCOL: &str = "certificate field encryption";
23
24/// Protocol ID used for HMAC-based nonce operations.
25pub const SERVER_HMAC_PROTOCOL: &str = "server hmac";
26
27/// Security level used for nonce HMAC operations.
28pub const NONCE_SECURITY_LEVEL: u8 = 2;
29
30// ---------------------------------------------------------------------------
31// MessageType
32// ---------------------------------------------------------------------------
33
34/// The type of an authentication protocol message.
35#[derive(Clone, Debug, PartialEq)]
36#[cfg_attr(feature = "network", derive(serde::Serialize, serde::Deserialize))]
37pub enum MessageType {
38    /// Initial authentication request from client to server.
39    #[cfg_attr(feature = "network", serde(rename = "initialRequest"))]
40    InitialRequest,
41    /// Response to an initial authentication request.
42    #[cfg_attr(feature = "network", serde(rename = "initialResponse"))]
43    InitialResponse,
44    /// Request for certificates from the peer.
45    #[cfg_attr(feature = "network", serde(rename = "certificateRequest"))]
46    CertificateRequest,
47    /// Response containing requested certificates.
48    #[cfg_attr(feature = "network", serde(rename = "certificateResponse"))]
49    CertificateResponse,
50    /// General authenticated message after handshake is complete.
51    #[cfg_attr(feature = "network", serde(rename = "general"))]
52    General,
53}
54
55// ---------------------------------------------------------------------------
56// RequestedCertificateSet
57// ---------------------------------------------------------------------------
58
59/// A set of certificates being requested from a peer.
60///
61/// Matches the TS SDK's RequestedCertificateSet wire format:
62/// `{ certifiers: string[], types: { [certTypeBase64]: string[] } }`
63#[derive(Clone, Debug, Default)]
64#[cfg_attr(feature = "network", derive(serde::Serialize, serde::Deserialize))]
65pub struct RequestedCertificateSet {
66    /// Certifier public keys whose certificates are accepted.
67    #[cfg_attr(feature = "network", serde(default))]
68    pub certifiers: Vec<String>,
69    /// Maps certificate type (base64) to the list of field names to request.
70    #[cfg_attr(feature = "network", serde(default))]
71    pub types: HashMap<String, Vec<String>>,
72}
73
74impl RequestedCertificateSet {
75    /// Returns true if no certificate types are requested.
76    pub fn is_empty(&self) -> bool {
77        self.types.is_empty()
78    }
79
80    /// Iterate over the requested certificate type keys.
81    pub fn keys(&self) -> impl Iterator<Item = &String> {
82        self.types.keys()
83    }
84
85    /// Check if a certificate type is in the requested set.
86    pub fn contains_key(&self, key: &str) -> bool {
87        self.types.contains_key(key)
88    }
89
90    /// Get the requested fields for a certificate type.
91    pub fn get(&self, key: &str) -> Option<&Vec<String>> {
92        self.types.get(key)
93    }
94
95    /// Insert a certificate type and its requested fields.
96    pub fn insert(&mut self, key: String, fields: Vec<String>) {
97        self.types.insert(key, fields);
98    }
99}
100
101// ---------------------------------------------------------------------------
102// AuthMessage
103// ---------------------------------------------------------------------------
104
105/// A message in the BRC-31 Authrite authentication protocol.
106///
107/// All fields match the TS SDK AuthMessage format for wire compatibility.
108#[derive(Clone, Debug)]
109#[cfg_attr(feature = "network", derive(serde::Serialize, serde::Deserialize))]
110#[cfg_attr(feature = "network", serde(rename_all = "camelCase"))]
111pub struct AuthMessage {
112    /// Protocol version string.
113    pub version: String,
114
115    /// The type of this message.
116    pub message_type: MessageType,
117
118    /// Compressed hex public key of the sender.
119    pub identity_key: String,
120
121    /// Base64-encoded nonce created by the sender.
122    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
123    pub nonce: Option<String>,
124
125    /// The other party's nonce (echoed back in responses).
126    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
127    pub your_nonce: Option<String>,
128
129    /// For general messages, references the session's initial nonce.
130    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
131    pub initial_nonce: Option<String>,
132
133    /// Certificates to share with the peer.
134    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
135    pub certificates: Option<Vec<crate::wallet::interfaces::Certificate>>,
136
137    /// Certificate types and fields being requested from the peer.
138    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
139    pub requested_certificates: Option<RequestedCertificateSet>,
140
141    /// General message payload bytes.
142    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
143    pub payload: Option<Vec<u8>>,
144
145    /// ECDSA signature over the message.
146    #[cfg_attr(feature = "network", serde(skip_serializing_if = "Option::is_none"))]
147    pub signature: Option<Vec<u8>>,
148}
149
150// ---------------------------------------------------------------------------
151// PeerSession
152// ---------------------------------------------------------------------------
153
154/// Tracks the state of an authenticated session with a peer.
155#[derive(Clone, Debug)]
156pub struct PeerSession {
157    /// The nonce that identifies this session.
158    pub session_nonce: String,
159    /// The peer's compressed hex identity key.
160    pub peer_identity_key: String,
161    /// The peer's nonce for this session.
162    pub peer_nonce: String,
163    /// Whether the handshake has completed successfully.
164    pub is_authenticated: bool,
165}