Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add make_signature and verify_signature to Sspi trait. #343

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/credssp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,36 @@ impl Sspi for SspiContext {
self.change_password_impl(&mut yield_point, change_password).await
}))
}

fn make_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SecurityStatus> {
match self {
SspiContext::Ntlm(ntlm) => ntlm.make_signature(flags, message, sequence_number),
SspiContext::Kerberos(kerberos) => kerberos.make_signature(flags, message, sequence_number),
SspiContext::Negotiate(negotiate) => negotiate.make_signature(flags, message, sequence_number),
SspiContext::Pku2u(pku2u) => pku2u.make_signature(flags, message, sequence_number),
#[cfg(feature = "tsssp")]
SspiContext::CredSsp(credssp) => credssp.make_signature(flags, message, sequence_number),
}
}

fn verify_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<crate::SignatureFlags> {
match self {
SspiContext::Ntlm(ntlm) => ntlm.verify_signature(flags, message, sequence_number),
SspiContext::Kerberos(kerberos) => kerberos.verify_signature(flags, message, sequence_number),
SspiContext::Negotiate(negotiate) => negotiate.verify_signature(flags, message, sequence_number),
SspiContext::Pku2u(pku2u) => pku2u.verify_signature(flags, message, sequence_number),
#[cfg(feature = "tsssp")]
SspiContext::CredSsp(credssp) => credssp.verify_signature(flags, message, sequence_number),
}
}
}

impl SspiEx for SspiContext {
Expand Down
16 changes: 16 additions & 0 deletions src/kerberos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,22 @@ impl Sspi for Kerberos {
self.change_password(&mut yield_point, change_password).await
}))
}

fn make_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SecurityStatus> {
todo!()
}

fn verify_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<crate::SignatureFlags> {
todo!()
}
}

impl SspiImpl for Kerberos {
Expand Down
20 changes: 20 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,19 @@ where
sequence_number: u32,
) -> Result<SecurityStatus>;

/// TODO
fn make_signature(&mut self,
flags: SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SecurityStatus>;
AvivNaaman marked this conversation as resolved.
Show resolved Hide resolved

fn verify_signature(&mut self,
flags: SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SignatureFlags>;

/// Decrypts a message. Some packages do not encrypt and decrypt messages but rather perform and check an integrity hash.
///
/// # Parameters
Expand Down Expand Up @@ -1066,6 +1079,13 @@ bitflags! {
}
}

bitflags! {
/// TODO
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SignatureFlags: u32 {
}
}
AvivNaaman marked this conversation as resolved.
Show resolved Hide resolved

bitflags! {
/// Indicate requests for the context. Not all packages can support all requirements. Bit flags can be combined by using bitwise-OR operations.
///
Expand Down
16 changes: 16 additions & 0 deletions src/negotiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,22 @@ impl Sspi for Negotiate {
self.change_password(&mut yield_point, change_password).await
}))
}

fn make_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SecurityStatus> {
todo!()
AvivNaaman marked this conversation as resolved.
Show resolved Hide resolved
}

fn verify_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<crate::SignatureFlags> {
todo!()
}
}

impl SspiImpl for Negotiate {
Expand Down
116 changes: 89 additions & 27 deletions src/ntlm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use crate::{
ClientRequestFlags, ClientResponseFlags, ContextNames, ContextSizes, CredentialUse, DecryptionFlags,
EncryptionFlags, Error, ErrorKind, FilledAcceptSecurityContext, FilledAcquireCredentialsHandle,
FilledInitializeSecurityContext, InitializeSecurityContextResult, OwnedSecurityBuffer, PackageCapabilities,
PackageInfo, SecurityBuffer, SecurityBufferType, SecurityPackageType, SecurityStatus, ServerResponseFlags, Sspi,
SspiEx, SspiImpl, PACKAGE_ID_NONE,
PackageInfo, SecurityBuffer, SecurityBufferType, SecurityPackageType, SecurityStatus, ServerResponseFlags,
SignatureFlags, Sspi, SspiEx, SspiImpl, PACKAGE_ID_NONE,
};

pub const PKG_NAME: &str = "NTLM";
Expand Down Expand Up @@ -368,6 +368,50 @@ impl Ntlm {
expiry: None,
})
}

fn compute_checksum(
&mut self,
message: &mut [SecurityBuffer],
sequence_number: u32,
digest: &[u8; 16],
) -> crate::Result<SecurityStatus> {
let checksum = self
.send_sealing_key
.as_mut()
.unwrap()
.process(&digest[0..SIGNATURE_CHECKSUM_SIZE]);

let signature_buffer = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?;
if signature_buffer.buf_len() < SIGNATURE_SIZE {
return Err(Error::new(ErrorKind::BufferTooSmall, "The Token buffer is too small"));
AvivNaaman marked this conversation as resolved.
Show resolved Hide resolved
}
let signature = compute_signature(&checksum, sequence_number);
signature_buffer.write_data(signature.as_slice())?;

Ok(SecurityStatus::Ok)
}

fn check_signature(
&mut self,
sequence_number: u32,
digest: &[u8; 16],
signature: &[u8],
) -> crate::Result<()> {
let checksum = self
.recv_sealing_key
.as_mut()
.unwrap()
.process(&digest[0..SIGNATURE_CHECKSUM_SIZE]);
let expected_signature = compute_signature(&checksum, sequence_number);

if signature != expected_signature.as_ref() {
return Err(Error::new(
ErrorKind::MessageAltered,
"Signature verification failed, something nasty is going on!",
AvivNaaman marked this conversation as resolved.
Show resolved Hide resolved
));
}
Ok(())
}
}

impl Sspi for Ntlm {
Expand Down Expand Up @@ -398,18 +442,7 @@ impl Sspi for Ntlm {
}
data.write_data(&encrypted_data)?;

let checksum = self
.send_sealing_key
.as_mut()
.unwrap()
.process(&digest[0..SIGNATURE_CHECKSUM_SIZE]);

let signature_buffer = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Token)?;
if signature_buffer.buf_len() < SIGNATURE_SIZE {
return Err(Error::new(ErrorKind::BufferTooSmall, "The Token buffer is too small"));
}
let signature = compute_signature(&checksum, sequence_number);
signature_buffer.write_data(signature.as_slice())?;
self.compute_checksum(message, sequence_number, &digest)?;

Ok(SecurityStatus::Ok)
}
Expand Down Expand Up @@ -437,19 +470,7 @@ impl Sspi for Ntlm {
save_decrypted_data(&decrypted, message)?;

let digest = compute_digest(&self.recv_signing_key, sequence_number, &decrypted)?;
let checksum = self
.recv_sealing_key
.as_mut()
.unwrap()
.process(&digest[0..SIGNATURE_CHECKSUM_SIZE]);
let expected_signature = compute_signature(&checksum, sequence_number);

if signature != expected_signature.as_ref() {
return Err(Error::new(
ErrorKind::MessageAltered,
"Signature verification failed, something nasty is going on!",
));
}
self.check_signature(sequence_number, &digest, signature)?;

Ok(DecryptionFlags::empty())
}
Expand Down Expand Up @@ -503,6 +524,47 @@ impl Sspi for Ntlm {
"NTLM does not support change pasword",
))
}

fn make_signature(
&mut self,
_flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SecurityStatus> {
if self.recv_sealing_key.is_none() {
self.complete_auth_token(&mut [])?;
}

SecurityBuffer::find_buffer(message, SecurityBufferType::Token)?; // check if exists

let data = SecurityBuffer::find_buffer_mut(message, SecurityBufferType::Data)?;
let digest = compute_digest(&self.send_signing_key, sequence_number, data.data())?;

self.compute_checksum(message, sequence_number, &digest)?;

Ok(SecurityStatus::Ok)
}

fn verify_signature(
&mut self,
_flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SignatureFlags> {
if self.recv_sealing_key.is_none() {
self.complete_auth_token(&mut [])?;
}

SecurityBuffer::find_buffer(message, SecurityBufferType::Token)?; // check if exists

let data = SecurityBuffer::find_buffer(message, SecurityBufferType::Data)?;
let digest = compute_digest(&self.recv_signing_key, sequence_number, data.data())?;

let signature = SecurityBuffer::find_buffer(message, SecurityBufferType::Token)?;
self.check_signature(sequence_number, &digest, signature.data())?;

Ok(SignatureFlags::empty())
}
}

impl SspiEx for Ntlm {
Expand Down
16 changes: 16 additions & 0 deletions src/pku2u/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,22 @@ impl Sspi for Pku2u {
"Pku2u does not support change pasword",
))
}

fn make_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<SecurityStatus> {
todo!()
}

fn verify_signature(&mut self,
flags: crate::SignatureFlags,
message: &mut [SecurityBuffer],
sequence_number: u32,
) -> crate::Result<crate::SignatureFlags> {
todo!()
}
}

impl SspiImpl for Pku2u {
Expand Down
Loading