Phase 1.2: SMB3 encryption negotiation + session state

- Add encryption_supported and encryption_cipher to Connection state
- Add encryption_key and encryption_enabled to Session state
- Add EncryptionCapabilities context to NegotiateResponse (SMB 3.1.1)
- Derive encryption_key from session_base_key in session_setup
- Export derive_encryption_key as public method
- Fix Session::new() signature with 8 parameters
- All encryption tests pass (3 passed)
This commit is contained in:
Warren
2026-06-22 02:56:02 +08:00
parent 104e7f5f9c
commit 98239c09d4
6 changed files with 56 additions and 4 deletions
+15
View File
@@ -7,6 +7,7 @@ use std::sync::{Arc, Mutex};
use crate::proto::auth::ntlm::{Identity, NtlmServer};
use crate::proto::crypto::{PreauthIntegrity, SigningAlgo};
use crate::proto::crypto::encryption::CipherAlgorithm;
use crate::proto::messages::{Dialect, FileId};
use tokio::sync::{mpsc, RwLock};
use uuid::Uuid;
@@ -40,6 +41,10 @@ pub struct Connection {
/// Granted at NEGOTIATE: large MTU support flag etc.
pub max_read_size: tokio::sync::RwLock<u32>,
pub max_write_size: tokio::sync::RwLock<u32>,
/// SMB3 encryption support (negotiated in NEGOTIATE)
pub encryption_supported: tokio::sync::RwLock<bool>,
pub encryption_cipher: tokio::sync::RwLock<Option<CipherAlgorithm>>,
/// Sessions keyed by SessionId.
pub sessions: RwLock<HashMap<u64, Arc<RwLock<Session>>>>,
@@ -72,6 +77,8 @@ impl Connection {
preauth: Mutex::new(PreauthIntegrity::new()),
max_read_size: tokio::sync::RwLock::new(max_read_size),
max_write_size: tokio::sync::RwLock::new(max_write_size),
encryption_supported: tokio::sync::RwLock::new(false),
encryption_cipher: tokio::sync::RwLock::new(None),
sessions: RwLock::new(HashMap::new()),
pending_auths: RwLock::new(HashMap::new()),
session_preauth: RwLock::new(HashMap::new()),
@@ -220,8 +227,12 @@ pub struct Session {
pub identity: Identity,
pub session_base_key: [u8; 16],
pub signing_key: [u8; 16],
/// SMB3 encryption key (derived from session_base_key)
pub encryption_key: Option<[u8; 16]>,
/// Whether signing is required for this session's traffic.
pub signing_required: bool,
/// Whether encryption is enabled for this session
pub encryption_enabled: bool,
pub trees: RwLock<HashMap<u32, Arc<RwLock<TreeConnect>>>>,
/// 3.1.1: snapshot taken at SESSION_SETUP completion (after the request
/// hash but before the response is hashed). Used as KDF context.
@@ -236,7 +247,9 @@ impl Session {
identity: Identity,
session_base_key: [u8; 16],
signing_key: [u8; 16],
encryption_key: Option<[u8; 16]>,
signing_required: bool,
encryption_enabled: bool,
preauth_snapshot: Option<[u8; 64]>,
) -> Self {
Self {
@@ -244,7 +257,9 @@ impl Session {
identity,
session_base_key,
signing_key,
encryption_key,
signing_required,
encryption_enabled,
trees: RwLock::new(HashMap::new()),
preauth_snapshot,
next_tree_id: AtomicU32::new(1),