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