DTLS using Schannel - windows

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:
InitializeSecurityContext with null input on the first pass, SECBUFFER_TOKEN & SECBUFFER_ALERT on output
AcceptSecurityContext with SECBUFFER_TOKEN & SECBUFFER_EMPTY on input, SECBUFFER_TOKEN & SECBUFFER_ALERT on output.
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.

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).
Set SCHANNEL_CRED.grbitEnabledProtocols to SP_PROT_DTLS1_X.
When calling AcceptSecurityContext, pass the client’s SOCKADDR via SECBUFFER_EXTRA.
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.]
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).
Implement timeout and retransmit logic in your application (since
schannel does not own the socket).
When receiving fragments, schannel will attempt to eliminate
duplicates, re-order and re-assemble, if possible.
SCHANNEL_SHUTDOWN does not apply to DTLS.

You can use https://github.com/mobius-software-ltd/iotbroker.cloud-windows-client As a sample to implement DTLS on windows
It does not uses SChannel but netty library.
MQTT-SN And CoAP are both supporting DTLS under this project.
BR
Yulian Oifa

Related

gRPC stopped working with APO on Windows 11

I have a Windows application (APP) and Audio Processing Object (APO) loaded by AudioDG.exe that communicate via gRPC:
APP part that is written in C# creates server via Grpc.Core.
APO part creates client via grpc++.
Server is on 127.0.0.1:20000 (I can see it's up and listening with netstat -ano).
I can confirm that APO is loaded into audio device graph by inspecting it with process explorer.
Everything worked like a charm on Windows 8 and 10, but on 11 it cannot communicate at all - I get either Error Code 14, Unavailable, failed to connect to all addresses or 4, Deadline Exceeded.
After enabling debug traces, I now see "socket is null" description for "connect failed" error:
I0207 16:20:59.916447 0 ..\..\..\src\core\ext\filters\client_channel\subchannel.cc:950: subchannel 000001D8B9B01E20 {address=ipv4:127.0.0.1:10000, args=grpc.client_channel_factory=0x1d8bb660460, grpc.default_authority=127.0.0.1:10000, grpc.internal.subchannel_pool=0x1d8b8c291b0, grpc.primary_user_agent=grpc-csharp/2.43.0 (.NET Framework 4.8.4470.0; CLR 4.0.30319.42000; net45; x64), grpc.resource_quota=0x1d8b8c28d90, grpc.server_uri=dns:///127.0.0.1:10000}: connect failed: {"created":"#1644240059.916000000","description":"socket is null","file":"..\..\..\src\core\lib\iomgr\tcp_client_windows.cc","file_line":112}
What I've tried so far:
Updating both parts to the latest grpc versions.
Using "no proxy", "Http2UnencryptedSupport" and other env variables.
Using "localhost" or "0.0.0.0" instead of "127.0.0.1".
Updating connection to use self signed SSL certificates (root CA, server cert + key, client cert + key).
Adding inbound / outbound rules for my port, and then disabling firewall completely.
Creating server on APO side and trying to connect with the client in APP.
Everything works (both insecure and SSL creds) if I create both client and server in C# part, but as soon as it's APP-APO communication it feels blocked or sandboxed.
What has been changed in Windows 11 that can "block" gRPC?
Thanks in advance!
In your input you write:
Server is at 127.0.0.1:20000
Further looking at the logs, you can see that:
The server is located at
grpc.server_uri=dns:///127.0.0.1:10000
Based on the question posed and the amount of data provided, I would check which port the server is really using and which port the client is looking for a connection on.
The easiest way to do this is to use the built-in Resource Monitor application. On the Network tab, in the TCP Connections list, you can find the application and the port it uses.
You can also use the PowerShell command
Test-NetConnection -Port 10000 -InformationLevel "Detailed"
Test-NetConnection -Port 20000 -InformationLevel "Detailed"
At least this is the first thing I would check based on what you described.
Regarding your question about the changes in Windows 11, I do not think that this is something that's causing problems for you. However, Windows 11 has additional security features compared to Windows 10, try disabling the security features completely as a test. Perhaps this will help solve the problem.
As for ASP.NET Core 6.0 itself (if I understood the version correctly), then there is a possibility that the server part, working not in the sandbox of the programming environment, still does not accept the client certificate. At the program level, you can try to fix this by adding the following exception to the code:
// This switch must be set before creating the GrpcChannel/HttpClient.
AppContext.SetSwitch(
"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
// The port number(5000) must match the port of the gRPC server.
var channel = GrpcChannel.ForAddress("http://localhost:5000");
var client = new Greet.GreeterClient(channel);
More troubleshooting issues with ASP.NET Core 6.0 Microsoft described in detail here.
https://learn.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-6.0
I hope it was useful and at least one of the solutions I suggested will help solve your problem. In any case, if I had more information, I think I could help you more accurately.

Is there ms Windows tcp/udp/icmp traceroute implementation without admin rights required?

I was trying to find traceroute program implementation for MS Windows that can be used by regular user (with no admin rights) and I could not find any. Those I could find (like tracetcp or nmap) require PCAP library and in order to install winpcap I think administration rights are required.
I don't know much about Windows internals but I'm wondering what is the 'magic' behind. If tracert shipped by MS with Win OS works fine for regular user (but it can use ICMP only) then is there any issue (technical limitation) with setting TTL for TCP/UDP packet by regular user and receiving respective response on the socket such as:
ICMP: TTL expired in transit
UDP: port unreachable
and probably few others (like TCP RST, ICMP host unreachable etc)?
So basically:
if there is no issue why there is no reasonable traceroute implementation
for windows?
if there is a technical limitation for TCP/UDP then why
original MS ICMP traceroute works fine for non admin users?
I know that the most popular linux traceroute with -T option (for using SYN probes) requires root priviliges too but I'm assuming it's just because it does not want to complete full TCP handshake and sending RST after receiving SYN-ACK may be restricted for root. Anyway as longs as TTL can be set by reqular user (for UDP it seems to work fine) then I would imagine TCP traceroute completing full TCP handshake should be possible to implement for non root linux users?
And by the way ICMP traceroute also needs admin rights because of using RAW sockets but surprisingly for Windows it does not seem to be an issue.
Sadly, the simple answer to your question is "no, there is no native way to do that on a Windows box".
I am a bit unsure about your specific usecase, but one route to go is evaluate if Power Shell has more functionality to help you out. Jose Baretto from Microsoft wrote an article about Power Shell equivalents for common networking commands. You can find it here:
https://blogs.technet.microsoft.com/josebda/2015/04/18/windows-powershell-equivalents-for-common-networking-commands-ipconfig-ping-nslookup/
Failing that, your only option is (as you mention yourself) 3rd party tools, and you'll be hard press to find one that doesn't require elevated privileges.

https with ECDHE-ECDSA-AES256-GCM-SHA384 in windows 2012

I have been a long time reader but this is my first real post on a topic that I couldn't find a solution to.
I am currently hosting a website on Windows 2012 that I would like to get the latest TLS 1.2 ciphersuites running on.
I am aware of how to enable TLS 1.1 and TLS 1.2 in windows and have done so(via registry edits). I have also changed the cipher order to what I would like it to be.
My question is: How do i actually go through and set up my ECDHE / ECDSA portion of the cipher suite after this step?
When i view the site in the latest chrome beta (which supports ECDHE and ECDSA in TLS 1.2 provided you use the supported curves) it seems to skip all of the ECHDE ciphersuites.
Is there something else i need to do to get ECDHE/ECDSA properly enabled?
I have read around on the net trying to solve this myself and they mention making copies of your root cert and then modifying them to somehow support ECDHE. Am i barking up the wrong tree?
Thank you in advance for any and all support with this issue.
Edit: adding clarification/progress
After more research, I have found that in order to get ECDSA to work, you need an ECDSA certificate. The only way to get one at this time is to self-sign, as the cert-cartel has not yet come up with proper cross-licensing agreements and fee structures for Ellipic Curve Certificates yet.
Since self-signing is not an option for this site, I have removed all ECDSA suites from the cipher-order.
Unfortunately, because all of the AES Galois Counter Mode suites were also ECDSA, this rules those out for the time being.
This leaves me with a strongest cipher suite of ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521 which I BELIEVE is supported by the latest version of Chrome beta correct? I can't seem to get Chrome to pick up anything beyond SHA-1. Is there no SHA-2 support? even in the latest beta?
AES-GCM is about how you encrypt the data in your connexion, EC-DSA or RSA about how the server identifies itself to the client. There is therefore no reason why you couldn't do AES-GCM encryption with a RSA authentication.
RFC 5289 does define the needed suite for that :
https://www.rfc-editor.org/rfc/rfc5289#section-3.2
CipherSuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = {0xC0,0x2F};
CipherSuite TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = {0xC0,0x30};
CipherSuite TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = {0xC0,0x31};
CipherSuite TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = {0xC0,0x32};
It's not however necessarily easy to find both the client and the server that will support them.
I had similar experiences with Win2008 R2.
Depending on the certificate, GCM cipher is offered by the server or not.
With self-signed ECDSA certificate i got GCM to work but older browsers
or Windows XP can't connect to such a https-site.
Windows doesnt support any TLS_ECDHE_RSA...GCM... ciphers:
http://msdn.microsoft.com/en-us/library/aa374757(v=vs.85).aspx
Thus normal RSA-certificates don't work with GCM under Windows.
Browser compatibility:
http://www.g-sec.lu/sslharden/SSL_comp_report2011.pdf

Does Windows 7 actually support the SMB core protocol?

I have started the development of a SMB server for an old Z80 based machine. This machine runs a very simple, MS-DOS like operating system (no multitask, no concept of users, FAT filesystem only, no unicode, 8.3 filenames only) and has limited memory, therefore my first idea is to implement just the SMB core protocol. I will use TCP transport.
As for now, I have just a very short testing code that just replies to the SMB_COM_NEGOTIATE command, indicating that the core protocol ("PC NETWORK PROGRAM 1.0") is the desired dialect. In order to test it, I try to connect from a Windows 7 machine, by opening a explorer window and typing "\\<server IP>" in the address bar. I have verified with Wireshark that the server receives the negotiate command and sends an (apparently) correct response.
The problem: as soon as the Windows client receives the response, it shows a generic "Can't access resource" error message (with error code 0x80004005) and then nothing happens (no further SMB messages are sent). I was expecting to receive SMB_COM_TREE_CONNECT or a similar command.
I was thinking that maybe Windows 7 does not support the core protocol (it is very old and it lacks any security feature whatsoever), but then, why does it list the core dialect name in the negotiate request? Maybe I am missing some step? Must the server send any additional packet after the negotiate response?
The client OS is Windows 7 Ultimate 64 bits, and here are the Wireshark dumps of both the request and the response in case anyone can spot anything wrong in the process:
The request:
The response:
UPDATE: If I select the NT LM 0.12 dialect instead of the core dialect, I receive a SESSION_SETUP_AND_REQUESTX command from the client. So apparently it seems that indeed, the core protocol is not supported by Windows 7. Anyway, any extra information will be appreciated.
I believe Windows 7 does support the Core Protocol. It downgrades to SMB 1.0 when connecting to older servers as per here.
Based on the issues that Windows 7 has with connecting to Samba servers, I believe the issue with the specifying the core protocol is due the LANMAN workstation / client settings on the Windows 7 machine.
Recommended changes would be
enabling LM and NTLM hashes to be as part of the security policy are
Network security: LAN Manager authentication level Send LM & NTLM responses
changing the 【HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa \【LmCompatibilityLevel 】 value of the registry key to 0 as per here
Adding the following parameters to LanmanWorkStation and NetLogon in the registry
HKLM\System\CCS\Services\LanmanWorkstation\Parameters
DWORD DomainCompatibilityMode = 1
DWORD DNSNameResolutionRequired = 0
HKLM\System\CCS\Services\Netlogon\Parameters
DWORD RequireSignOnSeal = 0
DWORD RequireStrongKey = 0
Possible changes to these settings both via registry and via security policy are listed here
These changes should ensure LanmanWorkstation doesn't use NTLMv2 session security.
This info is basically the same as #Appleman1234 provided (thanks!), just a bit easier to apply.
Export your current reg settings so you can restore what you had if necessary. Put the following code into a .bat file and it will export to your C: drive the 3 reg keys we are getting ready to modify.
reg export HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa HKEY_LOCAL_MACHINE.SYSTEM.CurrentControlSet.Control.Lsa.reg
reg export HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanWorkstation\Parameters HKEY_LOCAL_MACHINE.SYSTEM.CurrentControlSet.services.LanmanWorkstation.Parameters.reg
reg export HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Netlogon\Parameters HKEY_LOCAL_MACHINE.SYSTEM.CurrentControlSet.services.Netlogon.Parameters.reg
Un-restrict the required registry settings. Below is almost exactly what #Appleman1234 suggested except it also enables plain text passwords and disables security signatures. Put the following code into a .reg file and import it to your registry.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"lmcompatibilitylevel"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanWorkstation\Parameters]
"EnablePlainTextPassword"=dword:00000001
"EnableSecuritySignature"=dword:00000000
"RequireSecuritySignature"=dword:00000000
"DomainCompatibilityMode"=dword:00000001
"DNSNameResolutionRequired"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Netlogon\Parameters]
"RequireSignOrSeal"=dword:00000000
"RequireStrongKey"=dword:00000000
"RequireSignOnSeal"=dword:00000000

Setting DIFFSERV/DSCP with GQOS for specific socket in c

I need to set the DSCP field of packets sent from a specific (tcp) socket in windows XP.
It seems that the GQOS API should serve this purpose (see http://blogs.msdn.com/wndp/archive/2006/07/05/657196.aspx) but I really, really, can't find any working example or figure how to use it on my own.
I would be very grateful if anyone of you have a working example he/she could share.
However, the following workarounds are not acceptable:
Using the QOS2 api - it's only available on Vista and up (and I'll use it there)
Using the TC api - it's not specific to a given socket (it tries to match outgoing packets to a filter) and requires admin rights to use 3.
Using SetSockOpt with IP_TOS - it's deprecated in XP, was not meant for setting the DSCP field and requires changing the registery.
Thanks!

Resources