Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DTLS using Schannel

I am trying to create a DTLS "connection" using Schannel under Windows (I am testing under recent Windows 10 version, so all DTLS versions supported by Schannel should be available)

I tried starting from working code to establish a regular TLS connection by following the documentation:

  1. InitializeSecurityContext with null input on the first pass, SECBUFFER_TOKEN & SECBUFFER_ALERT on output
  2. AcceptSecurityContext with SECBUFFER_TOKEN & SECBUFFER_EMPTY on input, SECBUFFER_TOKEN & SECBUFFER_ALERT on output.
  3. Repeat the two steps until they succeed, and then move on to using Encrypt/DecryptMessage

This works perfectly fine in stream mode (ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM)

If I try to substitute STREAM with ISC/ASC_REQ_DATAGRAM, my InitializeSecurityContext succeeds with SEC_I_CONTINUE_NEEDED as expected, but my very first AcceptSecurityContext then fails with SEC_E_INVALID_PARAMETER.

I have tried setting grbitEnabledProtocols of my SCHANNEL_CRED to 0 to use the defaults as documented on both sides, I also tried setting it to SP_PROT_DTLS1_X, and I still get the Invalid Parameter return from my first ASC. I have also tried the DTLS_1_0 constants just in case.

Also, all security protocols are enabled by default in my registry settings.

From my understanding of the DTLS RFC, my code is failing at the HelloVerifyRequest step, and, again from my understanding of the RFC, this part requires that the security provider generates a cookie from a few parts of the ClientHello message as well as the source's IP address. However, I could not find any documented way to pass this information to the ASC function.

(I think? :) ) I have searched the entire internet for any working example usage of DTLS under Schannel without any luck. On stackoverflow, I found this question that simply mentions that it is supported: Is DTLS supported by Schannel on Windows 7?, and the linked MSDN article is just a high level overview.

I searched for any usage of the constants that are related to this feature... I searched for any usage of the constants that are related to this (ISC_REQ_DATAGRAM, SP_PROT_DTLS*, SECBUFFER_DTLS_MTU, ...) and the only thing I could find on all search engines I could think of were either copies of sspi.h or sites that index the constants in the Windows API...

I know DTLS is well supported by other implementations (OpenSSL etc), but I would really prefer to stay with Schannel, as other parts of my code currently work just fine with Schannel in TLS mode.

like image 623
fbrosseau Avatar asked Dec 06 '17 16:12

fbrosseau


People also ask

Is DTLS better than TLS?

Therefore, DTLS offers as many security guarantees as TLS but reduces the need to use IPsec or design a custom application layer security protocol. The main difference between DTLS and TLS is that DTLS is built on UDP, while TLS uses Transmission Control Protocol (TCP).

Is DTLS faster than TLS?

Note DTLS provides TLS functionalities that are based on the User Datagram Protocol (UDP) protocol. Because TLS is based on the Transmission Control Protocol (TCP) protocol, DTLS performs better than TLS.

How does DTLS protocol work?

The DTLS protocol is like an extra layer of privacy for UDP communications, and it's designed to prevent data packages from getting lost or arriving in the wrong order. DTLS uses a simple retransmission timer for this, with each endpoint continuing to retransmit its last message until a reply is received.

Does DTLS use UDP?

DTLS is an implementation of TLS over UDP (a datagram protocol). per wikipedia, TLS uses TCP, and DTLS uses UDP, so all the classic differences apply. UDP communications exist as streams of packets with no ordering, delivery reliability, or flow control.


1 Answers

From Microsoft: There is no documentation for implementing DTLS using Schannel. Known and persistent doc gap.

There are a few differences, but a TLS client or server can be adapted to DTLS fairly easily (a number of customers have done this successfully).

  1. Set SCHANNEL_CRED.grbitEnabledProtocols to SP_PROT_DTLS1_X.
  2. When calling AcceptSecurityContext, pass the client’s SOCKADDR via SECBUFFER_EXTRA.
  3. MTU can be set via SetContextAttributes using constant SECPKG_ATTR_DTLS_MTU where the buffer is just an pointer to a ULONG. [Default is 1096 bytes.]
  4. When ISC/ASC return SEC_I_MESSAGE_FRAGMENT, send this fragment and call ISC/ASC again, in a loop, to get the next fragment (without trying to read data from the network).
  5. Implement timeout and retransmit logic in your application (since schannel does not own the socket).
  6. When receiving fragments, schannel will attempt to eliminate duplicates, re-order and re-assemble, if possible.
  7. SCHANNEL_SHUTDOWN does not apply to DTLS.
like image 58
Matthew J. Bobowski Avatar answered Oct 18 '22 00:10

Matthew J. Bobowski