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}