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 ) ]
3870struct 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