{"id":363,"date":"2007-11-19T17:18:04","date_gmt":"2007-11-19T17:18:04","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/andrewarnottms\/2007\/11\/19\/why-net-compact-framework-fails-to-call-some-https-web-servers\/"},"modified":"2019-04-03T22:26:39","modified_gmt":"2019-04-04T05:26:39","slug":"why-net-compact-framework-fails-to-call-some-https-web-servers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/why-net-compact-framework-fails-to-call-some-https-web-servers\/","title":{"rendered":"Why .NET Compact Framework fails to call some HTTPS web servers"},"content":{"rendered":"<p>A bug was discovered recently in the .NET Compact Framework version 2.0 (SP2 and earlier) and 3.5 that causes HttpWebRequest&#8217;s directed at some HTTPS servers to fail with this error: (for web services)<\/p>\n<p>System.Net.WebException: Unable to read data from the transport connection. &#8212;&gt; System.Net.Sockets.SocketException: Unknown error (0x0).    <br>&nbsp;&nbsp; at System.Net.HttpWebRequest.fillBuffer(HttpWebRequest request, Connection connection, CoreResponseData data)     <br>&nbsp;&nbsp; at System.Net.HttpWebRequest.getLine(HttpWebRequest request, Connection connection, CoreResponseData data)     <br>&nbsp;&nbsp; at System.Net.HttpWebRequest.parseResponse(HttpWebRequest request, Connection connection, Boolean defaultKeepAlive)     <br>&nbsp;&nbsp; at System.Net.HttpWebRequest.startReceiving(Connection connection)     <br>&nbsp;&nbsp; at System.Net.Connection.startReceiving(Object ignored)     <br>&nbsp;&nbsp; at System.Threading.ThreadPool.WorkItem.doWork(Object o)     <br>&nbsp;&nbsp; at System.Threading.Timer.ring() <\/p>\n<p>&nbsp;&nbsp; at System.Net.HttpWebRequest.finishGetResponse()    <br>&nbsp;&nbsp; at System.Net.HttpWebRequest.GetResponse()     <br>&nbsp;&nbsp; \/\/ &#8230;     <br>&nbsp;&nbsp; at Program.Main(String[] args)<\/p>\n<p>For standard HttpWebRequest calls from your app the stack trace would be different, although the exception message and cause would be the same.<\/p>\n<p>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.&nbsp; Here is an illustration of the encryption process that occurs on the server for HTTPS:<\/p>\n<p>First, a memory buffer is initialized with unencrypted data that the server wants to send to the client over the network.<\/p>\n<table cellspacing=\"0\" cellpadding=\"2\" width=\"400\" border=\"1\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"99\">Step 1: <\/td>\n<td valign=\"top\" width=\"99\">&nbsp;<\/td>\n<td valign=\"top\" width=\"132\">unencrypted data<\/td>\n<td valign=\"top\" width=\"68\">&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Next, the server makes a call to <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa375378.aspx\">EncryptMessage<\/a> and the unencrypted data is encrypted in place.&nbsp; A header and footer is added to the buffer:<\/p>\n<table cellspacing=\"0\" cellpadding=\"2\" width=\"400\" border=\"1\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"99\">Step 2: <\/td>\n<td valign=\"top\" width=\"99\">header<\/td>\n<td valign=\"top\" width=\"132\">encrypted data<\/td>\n<td valign=\"top\" width=\"68\">footer<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This header if 5 bytes long, and the footer is several more bytes.&nbsp; 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 <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa375211.aspx\">DecryptMessage<\/a>.<\/p>\n<p>The trouble with NetCF&#8217;s SSL stack is when the server encrypts a buffer of <em>zero length<\/em> and sends it to the client:<\/p>\n<table cellspacing=\"0\" cellpadding=\"2\" width=\"400\" border=\"1\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"99\">Step 1: <\/td>\n<td valign=\"top\" width=\"99\">&nbsp;<\/td>\n<td valign=\"top\" width=\"132\">0 bytes of unencrypted data<\/td>\n<td valign=\"top\" width=\"68\">&nbsp;<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"99\">Step 2:<\/td>\n<td valign=\"top\" width=\"99\">header<\/td>\n<td valign=\"top\" width=\"132\">encrypted representation of a zero-length buffer<\/td>\n<td valign=\"top\" width=\"68\">footer<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Although the original data had a length of zero, the encrypted version of it actually has a non-zero length.&nbsp; 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.&nbsp; 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.&nbsp; Because NetCF will return an empty buffer after decrypting an &#8220;empty&#8221; encryption packet, the caller may misinterpret this as a sign of a disconnected socket and terminate the connection.<\/p>\n<p>In fact this is exactly what happens in NetCF&#8217;s web services code when calling services over SSL that respond with empty encryption packets.&nbsp; As a result the connection fails before the response is fully received and an exception is thrown.<\/p>\n<p>What causes the server to send these empty encryption packets?&nbsp; Technically it&#8217;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.<\/p>\n<p>Unfortunately there is no way to get NetCF to ignore these packets, so the only workarounds are these, in order of simplicity:<\/p>\n<ol>\n<li>Don&#8217;t use SSL to make your request (security implications here of course by sending your request and its response in clear text) <\/li>\n<li>Reconfigure your existing server in some way to get it to avoid generating these empty encryption packets. <\/li>\n<li>Build a new web server that will forward your device&#8217;s requests on a separate connection to the ultimate target server and forward the responses back to the device.&nbsp; This would work for web sites and web services.&nbsp; But this new front-end server (which serves something of the role of a proxy server) would have to be configured to <em>not <\/em>generate these empty encryption packets. <\/li>\n<li><strong>[Added 1\/2\/08] <\/strong>Build a device-side web proxy that calls into the SSPI functions itself (native would probably be easier than managed for this).&nbsp; Then have your managed app call into the proxy.&nbsp; 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. <\/li>\n<li>Wait until a future version of NetCF that fixes this bug. <\/li>\n<li>Write your own HTTPS client using native code or P\/Invoke&#8217;ing from NetCF (difficult to get right). <\/li>\n<\/ol>\n<p>So how do you know for sure if the HTTPS server is sending empty encryption packets that are causing your NetCF clients to fail?&nbsp; I wrote a native C++ app that calls a web server on an HTTPS connection and detects these packets.&nbsp; (No, I&#8217;m afraid it can&#8217;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.&nbsp; At least then you know what&#8217;s going on.<\/p>\n<p><strong>[Updated Feb 1, 2008]<\/strong> You can download the source code from its <a href=\"http:\/\/code.msdn.microsoft.com\/emptysslpackets\">resource page on the MSDN Code Gallery<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A bug was discovered recently in the .NET Compact Framework version 2.0 (SP2 and earlier) and 3.5 that causes HttpWebRequest&#8217;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. &#8212;&gt; System.Net.Sockets.SocketException: Unknown error (0x0). &nbsp;&nbsp; at System.Net.HttpWebRequest.fillBuffer(HttpWebRequest request, Connection connection, CoreResponseData data) [&hellip;]<\/p>\n","protected":false},"author":2685,"featured_media":37840,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[4617,3917,3918,383],"class_list":["post-363","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-permierdev","tag-andarno","tag-mobile-devices","tag-netcf","tag-wcf"],"acf":[],"blog_post_summary":"<p>A bug was discovered recently in the .NET Compact Framework version 2.0 (SP2 and earlier) and 3.5 that causes HttpWebRequest&#8217;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. &#8212;&gt; System.Net.Sockets.SocketException: Unknown error (0x0). &nbsp;&nbsp; at System.Net.HttpWebRequest.fillBuffer(HttpWebRequest request, Connection connection, CoreResponseData data) [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/2685"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=363"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/363\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/37840"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}