Bug 8883 - Logging out causes handling ssl certificate issue
Summary: Logging out causes handling ssl certificate issue
Status: RESOLVED NOT_REPRODUCIBLE
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 6.1.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Future Cycle (TBD)
Assignee: Sebastien Pouliot
URL:
Depends on:
Blocks:
 
Reported: 2012-12-11 11:02 UTC by Allie Miller
Modified: 2016-10-18 18:10 UTC (History)
5 users (show)

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

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 NOT_REPRODUCIBLE

Description Allie Miller 2012-12-11 11:02:19 UTC
Using an application that opens sslStream, the code runs on both desktop client and iPhone. The problem only manifests on iPhone

Version information:
MonoTouch 6.0.6
MonoDevelop 3.0.4.7
Mono 2.10.9


Below is the code snippet to get SSLStream:

private System.IO.Stream getSSLStream(TcpClient socket)

{

SslStream sslStream = null;

try

{

sslStream = new SslStream(

socket.GetStream(),

false,

new RemoteCertificateValidationCallback(ValidateServerCertificate),

null

);

}

catch (Exception e)

{

Console.logStackTrace(e);

}

String serverName = getServerName();

try

{

sslStream.AuthenticateAsClient(serverName);

showSslInfo(serverName, sslStream, true);

}

catch (AuthenticationException e)

{

Console.log(e.Message, LogConst.EXCEPTIONS);

Console.logStackTrace(e);

socket.Close();

sslStream.Close();

}

catch (Exception e)

{

Console.log(e.Message, LogConst.EXCEPTIONS);

Console.logStackTrace(e);

socket.Close();

sslStream.Close();

}

return sslStream;

}

When the app runs the first time, everything is fine. When you logout and login again, the iPhone code choked on showSslInfo(serverName, sslStream, true) resides inside System.IO.Stream getSSLStream(TcpClient socket) method

Following is the code snippet for showSslInfo and showCertificateInfo:

private void showSslInfo(string serverName, SslStream sslStream, bool verbose)

{

showCertificateInfo(sslStream.RemoteCertificate, verbose);

Console.log("\n\nSSL Connect Report for : " + serverName, LogConst.VERBOSE);

Console.log("Is Authenticated: " + sslStream.IsAuthenticated, LogConst.VERBOSE);

Console.log("Is Encrypted: " + sslStream.IsEncrypted, LogConst.VERBOSE);

Console.log("Is Signed: " + sslStream.IsSigned, LogConst.VERBOSE);

Console.log("Is Mutually Authenticated: \n" + sslStream.IsMutuallyAuthenticated, LogConst.VERBOSE);

Console.log("Hash Algorithm: " + sslStream.HashAlgorithm, LogConst.VERBOSE);

Console.log("Hash Strength: " + sslStream.HashStrength, LogConst.VERBOSE);

Console.log("Cipher Algorithm: " + sslStream.CipherAlgorithm, LogConst.VERBOSE);

Console.log("Cipher Strength: \n" + sslStream.CipherStrength, LogConst.VERBOSE);

Console.log("Key Exchange Algorithm: " + sslStream.KeyExchangeAlgorithm, LogConst.VERBOSE);

Console.log("Key Exchange Strength: \n" + sslStream.KeyExchangeStrength, LogConst.VERBOSE);

Console.log("SSL Protocol: " + sslStream.SslProtocol, LogConst.VERBOSE);
}

private void showCertificateInfo(X509Certificate remoteCertificate, bool verbose)

{

Console.log("Certficate Information for:\n\n" + remoteCertificate.Subject, LogConst.VERBOSE);

Console.log("Valid From: \n" + remoteCertificate.GetEffectiveDateString(), LogConst.VERBOSE);

Console.log("Valid To: \n" + remoteCertificate.GetExpirationDateString(), LogConst.VERBOSE);

Console.log("Certificate Format: \n\n" + remoteCertificate.GetFormat(), LogConst.VERBOSE);

Console.log("Issuer Name: \n" + remoteCertificate.Issuer, LogConst.VERBOSE);

if (verbose)

{

Console.log("Serial Number: \n" + remoteCertificate.GetSerialNumberString(), LogConst.VERBOSE);

Console.log("Hash: \n" + remoteCertificate.GetCertHashString(), LogConst.VERBOSE);

Console.log("Key Algorithm: \n" + remoteCertificate.GetKeyAlgorithm(), LogConst.VERBOSE);

Console.log("Key Algorithm Parameters: \n" + remoteCertificate.GetKeyAlgorithmParametersString(), LogConst.VERBOSE);

Console.log("Public Key: \n" + remoteCertificate.GetPublicKeyString(), LogConst.VERBOSE);

}

}

If you logout and login again, in the showCertificateInfo(X509Certificate remoteCertificate, bool verbose). Somehow the remoteCertificate is null. Right now I can get around the problem by added check if (remoteCertificate != null)

Then it displays the information. But that does not explain why if you logout and login again the remoteCertifcate will become null. When the iPhone client first login the remoteCertificate is not null…..



2. The second related issue is when you try to report in MonoTouch’s sslStream.KeyExchangeStrength, the SslStreamBase.cs

3. public int KeyExchangeStrength

4. {

5. get

6. {

7. if (this.context.HandshakeState == HandshakeState.Finished)

8. {

9. return this.context.ServerSettings.Certificates[0].RSA.KeySize;

10. }

11. 

12. return 0;

13. }

14. }



Since the Certificate[0] could be null. So the app have null reference here. I think the above code should check

If (this.context.ServerSettings.Certificates[0] != null)

Then return the keySize
Comment 1 Sebastien Pouliot 2012-12-17 09:34:15 UTC
1. there's no concept of 'login' and 'logout' in SSL/TLS. 

However SSL/TLS sessions can be cached (if the server allows it) to resume a pre-existing encrypted channel quickly. *Maybe* some properties are not available/updated under that condition.


2. That condition should not occur

> Since the Certificate[0] could be null.

since the handshare cannot be completed (Finished state) without a certificate. However maybe the caching (1) interfere with this.


I'll look* if I can reproduce that. 

* The general issue with SSL/TLS is that it's a negotiation between the client (MT code) and the server (3rd party code + custom configuration) so some conditions are not easily reproducable without a full test case.
Comment 3 PJ 2013-11-19 16:44:38 UTC
This bug was targeted for a past milestone, moving to the next non-hotfix active milestone.
Comment 4 GouriKumari 2016-01-11 20:37:31 UTC
Moving the mile stone to "far future".
Comment 5 Sebastien Pouliot 2016-10-18 18:10:13 UTC
Closing. This condition could not be reproduce (a long time ago) and the MonoTLS code base is being deprecated in favour of AppleTLS.