Skip to content

Commit

Permalink
Fixed #864 (Android self signed cert replication) in a different way …
Browse files Browse the repository at this point in the history
…since the last way turned out to be nonsense.
  • Loading branch information
borrrden committed Oct 11, 2017
1 parent 76ef883 commit 13fb8ef
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/Couchbase.Lite.Android/Couchbase.Lite.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>DynamicAssemblyInfo.tt</DependentUpon>
</Compile>
<Compile Include="CouchbaseAndroidClientHandler.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="SecureStorageAES.cs" />
<Compile Include="SecureStorageRSA.cs" />
Expand Down
79 changes: 79 additions & 0 deletions src/Couchbase.Lite.Android/CouchbaseAndroidClientHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// CouchbaseAndroidClientHandler.cs
//
// Author:
// Jim Borden <[email protected]>
//
// Copyright (c) 2017 Couchbase, Inc All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

using System;
using Java.Security;
using Java.Security.Cert;
using Javax.Net.Ssl;
using Xamarin.Android.Net;

namespace Couchbase.Lite
{
internal sealed class CouchbaseAndroidClientHandler : AndroidClientHandler
{
public bool AllowSelfSigned { get; set; }

protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
{
return AllowSelfSigned ? SelfSignedSocketFactory() : base.ConfigureCustomSSLSocketFactory(connection);
}

protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
{
return AllowSelfSigned ? new IgnoreHostnameVerifier() : base.GetSSLHostnameVerifier(connection);
}

private static SSLSocketFactory SelfSignedSocketFactory()
{
var trustManager = new SelfSignedTrustManager();
var sslContext = SSLContext.GetInstance("TLS");
sslContext.Init(null, new[] {trustManager}, null);
return sslContext.SocketFactory;
}

private sealed class IgnoreHostnameVerifier : Java.Lang.Object, IHostnameVerifier
{
public bool Verify(string hostname, ISSLSession session)
{
return true;
}
}

private sealed class SelfSignedTrustManager : Java.Lang.Object, IX509TrustManager
{

public void CheckClientTrusted(X509Certificate[] chain, string authType)
{

}

public void CheckServerTrusted(X509Certificate[] chain, string authType)
{

}

public X509Certificate[] GetAcceptedIssuers()
{
return new X509Certificate[0];
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ internal static void SetupSslCallback()
/// Build a pipeline of HttpMessageHandlers.
/// </summary>
#if __ANDROID__
internal HttpMessageHandler BuildHandlerPipeline(CookieStore store, IRetryStrategy retryStrategy, Java.Security.Cert.Certificate selfSignedCert)
internal HttpMessageHandler BuildHandlerPipeline(CookieStore store, IRetryStrategy retryStrategy, bool allowSelfSigned)
#else
internal HttpMessageHandler BuildHandlerPipeline (CookieStore store, IRetryStrategy retryStrategy)
#endif
Expand All @@ -149,14 +149,11 @@ internal HttpMessageHandler BuildHandlerPipeline (CookieStore store, IRetryStrat
var handler = default(HttpClientHandler);
#if __ANDROID__
if (global::Android.OS.Build.VERSION.SdkInt >= global::Android.OS.BuildVersionCodes.Lollipop) {
handler = new Xamarin.Android.Net.AndroidClientHandler
handler = new CouchbaseAndroidClientHandler
{
UseCookies = false,
AllowSelfSigned = allowSelfSigned,
UseCookies = false
};

if(selfSignedCert != null) {
((Xamarin.Android.Net.AndroidClientHandler)handler).TrustedCerts = new List<Java.Security.Cert.Certificate> { selfSignedCert };
}
} else
#endif
{
Expand Down Expand Up @@ -186,13 +183,13 @@ internal HttpMessageHandler BuildHandlerPipeline (CookieStore store, IRetryStrat
}

#if __ANDROID__
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy, Java.Security.Cert.Certificate selfSignedCert)
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy, bool allowSelfSigned)
#else
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy)
#endif
{
#if __ANDROID__
var authHandler = BuildHandlerPipeline(cookieStore, retryStrategy, selfSignedCert);
var authHandler = BuildHandlerPipeline(cookieStore, retryStrategy, allowSelfSigned);
#else
var authHandler = BuildHandlerPipeline(cookieStore, retryStrategy);
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/Couchbase.Lite.Shared/Replication/RemoteSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public void Setup(ReplicationOptions options)
_remoteRequestCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token);
ClientFactory.SocketTimeout = options.SocketTimeout;
#if __ANDROID__
var clientObj = ClientFactory.GetHttpClient(CookieStore, options.RetryStrategy, options.TrustedServerCert);
var clientObj = ClientFactory.GetHttpClient(CookieStore, options.RetryStrategy, options.AllowSelfSigned);
#else
var clientObj = ClientFactory.GetHttpClient(CookieStore, options.RetryStrategy);
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/Couchbase.Lite.Shared/Replication/ReplicationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ public TimeSpan Heartbeat

#if __ANDROID__
/// <summary>
/// Sets an X509 certificate that is unconditionally trusted, even if it would fail
/// otherwise (e.g. self signed). Useful for development, not recommended for production.
/// *DO NOT USE FOR PRODUCTION* (Android-only) sets up a replication to ignore SSL verification
/// so that a self signed certificate may be used for TLS.
/// </summary>
public Java.Security.Cert.Certificate TrustedServerCert { get; set; }
public bool AllowSelfSigned { get; set; }

#endif

Expand Down
2 changes: 1 addition & 1 deletion src/Couchbase.Lite.Shared/Util/IHttpClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal interface IHttpClientFactory
{
// Create an HTTP client based on the cookie store
#if __ANDROID__
CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy, Java.Security.Cert.Certificate selfSignedCert);
CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy, bool allowSelfSigned);
#else
CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy retryStrategy);
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public AlwaysFailingClientFactory()
}

#if __ANDROID__
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy, Java.Security.Cert.Certificate cert)
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy, bool allowSelfSigned)
#else
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy)
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public MockHttpClientFactory(Database db, bool defaultFail = true)
}

#if __ANDROID__
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy, Java.Security.Cert.Certificate cert)
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy, bool allowSelfSigned)
#else
public CouchbaseLiteHttpClient GetHttpClient(CookieStore cookieStore, IRetryStrategy strategy)
#endif
Expand Down

0 comments on commit 13fb8ef

Please sign in to comment.