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:
27
vendor/smb-server/src/handlers/negotiate.rs
vendored
27
vendor/smb-server/src/handlers/negotiate.rs
vendored
@@ -4,10 +4,11 @@ use std::sync::Arc;
|
||||
|
||||
use crate::proto::auth::spnego::encode_init_response;
|
||||
use crate::proto::crypto::SigningAlgo;
|
||||
use crate::proto::crypto::encryption::CipherAlgorithm;
|
||||
use crate::proto::header::Smb2Header;
|
||||
use crate::proto::messages::{
|
||||
Dialect, NegotiateContext, NegotiateRequest, NegotiateResponse, PreauthIntegrityCapabilities,
|
||||
SigningCapabilities,
|
||||
SigningCapabilities, EncryptionCapabilities,
|
||||
};
|
||||
use tracing::info;
|
||||
use uuid::Uuid;
|
||||
@@ -117,7 +118,29 @@ pub async fn handle(
|
||||
data: signing_data,
|
||||
};
|
||||
|
||||
let ctxs = vec![preauth_ctx, signing_ctx];
|
||||
// ENCRYPTION_CAPABILITIES — advertise AES-128-GCM (simplified)
|
||||
let encryption_caps = EncryptionCapabilities {
|
||||
cipher_count: 1,
|
||||
ciphers: vec![EncryptionCapabilities::CIPHER_AES_128_GCM],
|
||||
};
|
||||
let encryption_data = {
|
||||
use binrw::BinWrite;
|
||||
let mut c = std::io::Cursor::new(Vec::new());
|
||||
BinWrite::write(&encryption_caps, &mut c).expect("encryption negotiate context encodes");
|
||||
c.into_inner()
|
||||
};
|
||||
let encryption_ctx = NegotiateContext {
|
||||
context_type: NegotiateContext::TYPE_ENCRYPTION,
|
||||
data_length: encryption_data.len() as u16,
|
||||
reserved: 0,
|
||||
data: encryption_data,
|
||||
};
|
||||
|
||||
// Store encryption support in connection state
|
||||
*conn.encryption_supported.write().await = true;
|
||||
*conn.encryption_cipher.write().await = Some(CipherAlgorithm::Aes128Gcm);
|
||||
|
||||
let ctxs = vec![preauth_ctx, signing_ctx, encryption_ctx];
|
||||
if let Err(e) = NegotiateContext::encode_list(&ctxs, &mut contexts_bytes) {
|
||||
tracing::error!(error = %e, "encode_list failed");
|
||||
return HandlerResponse::err(ntstatus::STATUS_INVALID_PARAMETER);
|
||||
|
||||
14
vendor/smb-server/src/handlers/session_setup.rs
vendored
14
vendor/smb-server/src/handlers/session_setup.rs
vendored
@@ -198,13 +198,27 @@ pub async fn handle(
|
||||
0
|
||||
};
|
||||
let signing_required = false;
|
||||
|
||||
// Check if encryption is negotiated
|
||||
let encryption_supported = *conn.encryption_supported.read().await;
|
||||
let encryption_cipher = *conn.encryption_cipher.read().await;
|
||||
let encryption_enabled = encryption_supported && encryption_cipher.is_some();
|
||||
let encryption_key = if encryption_enabled {
|
||||
// Derive encryption key from session_base_key (simplified approach)
|
||||
use crate::proto::crypto::encryption::Smb3Encryption;
|
||||
Some(Smb3Encryption::derive_encryption_key(&session_base_key, b"SMB3ENC"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let session = Session::new(
|
||||
sid,
|
||||
outcome.identity.clone(),
|
||||
session_base_key,
|
||||
signing_key,
|
||||
encryption_key,
|
||||
signing_required,
|
||||
encryption_enabled,
|
||||
None,
|
||||
);
|
||||
let session_arc = Arc::new(tokio::sync::RwLock::new(session));
|
||||
|
||||
Reference in New Issue
Block a user