schannel/
lib.rs

1//! Bindings to the Windows SChannel APIs.
2#![cfg(windows)]
3#![warn(missing_docs)]
4#![allow(non_upper_case_globals)]
5
6use std::ffi::c_void;
7use std::ptr;
8
9use windows_sys::Win32::Security::Authentication::Identity;
10
11macro_rules! inner {
12    ($t:path, $raw:ty) => {
13        impl crate::Inner<$raw> for $t {
14            unsafe fn from_inner(t: $raw) -> Self {
15                $t(t)
16            }
17
18            fn as_inner(&self) -> $raw {
19                self.0
20            }
21
22            fn get_mut(&mut self) -> &mut $raw {
23                &mut self.0
24            }
25        }
26
27        impl crate::RawPointer for $t {
28            unsafe fn from_ptr(t: *mut ::std::os::raw::c_void) -> $t {
29                $t(t as _)
30            }
31
32            unsafe fn as_ptr(&self) -> *mut ::std::os::raw::c_void {
33                self.0 as *mut _
34            }
35        }
36    };
37}
38
39/// Allows access to the underlying schannel API representation of a wrapped data type
40///
41/// Performing actions with internal handles might lead to the violation of internal assumptions
42/// and therefore is inherently unsafe.
43pub trait RawPointer {
44    /// Constructs an instance of this type from its handle / pointer.
45    /// # Safety
46    /// This function is unsafe
47    unsafe fn from_ptr(t: *mut ::std::os::raw::c_void) -> Self;
48
49    /// Get a raw pointer from the underlying handle / pointer.
50    /// # Safety
51    /// This function is unsafe
52    unsafe fn as_ptr(&self) -> *mut ::std::os::raw::c_void;
53}
54
55pub mod cert_chain;
56pub mod cert_context;
57pub mod cert_store;
58pub mod crypt_key;
59pub mod crypt_prov;
60/* pub */ mod ctl_context;
61pub mod key_handle;
62pub mod ncrypt_key;
63pub mod schannel_cred;
64pub mod tls_stream;
65
66mod alpn_list;
67mod context_buffer;
68mod security_context;
69
70#[cfg(test)]
71mod test;
72
73const ACCEPT_REQUESTS: u32 = Identity::ASC_REQ_ALLOCATE_MEMORY
74    | Identity::ASC_REQ_CONFIDENTIALITY
75    | Identity::ASC_REQ_SEQUENCE_DETECT
76    | Identity::ASC_REQ_STREAM
77    | Identity::ASC_REQ_REPLAY_DETECT;
78
79const INIT_REQUESTS: u32 = Identity::ISC_REQ_CONFIDENTIALITY
80    | Identity::ISC_REQ_INTEGRITY
81    | Identity::ISC_REQ_REPLAY_DETECT
82    | Identity::ISC_REQ_SEQUENCE_DETECT
83    | Identity::ISC_REQ_MANUAL_CRED_VALIDATION
84    | Identity::ISC_REQ_ALLOCATE_MEMORY
85    | Identity::ISC_REQ_STREAM
86    | Identity::ISC_REQ_USE_SUPPLIED_CREDS;
87
88trait Inner<T> {
89    unsafe fn from_inner(t: T) -> Self;
90
91    fn as_inner(&self) -> T;
92
93    fn get_mut(&mut self) -> &mut T;
94}
95
96unsafe fn secbuf(buftype: u32, bytes: Option<&mut [u8]>) -> Identity::SecBuffer {
97    let (ptr, len) = match bytes {
98        Some(bytes) => (bytes.as_mut_ptr(), bytes.len() as u32),
99        None => (ptr::null_mut(), 0),
100    };
101    Identity::SecBuffer {
102        BufferType: buftype,
103        cbBuffer: len,
104        pvBuffer: ptr as *mut c_void,
105    }
106}
107
108unsafe fn secbuf_desc(bufs: &mut [Identity::SecBuffer]) -> Identity::SecBufferDesc {
109    Identity::SecBufferDesc {
110        ulVersion: Identity::SECBUFFER_VERSION,
111        cBuffers: bufs.len() as u32,
112        pBuffers: bufs.as_mut_ptr(),
113    }
114}