Skip to content

Commit

Permalink
[Azure] fix Android API_8 SSL issue (rather than hack)
Browse files Browse the repository at this point in the history
  • Loading branch information
conceptdev committed Sep 9, 2012
1 parent 5c9bffd commit 8d82c0a
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 20 deletions.
101 changes: 84 additions & 17 deletions Azure/Android/AzureWebService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
using System.Net;
using System.Json;

using System.Security;
using System.Security.Cryptography;
using Java.Security;
using Java.Security.Cert;
using Android;
using Android.Runtime;
using Javax.Net.Ssl;

namespace Azure
{
/// <summary>
Expand All @@ -14,8 +22,8 @@ namespace Azure
public static class AzureWebService
{

static string subdomain = "xxxxxxx"; // your subdomain
static string MobileServiceAppId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // your application key
static string subdomain = "xxxxxxx"; // your subdomain
static string MobileServiceAppId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // your application key

static string GetAllUrl = "https://" + subdomain + ".azure-mobile.net/tables/TodoItem"; //?$filter=(complete%20eq%20false)
static string GetUrl = "https://" + subdomain + ".azure-mobile.net/tables/TodoItem?$filter=(id%20eq%20{0})";
Expand All @@ -30,7 +38,9 @@ public static List<Task> LoadTodos(Action<List<Task>> whenDone )
var tasks = new List<Task>();
WebClient client = new WebClient();
try {
ServicePointManager.CertificatePolicy = new NoCheck(); // HACK: sorry, quick hack around SSL cert issue
// HACK: Android issue - see Validator method declaration
ServicePointManager.ServerCertificateValidationCallback = Workaround.Validator;

// make it synchronous
client.Headers.Add (HttpRequestHeader.Accept, "application/json");
client.Headers.Add ("X-ZUMO-APPLICATION", MobileServiceAppId);
Expand Down Expand Up @@ -69,8 +79,10 @@ public static Task GetTodo(int id)
Task task = null;
WebClient client = new WebClient();
try {
ServicePointManager.CertificatePolicy = new NoCheck(); // HACK: sorry, quick hack around SSL cert issue
// make it synchronous
// HACK: Android issue - see Validator method declaration
ServicePointManager.ServerCertificateValidationCallback = Workaround.Validator;

// make it synchronous
client.Headers.Add(HttpRequestHeader.Accept, "application/json");
client.Headers.Add("X-ZUMO-APPLICATION", MobileServiceAppId);
var response = client.DownloadData(String.Format(GetUrl, id)); // GET
Expand Down Expand Up @@ -104,7 +116,9 @@ public static void UpdateTodo(Task t)
{
WebClient client = new WebClient();
try {
ServicePointManager.CertificatePolicy = new NoCheck(); // HACK: sorry, quick hack around SSL cert issue
// HACK: Android issue - see Validator method declaration
ServicePointManager.ServerCertificateValidationCallback = Workaround.Validator;

// make it synchronous
client.Headers.Add (HttpRequestHeader.Accept, "application/json");
client.Headers.Add (HttpRequestHeader.ContentType, "application/json");
Expand All @@ -131,7 +145,9 @@ public static void AddTodo(Task t)
{
WebClient client = new WebClient();
try {
ServicePointManager.CertificatePolicy = new NoCheck(); // HACK: sorry, quick hack around SSL cert issue
// HACK: Android issue - see Validator method declaration
ServicePointManager.ServerCertificateValidationCallback = Workaround.Validator;

// make it synchronous
client.Headers.Add (HttpRequestHeader.Accept, "application/json");
client.Headers.Add (HttpRequestHeader.ContentType, "application/json");
Expand All @@ -157,7 +173,9 @@ public static void DeleteTodo(Task t)
{
WebClient client = new WebClient();
try {
ServicePointManager.CertificatePolicy = new NoCheck(); // HACK: sorry, quick hack around SSL cert issue
// HACK: Android issue - see Validator method declaration
ServicePointManager.ServerCertificateValidationCallback = Workaround.Validator;

// make it synchronous
client.Headers.Add(HttpRequestHeader.Accept, "application/json");
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
Expand All @@ -176,16 +194,65 @@ public static void DeleteTodo(Task t)
}
}

/// <summary>
/// HACK: sorry, quick hack around SSL cert issue
/// </summary>
class NoCheck : ICertificatePolicy {
// /// <summary>
// /// HACK: sorry, quick hack around SSL cert issue (see better hack/fix below)
// /// FIXES: "Error getting response stream (Write: The authentication or decryption has failed.): SendFailure"
// /// </summary>
// /// <remarks>
// /// Use like this before attempting WebClient request
// /// ServicePointManager.CertificatePolicy = new NoCheck();
// /// </remarks>
// class NoCheck : ICertificatePolicy {
//
// public bool CheckValidationResult(ServicePoint srvPoint, System.Security.Cryptography.X509Certificates.X509Certificate certificate, WebRequest request, int certificateProblem)
// {
// return true;
// }
// }

public bool CheckValidationResult(ServicePoint srvPoint, System.Security.Cryptography.X509Certificates.X509Certificate certificate, WebRequest request, int certificateProblem)
{
return true;
}
}
/// <summary>
/// Workaround for the bug described here (because I'm testing on API_8)
/// https://bugzilla.xamarin.com/show_bug.cgi?id=6501
/// </summary>
class Workaround {
public static bool Validator (object sender,
System.Security.Cryptography.X509Certificates.X509Certificate
certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
var sslTrustManager = (IX509TrustManager) typeof (AndroidEnvironment)
.GetField ("sslTrustManager",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Static)
.GetValue (null);
Func<Java.Security.Cert.CertificateFactory,
System.Security.Cryptography.X509Certificates.X509Certificate,
Java.Security.Cert.X509Certificate> c = (f, v) =>
f.GenerateCertificate (
new System.IO.MemoryStream (v.GetRawCertData ()))
.JavaCast<Java.Security.Cert.X509Certificate>();
var cFactory = Java.Security.Cert.CertificateFactory.GetInstance (
Javax.Net.Ssl.TrustManagerFactory.DefaultAlgorithm);
var certs = new List<Java.Security.Cert.X509Certificate>(
chain.ChainElements.Count + 1);
certs.Add (c (cFactory, certificate));
foreach (var ce in chain.ChainElements) {
if (certificate.Equals (ce.Certificate))
continue;
certificate = ce.Certificate;
certs.Add (c (cFactory, certificate));
}
try {
sslTrustManager.CheckServerTrusted (certs.ToArray (),
Javax.Net.Ssl.TrustManagerFactory.DefaultAlgorithm);
return true;
}
catch (Exception e) {
return false;
}
}
}
}
}

4 changes: 1 addition & 3 deletions Azure/Android/TaskyAzureAndroid.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<AndroidSupportedAbis>armeabi%3barmeabi-v7a%3bx86</AndroidSupportedAbis>
<AndroidStoreUncompressedFileExtensions />
<MandroidI18n />
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
Expand All @@ -30,8 +31,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkSkip />
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
</PropertyGroup>
Expand All @@ -42,7 +41,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
Expand Down
20 changes: 20 additions & 0 deletions Azure/Android/TaskyAzureAndroid.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaskyAzureAndroid", "TaskyAzureAndroid.csproj", "{82F04C1E-2F0D-4396-ADC3-BC9EADEE8E7E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{82F04C1E-2F0D-4396-ADC3-BC9EADEE8E7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82F04C1E-2F0D-4396-ADC3-BC9EADEE8E7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82F04C1E-2F0D-4396-ADC3-BC9EADEE8E7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82F04C1E-2F0D-4396-ADC3-BC9EADEE8E7E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = TaskyAzureAndroid.csproj
EndGlobalSection
EndGlobal

0 comments on commit 8d82c0a

Please sign in to comment.