Skip to content

Commit 2014cbb

Browse files
authored
Efer/wincrypto fixes (algesten#729)
* fix minor issues in wincrypto * set_active should never fail, it takes no user input, so it should succeed always on a functioning system
1 parent 15f822b commit 2014cbb

File tree

1 file changed

+85
-61
lines changed

1 file changed

+85
-61
lines changed

wincrypto/src/dtls.rs

Lines changed: 85 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,70 @@
1-
use super::{Certificate, WinCryptoError};
2-
use std::{
3-
collections::VecDeque,
4-
sync::Arc,
5-
time::{Duration, Instant},
6-
};
7-
use windows::Win32::{
8-
Foundation::{
9-
SEC_E_MESSAGE_ALTERED, SEC_E_OK, SEC_E_OUT_OF_SEQUENCE, SEC_I_CONTEXT_EXPIRED,
10-
SEC_I_CONTINUE_NEEDED, SEC_I_MESSAGE_FRAGMENT, SEC_I_RENEGOTIATE,
11-
},
12-
Security::{
13-
Authentication::Identity::{
14-
AcceptSecurityContext, AcquireCredentialsHandleW, DecryptMessage,
15-
DeleteSecurityContext, EncryptMessage, FreeContextBuffer, FreeCredentialsHandle,
16-
InitializeSecurityContextW, QueryContextAttributesExW, QueryContextAttributesW,
17-
SecBuffer, SecBufferDesc, SecPkgContext_KeyingMaterial,
18-
SecPkgContext_KeyingMaterialInfo, SecPkgContext_SrtpParameters,
19-
SecPkgContext_StreamSizes, SetContextAttributesW, ASC_REQ_CONFIDENTIALITY,
20-
ASC_REQ_DATAGRAM, ASC_REQ_EXTENDED_ERROR, ASC_REQ_INTEGRITY, ASC_REQ_MUTUAL_AUTH,
21-
ISC_REQ_CONFIDENTIALITY, ISC_REQ_DATAGRAM, ISC_REQ_EXTENDED_ERROR, ISC_REQ_INTEGRITY,
22-
ISC_REQ_MANUAL_CRED_VALIDATION, ISC_REQ_USE_SUPPLIED_CREDS, SCHANNEL_CRED,
23-
SCHANNEL_CRED_VERSION, SCH_CRED_MANUAL_CRED_VALIDATION, SECBUFFER_ALERT,
24-
SECBUFFER_DATA, SECBUFFER_DTLS_MTU, SECBUFFER_EMPTY, SECBUFFER_EXTRA,
25-
SECBUFFER_SRTP_PROTECTION_PROFILES, SECBUFFER_STREAM_HEADER, SECBUFFER_STREAM_TRAILER,
26-
SECBUFFER_TOKEN, SECBUFFER_VERSION, SECPKG_ATTR, SECPKG_ATTR_KEYING_MATERIAL,
27-
SECPKG_ATTR_KEYING_MATERIAL_INFO, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
28-
SECPKG_ATTR_SRTP_PARAMETERS, SECPKG_ATTR_STREAM_SIZES, SECPKG_CRED_INBOUND,
29-
SECPKG_CRED_OUTBOUND, SECURITY_NATIVE_DREP, SEC_DTLS_MTU, SP_PROT_DTLS1_2_CLIENT,
30-
SP_PROT_DTLS1_2_SERVER, UNISP_NAME_W,
31-
},
32-
Credentials::SecHandle,
33-
Cryptography::CERT_CONTEXT,
34-
},
35-
};
1+
use super::Certificate;
2+
use super::WinCryptoError;
3+
use std::collections::VecDeque;
4+
use std::sync::Arc;
5+
use std::time::Duration;
6+
use std::time::Instant;
7+
use windows::Win32::Foundation::SEC_E_MESSAGE_ALTERED;
8+
use windows::Win32::Foundation::SEC_E_OK;
9+
use windows::Win32::Foundation::SEC_E_OUT_OF_SEQUENCE;
10+
use windows::Win32::Foundation::SEC_I_CONTEXT_EXPIRED;
11+
use windows::Win32::Foundation::SEC_I_MESSAGE_FRAGMENT;
12+
use windows::Win32::Foundation::SEC_I_RENEGOTIATE;
13+
use windows::Win32::Security::Authentication::Identity::AcceptSecurityContext;
14+
use windows::Win32::Security::Authentication::Identity::AcquireCredentialsHandleW;
15+
use windows::Win32::Security::Authentication::Identity::DecryptMessage;
16+
use windows::Win32::Security::Authentication::Identity::DeleteSecurityContext;
17+
use windows::Win32::Security::Authentication::Identity::EncryptMessage;
18+
use windows::Win32::Security::Authentication::Identity::FreeContextBuffer;
19+
use windows::Win32::Security::Authentication::Identity::FreeCredentialsHandle;
20+
use windows::Win32::Security::Authentication::Identity::InitializeSecurityContextW;
21+
use windows::Win32::Security::Authentication::Identity::QueryContextAttributesExW;
22+
use windows::Win32::Security::Authentication::Identity::QueryContextAttributesW;
23+
use windows::Win32::Security::Authentication::Identity::SecBuffer;
24+
use windows::Win32::Security::Authentication::Identity::SecBufferDesc;
25+
use windows::Win32::Security::Authentication::Identity::SecPkgContext_KeyingMaterial;
26+
use windows::Win32::Security::Authentication::Identity::SecPkgContext_KeyingMaterialInfo;
27+
use windows::Win32::Security::Authentication::Identity::SecPkgContext_SrtpParameters;
28+
use windows::Win32::Security::Authentication::Identity::SecPkgContext_StreamSizes;
29+
use windows::Win32::Security::Authentication::Identity::SetContextAttributesW;
30+
use windows::Win32::Security::Authentication::Identity::ASC_REQ_CONFIDENTIALITY;
31+
use windows::Win32::Security::Authentication::Identity::ASC_REQ_DATAGRAM;
32+
use windows::Win32::Security::Authentication::Identity::ASC_REQ_EXTENDED_ERROR;
33+
use windows::Win32::Security::Authentication::Identity::ASC_REQ_INTEGRITY;
34+
use windows::Win32::Security::Authentication::Identity::ASC_REQ_MUTUAL_AUTH;
35+
use windows::Win32::Security::Authentication::Identity::ISC_REQ_CONFIDENTIALITY;
36+
use windows::Win32::Security::Authentication::Identity::ISC_REQ_DATAGRAM;
37+
use windows::Win32::Security::Authentication::Identity::ISC_REQ_EXTENDED_ERROR;
38+
use windows::Win32::Security::Authentication::Identity::ISC_REQ_INTEGRITY;
39+
use windows::Win32::Security::Authentication::Identity::ISC_REQ_MANUAL_CRED_VALIDATION;
40+
use windows::Win32::Security::Authentication::Identity::ISC_REQ_USE_SUPPLIED_CREDS;
41+
use windows::Win32::Security::Authentication::Identity::SCH_CREDENTIALS;
42+
use windows::Win32::Security::Authentication::Identity::SCH_CREDENTIALS_VERSION;
43+
use windows::Win32::Security::Authentication::Identity::SCH_CRED_FORMAT_CERT_CONTEXT;
44+
use windows::Win32::Security::Authentication::Identity::SCH_USE_DTLS_ONLY;
45+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_ALERT;
46+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_DATA;
47+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_DTLS_MTU;
48+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_EMPTY;
49+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_EXTRA;
50+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_SRTP_PROTECTION_PROFILES;
51+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_STREAM_HEADER;
52+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_STREAM_TRAILER;
53+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_TOKEN;
54+
use windows::Win32::Security::Authentication::Identity::SECBUFFER_VERSION;
55+
use windows::Win32::Security::Authentication::Identity::SECPKG_ATTR;
56+
use windows::Win32::Security::Authentication::Identity::SECPKG_ATTR_KEYING_MATERIAL;
57+
use windows::Win32::Security::Authentication::Identity::SECPKG_ATTR_KEYING_MATERIAL_INFO;
58+
use windows::Win32::Security::Authentication::Identity::SECPKG_ATTR_REMOTE_CERT_CONTEXT;
59+
use windows::Win32::Security::Authentication::Identity::SECPKG_ATTR_SRTP_PARAMETERS;
60+
use windows::Win32::Security::Authentication::Identity::SECPKG_ATTR_STREAM_SIZES;
61+
use windows::Win32::Security::Authentication::Identity::SECPKG_CRED_INBOUND;
62+
use windows::Win32::Security::Authentication::Identity::SECPKG_CRED_OUTBOUND;
63+
use windows::Win32::Security::Authentication::Identity::SECURITY_NATIVE_DREP;
64+
use windows::Win32::Security::Authentication::Identity::SEC_DTLS_MTU;
65+
use windows::Win32::Security::Authentication::Identity::UNISP_NAME_W;
66+
use windows::Win32::Security::Credentials::SecHandle;
67+
use windows::Win32::Security::Cryptography::CERT_CONTEXT;
3668

3769
#[repr(C)]
3870
struct SrtpProtectionProfilesBuffer {
@@ -126,30 +158,18 @@ impl Dtls {
126158
self.is_client = Some(active);
127159

128160
let mut cert_contexts = [self.cert.context()];
129-
let schannel_cred = SCHANNEL_CRED {
130-
dwVersion: SCHANNEL_CRED_VERSION,
131-
hRootStore: windows::Win32::Security::Cryptography::HCERTSTORE(std::ptr::null_mut()),
132-
133-
grbitEnabledProtocols: if active {
134-
SP_PROT_DTLS1_2_CLIENT
135-
} else {
136-
SP_PROT_DTLS1_2_SERVER
137-
},
138-
161+
let sch_cred = SCH_CREDENTIALS {
162+
dwVersion: SCH_CREDENTIALS_VERSION,
163+
dwCredFormat: SCH_CRED_FORMAT_CERT_CONTEXT,
139164
cCreds: cert_contexts.len() as u32,
140165
paCred: cert_contexts.as_mut_ptr() as *mut *mut CERT_CONTEXT,
141-
166+
hRootStore: windows::Win32::Security::Cryptography::HCERTSTORE(std::ptr::null_mut()),
142167
cMappers: 0,
143168
aphMappers: std::ptr::null_mut(),
144-
145-
cSupportedAlgs: 0,
146-
palgSupportedAlgs: std::ptr::null_mut(),
147-
148-
dwMinimumCipherStrength: 128,
149-
dwMaximumCipherStrength: 256,
150169
dwSessionLifespan: 0,
151-
dwFlags: SCH_CRED_MANUAL_CRED_VALIDATION,
152-
dwCredFormat: 0,
170+
dwFlags: SCH_USE_DTLS_ONLY,
171+
cTlsParameters: 0,
172+
pTlsParameters: std::ptr::null_mut(),
153173
};
154174

155175
// These are the outputs of AcquireCredentialsHandleA
@@ -169,7 +189,7 @@ impl Dtls {
169189
SECPKG_CRED_INBOUND
170190
},
171191
None,
172-
Some(&schannel_cred as *const _ as *const std::ffi::c_void),
192+
Some(&sch_cred as *const _ as *const std::ffi::c_void),
173193
None,
174194
None,
175195
&mut cred_handle,
@@ -390,26 +410,30 @@ impl Dtls {
390410

391411
debug!("DTLS Handshake status: {status}");
392412
self.security_ctx = Some(new_ctx_handle);
393-
if out_buffers[0].cbBuffer > 0 {
413+
414+
// Only output datagram if we have data to send and we didn't fail.
415+
if (status.is_ok() || status == SEC_E_OK) && out_buffers[0].cbBuffer > 0 {
394416
let len = out_buffers[0].cbBuffer;
395417
self.output_datagrams
396418
.push_back(token_buffer[..len as usize].to_vec());
397419
}
420+
398421
return match status {
399422
SEC_E_OK => {
400423
// Move to Done
401424
self.transition_to_completed()
402425
}
403-
SEC_I_CONTINUE_NEEDED => {
404-
// Stay in handshake while we wait for the other side to respond.
405-
debug!("Wait for peer");
406-
Ok(DtlsEvent::None)
407-
}
408426
SEC_I_MESSAGE_FRAGMENT => {
409427
// Fragment was sent, we need to call again to send the next fragment.
410428
debug!("Sent handshake fragment");
411429
self.handshake(None)
412430
}
431+
status if status.is_ok() => {
432+
// For any other "OK" status, we just wait for the peer, this
433+
// includes SEC_I_CONTINUE_NEEDED.
434+
debug!(?status, "Wait for peer");
435+
Ok(DtlsEvent::None)
436+
}
413437
e => {
414438
// Failed
415439
self.state = EstablishmentState::Failed;

0 commit comments

Comments
 (0)