Why .NET Compact Framework fails to call some HTTPS web servers

Published 19 November 07 10:18 PM | andarno 

A bug was discovered recently in the .NET Compact Framework version 2.0 (SP2 and earlier) and 3.5 that causes HttpWebRequest's directed at some HTTPS servers to fail with this error: (for web services)

System.Net.WebException: Unable to read data from the transport connection. ---> System.Net.Sockets.SocketException: Unknown error (0x0).
   at System.Net.HttpWebRequest.fillBuffer(HttpWebRequest request, Connection connection, CoreResponseData data)
   at System.Net.HttpWebRequest.getLine(HttpWebRequest request, Connection connection, CoreResponseData data)
   at System.Net.HttpWebRequest.parseResponse(HttpWebRequest request, Connection connection, Boolean defaultKeepAlive)
   at System.Net.HttpWebRequest.startReceiving(Connection connection)
   at System.Net.Connection.startReceiving(Object ignored)
   at System.Threading.ThreadPool.WorkItem.doWork(Object o)
   at System.Threading.Timer.ring()

   at System.Net.HttpWebRequest.finishGetResponse()
   at System.Net.HttpWebRequest.GetResponse()
   // ...
   at Program.Main(String[] args)

For standard HttpWebRequest calls from your app the stack trace would be different, although the exception message and cause would be the same.

While there are multiple reasons this exception can be produced, one thing that can cause it is if the server sends an empty encryption packet to the NetCF client.  Here is an illustration of the encryption process that occurs on the server for HTTPS:

First, a memory buffer is initialized with unencrypted data that the server wants to send to the client over the network.

Step 1:   unencrypted data  

Next, the server makes a call to EncryptMessage and the unencrypted data is encrypted in place.  A header and footer is added to the buffer:

Step 2: header encrypted data footer

This header if 5 bytes long, and the footer is several more bytes.  This entire packet, which is necessarily longer than the original unencrypted data, is then sent down the wire where the process is reversed using a call to DecryptMessage.

The trouble with NetCF's SSL stack is when the server encrypts a buffer of zero length and sends it to the client:

Step 1:   0 bytes of unencrypted data  
Step 2: header encrypted representation of a zero-length buffer footer

Although the original data had a length of zero, the encrypted version of it actually has a non-zero length.  When this packet is sent to a NetCF client, current versions of NetCF decrypt the packet and return a zero length buffer to the caller.  The semantics of a network Read method is traditionally that it blocks until some data is received, and if a zero length buffer is returned it is the sign that the socket was closed.  Because NetCF will return an empty buffer after decrypting an "empty" encryption packet, the caller may misinterpret this as a sign of a disconnected socket and terminate the connection.

In fact this is exactly what happens in NetCF's web services code when calling services over SSL that respond with empty encryption packets.  As a result the connection fails before the response is fully received and an exception is thrown.

What causes the server to send these empty encryption packets?  Technically it's legally allowed for these empty packets to be sent (although they are pointless), so depending on your server and its configuration this may never happen or it may happen regularly.

Unfortunately there is no way to get NetCF to ignore these packets, so the only workarounds are these, in order of simplicity:

  1. Don't use SSL to make your request (security implications here of course by sending your request and its response in clear text)
  2. Reconfigure your existing server in some way to get it to avoid generating these empty encryption packets.
  3. Build a new web server that will forward your device's requests on a separate connection to the ultimate target server and forward the responses back to the device.  This would work for web sites and web services.  But this new front-end server (which serves something of the role of a proxy server) would have to be configured to not generate these empty encryption packets.
  4. [Added 1/2/08] Build a device-side web proxy that calls into the SSPI functions itself (native would probably be easier than managed for this).  Then have your managed app call into the proxy.  This proxy would be responsible for consuming the empty packets and re-encrypting everything (if necessary to secure IPC) for the app on the same device without any empty SSL packets.
  5. Wait until a future version of NetCF that fixes this bug.
  6. Write your own HTTPS client using native code or P/Invoke'ing from NetCF (difficult to get right).

So how do you know for sure if the HTTPS server is sending empty encryption packets that are causing your NetCF clients to fail?  I wrote a native C++ app that calls a web server on an HTTPS connection and detects these packets.  (No, I'm afraid it can't filter them out for NetCF clients) By running this app against your web server the app will tell you whether your server generates these empty packets.  At least then you know what's going on.

[Updated Feb 1, 2008] You can download the source code from its resource page on the MSDN Code Gallery.

Filed under: , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# MSDN Blog Postings » Why .NET Compact Framework fails to call some HTTPS web servers said on November 19, 2007 6:05 PM:

PingBack from http://msdnrss.thecoderblogs.com/2007/11/19/why-net-compact-framework-fails-to-call-some-https-web-servers/

# Dima said on November 20, 2007 3:02 AM:

wow.. I have this bug and I couldn't figure out what was the problem... it was VERY frustrating.

Thanks,

Dima.

# Oren said on November 20, 2007 3:31 AM:

Is this behavior is depend only by the CF. version?

As I can see this behavior only at WM6 devices and not at WM5, running the same application..

# Vinay C said on November 20, 2007 4:46 AM:

Just check as i only get this error while using code in WM6.....it works fine with WM5

# .NET Compact Framework Team said on November 21, 2007 11:57 AM:

On his blog, Andrew discusses an HTTPS bug in NetCF that causes NetCF to throw a WebException when connecting

# Anthony Wong's Blog said on November 21, 2007 3:03 PM:

A bug has been found on NETCF v2 and v35 that affects HTTPS web requests from Windows Mobile 6 devices.

# Noticias externas said on November 21, 2007 3:24 PM:

A bug has been found on NETCF v2 and v35 that affects HTTPS web requests from Windows Mobile 6 devices

# Tony said on November 27, 2007 9:58 AM:

When can we expect the source posted?

# andarno said on November 27, 2007 5:04 PM:

In response to several suggestions that this only occurs on WM6 (and that WM5 and earlier are fine), the answer seems to be from my tests that <i>all</i> platforms are capable of producing this error, but WM6 is more likely to produce the error that earlier platforms.

# Alfred said on November 28, 2007 6:37 PM:

Does IIS send out these empty packets, and if so, can it be configured so that it doesn't?

# andarno said on November 30, 2007 1:05 PM:

Tony, The source is posted now.

Alfred, IIS has been observed to generate these empty packets in some scenarios, but I can't yet accurately predict which scenarios those are.  One tip to try though: ignoring client certificates (as opposed to requesting or requiring them) has been suggested by a customer as a way to keep IIS from generating them.  This hasn't been verified yet though.

# Alex said on December 5, 2007 8:30 AM:

Is there anywhere an announcement of MS about this issue?

I need to update our customer that bought WM6 devices, and I want to sent them something official.

# andarno said on December 22, 2007 12:50 PM:

Alex,

No official announcement from MS about this issue as far as a KB article.  The team's link to this blog is the closest thing.  http://blogs.msdn.com/netcfteam/archive/2007/11/21/why-net-compact-framework-fails-to-call-some-https-web-servers.aspx

# mtubigdog said on January 4, 2008 11:06 PM:

Do we have any idea how long a patch for .NET Compact Framework is down the road?  We rely on an application that uses this code to sync many mobile phones, and all new phones are shipping with WM6 now and even our WM5 phones that get updated are dying off now.  Becoming a pretty big problem for our institution.

# Oren said on January 20, 2008 4:51 AM:

Is there any patch that fix this issue?

# andarno said on February 7, 2008 3:59 PM:

At the moment, the only planned fixes for this will be released with 3.5 SP1 and any subsequent version.  No hotfix is scheduled, but those plans may change with sufficient customer need.

# Peter said on February 8, 2008 7:29 AM:

I'm having this problem as well, please fix this asap ;)

I think I'll try to write my own client side proxy, maybe learn a few things while doing so...

# Richard said on February 13, 2008 10:38 AM:

Where do we make the requests for a hotfix then?  I am sure I have this problem too but it is not constant.  I will definately confirm this but if I find it is where can I submit my vote for a fix?

Thanks

# ariel said on February 17, 2008 10:07 PM:

i also encountered this problem almost a year ago and couldn't find a solution. 4 months later i tested my app on a different server and did not experience that problem again.

# Nick said on February 19, 2008 10:23 AM:

Where do we sign up to inform MS of this sufficient customer need? :)

# DarkChuky said on February 20, 2008 4:12 PM:

Hi, I have tested 2 version of the WM6 Emulator, in the old one I have the same bug, but with the newest the problem is gone... But now I'm testing a PDA (Workabout Pro PSION) and it has the same problem... does anybody know a patch for WM6 that can solve the problem? (DarkChuky@hotmail.com). Thanks Andrew, your article gives me the basic for the problem!

# Victor said on March 10, 2008 11:39 PM:

you need stop the windows service "IPSEC Service" on the machine on which your WebService is deployed .

Leave a Comment

(required) 
(optional)
(required) 

Search

Go

This Blog

Interesting blogs

Related sites

Syndication

Page view tracker