Showing posts with label xamarin. Show all posts
Showing posts with label xamarin. Show all posts

Wednesday, June 7, 2017

Enable TLS 1.2 & 1.1 Xamarin.Android JellyBean & KitKat



  TLS or Transport Layer Security is a cryptographic protocol that provides communication security over a computer network. If you develop for both iOS and Android you probably know that on iOS by default enforces TLS v1.2 for any application (that, for the moment, you can disable).
  When developing for iOS and Android using Xamarin you will probably end up using the HttpClient class. The default implementation of HttpClient on Mono only has built-in support for TLS v1.0. This is why, in order to use the newer versions of TLS, you would had to implement a class derived from HttpClientHandler that under the hood uses the native classes included in the platform that already support  newer TLS versions . The first choice, for a while, was the ModerHttpClient that NSUrlSession class on iOS and OkHttp on Android.
   Recently Xamarin added its own native HttpClientHandler in both iOS and Android. You can are free to switch from the fully managed one or the native one (which imho is recommended). To set the default implementation you will have to go in the project's settings dialog.

    There a small detail for the Android native implementation.  The Xamarin TLS document tells you that v1.2 is only supported for Android >= 5.0 . On the other side if you go to Wikipidia TLS Document you will see that TLS v.1.1 & v1.2 are supported by Android >= 4.1 but they are not enabled by default until Android 5.0.
  If you try to use TLS v1.1& 1.2 on an Android device version >4.0 & <5.0, as these protocols are not enabled by default you will get an "Connection closed by peer" exception.
     There is actually a simple solution for this problem: in order to enable TLS v1.1 & 1.2 in Android JellyBean & KitKat you will have to implement a class derived from SSLSocketFactory and enable the protocols and than change the factory that AndroidClientHandler uses by default. This can easily be achieved by using a implementing a class derived from  AndroidClientHandler where you will override the method SetupRequest and change the SSLSocketFactory with our own implementation that enables TLS v1.1 & 1.2 on the SSLSocket it creates:


  public class AndroidCustomClientHandler:AndroidClientHandler
    {
        CustomTlsSSLSocketFactory _customTlsSSLSocketFactory=new CustomTlsSSLSocketFactory();
        protected override System.Threading.Tasks.Task SetupRequest(System.Net.Http.HttpRequestMessage request, Java.Net.HttpURLConnection conn)
        {
            if (conn is HttpsURLConnection)
            {
                if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
                    //Enable support for TLS v1.2
                    ((HttpsURLConnection)conn).SSLSocketFactory = _customTlsSSLSocketFactory;
            }
            return base.SetupRequest(request, conn);
        } 
    }


where CustomTlsSSLSocketFactory is this:


public class CustomTlsSSLSocketFactory : SSLSocketFactory
 {
  readonly SSLSocketFactory factory = (SSLSocketFactory)Default;

  public override string[] GetDefaultCipherSuites()
  {
   return factory.GetDefaultCipherSuites();
  }

  public override string[] GetSupportedCipherSuites()
  {
   return factory.GetSupportedCipherSuites();
  }
  public override Java.Net.Socket CreateSocket(Java.Net.InetAddress address, int port, Java.Net.InetAddress localAddress, int localPort)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(address, port, localAddress, localPort);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(Java.Net.InetAddress host, int port)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(string host, int port, Java.Net.InetAddress localHost, int localPort)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port, localHost, localPort);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(string host, int port)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(host, port);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  public override Java.Net.Socket CreateSocket(Java.Net.Socket s, string host, int port, bool autoClose)
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket(s, host, port, autoClose);
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }

  protected override void Dispose(bool disposing)
  {
   factory.Dispose();
   base.Dispose(disposing);
  }

  public override Java.Net.Socket CreateSocket()
  {
   SSLSocket socket = (SSLSocket)factory.CreateSocket();
   socket.SetEnabledProtocols(socket.GetSupportedProtocols());

   return socket;
  }
 }


You can see that I've chosen to enable all the supported protocols, but a better approach would be to enable just the ones that you actually use.

Hope you will find it useful!

I almost forgot the most important part: When you initialize your HttpClient you will have to pass an instance of your AndroidCustomClientHandler class:


 HttpClient _client = new HttpClient(new AndroidCustomClientHandler()) { BaseAddress = _baseAddr };

Thursday, January 1, 2015

Using the Android Hyper-V Preview with Visual Studio 2013

   Happy New Year to you all! While I am anxiously waiting to know if I will be renewed today as an Microsoft MVP (btw being MVP is an awesome experience, the MVPSummit was a great experience even if I was expecting to see more new things so if you can get involved and try this experience). Still planning to do the post on BLE background agents but there are so many things to write that I have to find time to write it. Hopefully this will happen soon.
    So this small post is all about running the Android Hyper-V Preview Emulator that comes with the Visual Studio 2015 Preview as a stand-alone emulator and use it with your production machine running Visual Studio 2013 and the Xamarin tools. Even if the emulator is still in preview if you are doing Android and Windows Phone development on the same machine you won't have to reboot your machine without Hyper-V support in order to have a decent Android emulator. Strangely Microsoft decided for this preview that the emulator can install only if you have the preview of Visual Studio 2015. In theory you could run the preview along with Visual Studio 2013 but things are not always perfect so many of you will keep two different instances for VS 2013 and the Preview. In oreder to get the emulator work you will still have to install the preview of Visual Studio 2015 on some virtual machine or secondary machine and copy the needed files.
    The method is pretty simple. All you will need to do is to copy the folder "Microsoft Visual Studio Emulator for Android" that is located inside Program Files (x86) [ %PROGRAMFILES(X86)%] folder to the machine you want to run the emulator on. At this point you have everything you need. Copy the folder at the same location on the other machine. We still need to take two steps before launching the emulator for the first time. Inside the folder that you've just copied there are two files vsemu.vhd and sdcard.vhd that will be used to "generate" the two virtual machines (phone and tablet). Here are the two steps that you have to take:
  1.  Make sure that adb.exe is in your Path as it will be used by XDE.exe
  2. Create a new folder called Android inside the folder "%userprofile%\AppData\Local\Microsoft\XDE" and copy the two vhd each of them two times with the following names:
     vsemu.vhd copied as: vsemulator.phone.android.vhd and vsemulator.tablet.android.vhd
     sdcard.vhd copied as vsemulator.phone.android.sdcard.vhd and vsemulator.tablet.android.sdcard.vhd

     Now we are ready to start the emulator. You won't be able to start the emulator from Visual Studio 2013 the way VS 2015 Preview does but you can start it manually and once you've started it and the adb automatically connects to the emulator you will see it in Visual Studio as a deployable device. Let's not mention that you can actually use the accelerometer, the location, battery simulation and the screenshot (awesome).

     Here are the two commands that you need to run (make a batch on your desktop):

Phone Android Emulator:
"%PROGRAMFILES(X86)%\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe" /name "VS Emulator Android - Phone" /vhd %userprofile%\AppData\Local\Microsoft\XDE\Android\vsemulator.phone.android.vhd /video "720x1280" /memsize 1024 /telemetrySession "14.0;eyJBcHBJZCI6MTAwMSwiRGVmYXVsdENvbnRleHRJZCI6ImJkNmMxNjk2LTQ5ZjUtNDI4My1iZTk2LWUzNGNjZWYwZTA4YSIsIkhvc3ROYW1lIjoiRGV2MTQiLCJJZCI6ImIyOWZlODMwLThhOWMtNDE1Yy04MWExLWFlNTFkNzFiYTUwNSIsIklzT3B0ZWRJbiI6dHJ1ZSwiUHJvY2Vzc1N0YXJ0VGltZSI6NjM1NTU2MTAxODUyMjI0MzA1fQ=="

Tablet Android Emulator:
"%PROGRAMFILES(X86)%\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe" /name "VS Emulator Android - Tablet" /vhd %userprofile%\AppData\Local\Microsoft\XDE\Android\vsemulator.tablet.android.vhd /video "1080x1920" /memsize 2048 /telemetrySession "14.0;eyJBcHBJZCI6MTAwMSwiRGVmYXVsdENvbnRleHRJZCI6ImJkNmMxNjk2LTQ5ZjUtNDI4My1iZTk2LWUzNGNjZWYwZTA4YSIsIkhvc3ROYW1lIjoiRGV2MTQiLCJJZCI6ImIyOWZlODMwLThhOWMtNDE1Yy04MWExLWFlNTFkNzFiYTUwNSIsIklzT3B0ZWRJbiI6dHJ1ZSwiUHJvY2Vzc1N0YXJ0VGltZSI6NjM1NTU2MTAxODUyMjI0MzA1fQ==" /noStart

You won't probably need the /telemetrySession but this way you could give back some feedback (I guess). Also the first time you run the emulator it will ask permission to configure the Internet on the device and of course you will have to accept.

Also while digging to make this work I found out that the source code of the Android Preview Emulator is published here:  http://aka.ms/getsource . In the same place there is also the source code for the Microsoft Wireless Display Adapter. It looks like it is running on Linux kernel with a pretty decent CPU and we might get some new features other than a simple Miracast adapter.

Until my next blog post: NAMASTE and again HAVE A GREAT NEW YEAR!






Friday, October 24, 2014

Using Cordova/PhoneGap with Xamarin Android

    Since I haven't found a lot of informations on this matter searching with Google I've decided to share my solution and, maybe, save some time for some of you. The target of this post is to get the Cordova / Phonegap running inside an Xamarin Android project on an Android device.

    In order to use Cordova inside an Xamarin project you would first need to build the Cordova framework.  What I did was to clone the repository Cordova Android and then follow the Building without the Tooling instructions.

      Once you have the cordova*.jar we can start binding the library using Xamarin. Do to that you will have to create a new Project using Xamarin Studio (this does not work in Visual Studio) and select the Android Java Bindings project type:


       The structure of the project is pretty simple. Add the Jar to the Jars folder and ensure the Build action is set to EmbeddedJar and try to build the project.



  You will get some errors compiling but luckily these errors are on components we don't need to bind to. So what you have to to is to edit the Metadata.xml file inside the Transforms folder and add the these two internal packages that we want to ignore:

Doing that will enable to correctly build the binding project.

    Now that we have the binding we can test it. For this I have build a test Project and copied the test www container from the github repository.  It took some while to make it work but everything seems to run as expected. I didn't have time to implement all the activities from the sample but only some of them. It should be pretty easy to port also the others if needed. This sample also uses a custom plugin that launches activities when the button on the main screen get pressed so you should basically have all that you need to start using Cordova with Xamarin. When you launch the project you should see this screen on your device/emulator:



These are the items implemented in the Test project: Backgroundcolor, Basic Authentification, Full Screen, HTML not found, Iframe Lifecycle, Menus & Splashscreen

Here is the link to my Github repository that contains the Binding project and the Test project. This sample is using Cordova 3.7.0


Contact me if you need help

P.S. Still preparing the 3rd post on BLE and it will be the most interesting one as it will be on running in the background.

NAMASTE!





Monday, February 4, 2013

How to use Team Foundation Service with MonoDevelop

  As you probably know Team Foundation Service team announced a few days ago full support for Git protocol. This was AWESOME news for our small company that needed a FREE source control solution for our MonoTouch and Mono for Android projects. We were already using visualstudio.com for our Windows Phone and Windows 8 projects and previously to Git support in TFS we had an in-house svn server but I was not really happy with it. The thing it took me most was to understand what is the Git endpoint address than everything is standard.
  Here is a quick guide on how to create and then use a TFS Git repository with MonoDevelop:
  1. First you need to create a new Team Project with Git support 
     
     Once the project is created press the "Navigate to projec"t button. 

2. Go to Code explorer and you will be able to see the the Git endpoint address. It might not show the git endpoint the first time but if you navigate away and try again you will see it.


3. Use the Git endpoint address to register a new Repository in MonoDevelop



4. Then just publish your solution using the registered repository. You can see all your files in Code Explorer and also all the commits:




Tip: If you want to use a more simple user name than you full live id you can enable your Alternate Credentials on the User Profile page 


The same Git endpoint can be also used to "Connect to a repository" in Xcode for your Obejctive C projects.

Thank you TFS TEAM for this great feature.


NAMASTE