Bug 19608 - On Xamarin.Android, avoid throwing & catching unused "Store Root doesn't exists" and "Store CA doesn't exists" exceptions
Summary: On Xamarin.Android, avoid throwing & catching unused "Store Root doesn't exis...
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 4.13.x
Hardware: PC Mac OS
: Normal enhancement
Target Milestone: ---
Assignee: Marek Habersack
URL:
Depends on:
Blocks:
 
Reported: 2014-05-07 23:28 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2016-05-03 02:39 UTC (History)
10 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Full call stacks for exceptions (5.43 KB, text/plain)
2014-05-07 23:28 UTC, Brendan Zagaeski (Xamarin Team, assistant)
Details
Patch: simple but indelicate workaround (1.85 KB, patch)
2014-05-15 14:12 UTC, Brendan Zagaeski (Xamarin Team, assistant)
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Brendan Zagaeski (Xamarin Team, assistant) 2014-05-07 23:28:07 UTC
Created attachment 6754 [details]
Full call stacks for exceptions

Currently the TLS handshake process on Xamarin.Android always throws and catches a few exceptions. This is explained briefly in https://bugzilla.xamarin.com/show_bug.cgi?id=12106#c5.

If it wouldn't cause problems for any existing apps, maybe these exceptions could be avoided entirely? This might also help with any future investigation of bug #12106 or similar bugs. Perhaps the "Store [Root/CA] doesn't exists" errors were actually a red herring on that case.


## Possible fix?

Maybe the calls to `collection.AddRange()` in `System.Security.Cryptography.X509Certificates.X509Chain.CertificateCollection` can be skipped on Monodroid:

> #if !MONODROID
> 					collection.AddRange (Roots);
> 					collection.AddRange (CertificateAuthorities);
> #endif


This stops the exception messages for the test case described below, although it also changes the behavior of `Mono.Security.X509.X509Chain.Build()`.


## Another possibility

It's not strictly necessary to throw out `Roots` and `CertificateAuthorities`. Another way to prevent the exceptions for the "User" stores is simply to create empty directories in the app's data directory:

> /data/data/com.example.myapp/files/.config/.mono/certs/Trust
> /data/data/com.example.myapp/files/.config/.mono/certs/CA

These correspond to the `Mono.Security.X509.X509StoreManager.CurrentUserPath` stores, and allow `X509Store.Open()` to run without exceptions.


### The "LocalMachine" stores

On the other hand, at the moment it is _not_ possible to create empty directories for the local machine stores on Android. The problem is that..

`Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData)` returns:
> "/usr/share"

so

`Mono.Security.X509.X509StoreManager.LocalMachinePath` returns:
> "/usr/share/.mono/certs"


... and the `/usr` directory doesn't exist on Android.


If `Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData)` [1] instead returned a writable location, the same empty-folder workaround could be applied to the "LocalMachine" stores.


> [1] https://github.com/mono/mono/blob/c8d91bc505446f3d017f238250e6de608b603110/mcs/class/corlib/System/Environment.cs#L704-L705



## Steps to reproduce

1. Create a new Android application.


2. Add a line to connect to a TLS web server via `WebClient`:

> new WebClient().DownloadString("https://www.google.com");


3. Run the app in the Debug configuration with the IDE set to break on all exceptions.



## Result

The IDE breaks as each of 4 exceptions are thrown (and caught):

> System.Security.Cryptography.CryptographicException: Store Root doesn't exists.
(LMRootStore)

> System.Security.Cryptography.CryptographicException: Store Root doesn't exists.
(UserRootStore)

> System.Security.Cryptography.CryptographicException: Store CA doesn't exists.
(LMCAStore)

> System.Security.Cryptography.CryptographicException: Store CA doesn't exists.
(UserCAStore)

(Full call stacks attached)


If you run the connection a second time, the app can usually perform an abbreviated TLS handshake, so it does not need to repeat the `Mono.Security.X509.X509Chain.Build()` process, and these exceptions do not occur.




Many thanks!
Comment 2 Brendan Zagaeski (Xamarin Team, assistant) 2014-05-15 14:12:35 UTC
Created attachment 6823 [details]
Patch: simple but indelicate workaround

(Based on Mono commit fcf29c0)

Disregard the original proposed "Possible fix". That wasn't general enough.

Really, the way to avoid the exceptions completely would be to remove the 4 method calls that try to load the various stores (attached patch).

That prevents the exceptions from being thrown, but also means that users will _not_ be able to use the normal API to load items from the "User" or "Local Machine" stores. This definitely breaks expected .NET behavior, so the "Another possibility" fix might be preferable.
Comment 3 Nate Cook 2014-08-14 02:19:33 UTC
This is really annoying behavior! Please stop throwing certificate exceptions on Android! I can't keep a catch-all-exceptions breakpoint enabled with this behavior on Android.
Comment 4 Jonathan Pryor 2014-12-05 11:46:20 UTC
> I can't keep a catch-all-exceptions breakpoint enabled 

How can you reasonably have that enabled anyway? (Rephrased: why do you have this enabled?)

It is not uncommon for libraries to internally throw and catch exceptions, and "catch all exceptions" will cause you to "break" in the debugger even if the exception is handled, and thus isn't something you need to worry about.

If you include any 3rd party code of any sort, this can possibly happen, and I don't think that requiring 3rd parties avoid use of `catch` blocks is tenable.
Comment 5 Nate Cook 2014-12-05 11:55:40 UTC
Jonathan, a catch all exceptions breakpoint is a great debugging tool, and its usage is in fact mentioned as a nice feature of Xamarin Studio (most recently at the Evolve conference by Mark Hutchinson). I can say that it is very useful at times. Is there no way to make it ignore exceptions that are thrown by system libraries? i.e. some sort of "Just My Code" aspect a la Visual Studio?
Comment 6 Reza 2015-01-12 19:01:36 UTC
Jonathan, I completely agree with Nate.

Although one thing that I would add is that it occurs in Visual Studio even when the "Just My Code" feature is enabled!!!

Having handled exceptions stop in the debugger allows a developer to see all exceptions being thrown within an application and is extremely useful when you need to pinpoint an exception before it is gobbled up by some exception handler.  True you can get this from logs, etc, but a debugger always gives you far more information regarding the state of the application at the time an exception occurs.  I.E.  It doesn't need to be unhandled for it to be interesting.

Unfortunately, somehow it seems as though internal library exceptions are actually thrown back in the debugger when debugging a Xamarin app, regardless of whether or not the "Just My Code" is enabled.  I can only assume it is because it goes through unmanaged code.  According to Microsoft, checking 'Thrown' in the Exceptions dialog when 'Just My Code' is enabled should only cause the debugger to stop when either user code throws the exception, or when system code throws the exception back to user code. In other words, the debugger should not stop for internal exceptions within code where no source exists.
Comment 7 Nate Cook 2015-01-12 21:43:40 UTC
Hear, hear

This still bugs me on an almost daily basis. (I have to continually enable and disable the catch all breakpoint, depending on the type of debugging I am doing.)
Comment 8 Nate Cook 2015-02-27 19:06:42 UTC
Related bug:
https://bugzilla.xamarin.com/show_bug.cgi?id=9615
Comment 9 Andy 2015-12-18 15:29:41 UTC
This has become a problem since upgrading to Xamarin 6.0.0.41.  Prior to this I had never seen this exception before.

Exception:

System.Security.Cryptography.CryptographicException: Store Root doesn't exists.

Exception:

System.Security.Cryptography.CryptographicException: Store Root doesn't exists.


I have set Visual Studio to never break on exceptions so not sure why it is now doing this?
Comment 10 FieldstrikeMobile 2016-02-02 10:32:38 UTC
I'm sure this bug is affecting all my Https requests as well.

I am calling a WCF service using Https and these exceptions are fireing all over the place and make my service fail.

Adding this:

            ServicePointManager.ServerCertificateValidationCallback += delegate
            {
                return true;
            };

to MainActivity and AppDelegate has fixed it but I don't think this should be permanent because its accepting certificates for https blindly
Comment 11 Nicholas Ventimiglia 2016-02-08 05:54:17 UTC
Ran into this. ServicePointManager not helping. Please advise ?
Comment 12 adrien.padol 2016-02-23 16:59:23 UTC
Any updates on this ? It is super annoying when debugging to have to click a thousand times on "Continue" because VS keep prompting for handled exceptions ...
Comment 13 FieldstrikeMobile 2016-02-23 17:04:24 UTC
I second @Adrien.padol's point. this is SUPER! annoying
Comment 14 Andy 2016-02-23 17:05:51 UTC
I've been struggling with this since December and am surprised more people haven't been affected by it
Comment 15 Nate Cook 2016-02-23 17:11:17 UTC
I wonder if this will be taken care of with https://bugzilla.xamarin.com/show_bug.cgi?id=9615

I think Target Milestone C7 = Xamarin Studio 6 (Roslyn)
Comment 16 adrien.padol 2016-02-23 17:49:17 UTC
@Andy it seems to only affect some exceptions. In my project I face this with the System.Security.Cryptography exceptions, and also when a task gets cancelled (after a timeout for example), but it doesn't seem to occur for more "regular" exceptions.
Comment 17 adrien.padol 2016-02-24 16:12:17 UTC
After upgrading to the "Alpha" channel of the Xamarin Visual Studio Extension, the bug does not occur for the System.Security.Cryptography exceptions.


Yet it still occurs with other kinds of exceptions.
I mentioned in my previous comment that it also occurs with a TaskCancelledException and it is still the case.
Comment 18 adrien.padol 2016-03-02 15:13:54 UTC
It seems that a possible workaround for this, is to use the "Reset to default" button in Visual Studio Exceptions panel.

I'd like to check if someone else is capable of confirming that.

In my case after hitting the "reset to default" button the exception popups stopped
Comment 19 FieldstrikeMobile 2016-03-02 15:18:10 UTC
@adrien.padol

"Reset To Default" resets Visual Studio Exception Settings to Default (Which means exception boxes dont appear when exepctions are THROWN. Only when UNHANDLED)

When debugging your application it is often good to change the exception settings to show ALL exceptions that are THROWN (regardless of whether they are handled or not) to get to the root cause of your problem, not just the exception that was unhandled.

But changing these default exception settings results in the exception outlined in the bug being thrown a ridiculous amount of times, rendering the feature useless. Hence why this bug has been raised
Comment 22 Brendan Zagaeski (Xamarin Team, assistant) 2016-03-07 19:59:45 UTC
## "Verification" status: "verified fixed" on the Cycle 7 Alpha 1 Preview

Somewhat "by luck," the exact issue with "CryptographicExceptions" as described in Comment 0 no longer happens with the current Alpha channel "Cycle 7 Preview" builds of Xamarin.Android. Specifically the Cycle 7 builds no longer call the `X509Chain.Build()` method that was throwing and catching those exceptions. `SslClientStream` [1] now instead uses a different implementation of `ChainValidationHelper` that does not call that method.

[1] https://github.com/mono/mono/commit/25a206c6dac1cf79d91b92a279cad86428ee4d95


### Comparison of 2 specific versions

Xamarin.Android 6.0.99.544 (8f34ab4): TLS verification does _not_ call `X509Chain.Build()`

Xamarin.Android 6.0.1.10   (e98e962): TLS verification _does_ call `X509Chain.Build()`




## New bugs for the _more general_ behavior of "break on all thrown exceptions" combined with "Just My Code"


### Visual Studio

I have filed a new detailed bug report to discuss the behavior of the debugger when both "break on all thrown exceptions" and "Just My Code" are enabled in Visual Studio:

- Bug 39345


### Xamarin Studio

I have also filed a corresponding bug report for Xamarin Studio (where the "Just My Code" option is named "Debug project code only"):

- Bug 39346


Bug 39346 already has an update from the engineering team about some fixes that will be needed in the Mono soft debugger agent to allow this behavior to work as desired.




## Setting status to RESOLVED

Since the "CryptographicException" issue from Comment 0 no longer occurs as of the Cycle 7 builds, and since the more general behavior related to "break on all exceptions" + "Just My Code" now has its own bug reports, I will mark this bug as RESOLVED to direct any further discussion and updates onto the new bug reports.



Best,
Brendan
Xamarin Customer Support