Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
marvin_hoffmann
Active Participant

X.509 Authentication in Windows 8.1 or Windows 10 Apps

In the last months I was involved in several projects where a hybrid application (based on Cordova and SAP's Kapsel plugins) should use client certificates (X.509 certificate) to authenticate against the server. Most of the projects targeted iOS or Android, but recently more and more customers start asking for solution on Windows 8.1 (or Windows 10).


I want to use this blog post to describe how you can enable certificate-based authentication in a Windows Kapsel application.

User Certificates in Windows Store Apps

When talking about certificate handling we strictly should separate between the different mobile operating systems, because the behavior is slightly different. On iOS user certificates which are in the system keychain cannot be used by your custom applications, thus there you have to insert them into an app keychain. On Android user certificates can be requested directly from the system keystore. The app keystore concept is quite new and not yet fully adopted. On Windows we have a mixture of both concepts (which is quite nice in my opinion. We can make use on an user certificate which is stored in the system keystore, but we also can use a local app keystore which is part of our Windows 8.1 or Win 10 App.

What all three operating system have in common is the realization of a "Custom Certificate Provider" extension concept, which is part of SMP's Kapsel SDK. Because the SAP FioriClient is also built on top of this KapselSDK, we can also use this way when we want to use the custom FioriClient. Additionally we can also use this concept when using the KapselSDK (or FioriClient) without SMP, thus when we are directly connecting to SAP Gateway.

The idea of the custom certificate provider is the following:

If we start the app the Kapsel Logon plugin will trigger the Logon operation (or when using SMP the onboarding task). When triggering this logon operation we can provide a context where we specify connection and authentication properties. These properties can be defined inside the app, but they could also be retrieved dynamically on runtime, e.g. by using MobilePlace. When we want to use a custom certificate provider, we have to specify here an identifier string. This string is used later to retrieve a class name. this class has to implement the ICertificateProvider interface and will be called by the LogonPlugin to load the certificate. We can implement this class and specify where to get the user certificate. On iOS and Android this Custom Certificate provider is always called if the LogonPlugin or the AuthProxy plugin have to handle a certificate authentication challenge. On Windows this custom provider is called once when the app starts and is responsible for retrieving the certificate and storing it into the app's internal keystore. Later the app will load this cert directly from the keystore.

To summarize the possibilities on Windows:

  1. Using System KeyStore
    If the user certificate got imported into the system keystore it can be used directly inside a cordova based kapsel app. There is no additional action needed.

  2. Using App KeyStore (with Custom Certificate Provider)
    If the user certificate is not available inside the system keystore (maybe due to security reasons), the user certificate can be imported into the app keystore at app runtime. For this purpose the Kapsel SDK provides a certificate provider extension that can be implemented.

Even if possibility 1) is trivial, I recommend that you are trying this first, because this will ensure that your environment is setup correctly for certificate usage.

Preparation

In the following I will describe the two ways mentioned in previous section. For that we need to prepare a cordova app project as well as configuration on SMP.

I will extend the sample application which I created for this blog post http://scn.sap.com/community/developer-center/mobility-platform/blog/2015/12/13/developing-kapsel-ap...

If you do not know how to create a cordova project and how to work with Visual Studio I would recommend that you are walking through the linked blog post first. Otherwise you can directly download the sample app (which I will use in this tutorial) from folder “KapselSampleRefSmall” of my github repository: https://github.com/MarvinHoffmann/kapsel and place it into your cordova www folder.

Please prepare a user certificate for testing purpose. I will not describe here how to create one, but you can use for example the command line utility openssl or the GUI tool XCA which can simulate a CA (my preferred tool for certificate creation and signing).


SMP Configuration

I created a sample application configuration on my SMP server. I named the hybrid app "com.sap.mit.mutualtest", provided any OData endpoint address ( http://services.odata.org/V2/Northwind/Northwind.svc/ ) and a new security profile.

Important is that the X.509 Authentication Provider is added to the security profile. You can tell SMP that e.g. the common name (CN) should be the user's name when registering the connection at SMP.


Using User Certificates from System KeyStore

As said already we should start performing mutual authentication with a user certificate that we placed in advance into the system keystore. When the test after that is successful we know that our environment is setup correctly for handling certificates.

Import of User Certificate

At first import your user certificate into the System KeyStore, e.g. by opening your pfx or p12 user certificate file and following the wizard steps

You can verify in Certificate Manager if the user certificate got imported into the right store. For this choose "Run" and execute "certmgr.msc".

User Certificates should be stored in folder Personal > Certificates

Mutual Authentication Connection Test

Before testing any real app you can verify the user certificate and also your system setup you can call the SMP server on its mutual auth port directly inside the browser. The standard port (if not changed during installation) for mutual authentication is port 8082, so make sure that you are calling this port. If everything works fine the browser should ask you for your certificate

After that the page is loaded. In case of wrong or no user certificates you will not be able to see this page

It is working...

Using User Certificates in Windows Store Apps

As mentioned above we want to extend an existing cordova Kapsel app, so that user certificates are used for authentication. Because User certificate handling is happening in the native part of the container, we should open the Windows platform Cordova project. You can find the project in folder platforms/windows.

You can now see the different Windows projects (e.g. one for Win Phone, Win 8.1 and Win 10). In File utils/SMPHelper.js we need to adjust the server related settings. Add the correct appId, enable https and add the mutual-auth port (default: 8082). Be aware when changing the www content here you are changing the content directly inside the platform directory!. So if you are developing for different OS or if you are working with Cordova prepare, better edit directly cordova's main www folder.

The following step is only required if your SMP server is using a self signed certificate, because then you need to specify explicitly that your windows app should trust this server certificate. Get your server's certificate and copy it into your project (e.g. in a folder called assets). Now open the package.windows.appxmanifest file and switch to tab "Declarations". In the dropdown menu choose "Certificates" and add it. Then click on "Add New", specify as certificate store "Root" and choose as content the path to your server certificate. then save everthing.

Start/Run your app. The Logon screen should appear. After clicking on "Register" (button at right top corner) you should get a message that is informing you that your user certificate is requested by our app.

After confirmation you should see the app passcode screen and thus the app registration via mutual authentication was successful.

Using User Certificate from App KeyStore (Kapsel Custom Certificate Provider)

In this scenario we do not have a user certificate in our system keystore. So if you executed the last sample, do not forget to delete your user certificate from the system keystore again. We will create a custom certificate provider that will be used to insert a user certificate into the app's own keychain. In this example we will load the user certificate from a folder. Of course in real scenarios you would load the user certificate e.g. from a smart card, an MDM solution or some other source.

1. At first we will adjust the context object which will be an input parameter for the logon method (sap.Logon.startLogonInit). Here we have to tell the logon plugin that it should call our custom certificate provider. The given string will be mapped later against a value which defines our native class implementing the certificate provider interface.

2. As said we need to map this given string with a real class name. The mapping is based on a resource file called "AppMetadata.resjson". Thus we need to create this file. Right click on the target Cordova project, e.g. for Windows 8.1 and choose "Add > New Item..."

3. Create a file called "Resources File (.resjson) and name it "AppMetadata.resjson".

4. Add the following content into the resource file. The key value (left part of the string) is the identifier which realizes the mapping to our class "CertProviderWRC.FileCertificateProvider" . In next step we have to create this class.


{
"com.sap.mit.certprovider":"CertProviderWRC.FileCertificateProvider,FileCertificateProvider,ContentType=WindowsRuntime"
}

5. We will create a Windows Runtime Component in which we realize our custom certificate provider as a C# class. For that right click on the base project and choose "Add > New Project..."

6. Then choose "Visual C# > Windows > Windows 8 > Windows > Windows Runtime Component (Windows 8.1)" and name it "CertProviderWRC".

7. Before we can start implementing our provider we need to add a reference to SAP's Certificate Provider. SAP's native Windows libraries are packaged in NuGet packages, so we can simply add the SAP.CertificateProvider NuGet package. Right click on "References" of project CertProviderWRC and choose "Manage NuGet Packages..."

8. the first time you need to add the directory which contains the Windows native libraries (nupkg files) as a new package source. Usually you can find these files inside your MobileSDK installation in \NativeSDK\ODataFramework\Windows\

9. After adding the package source you can use it to see the available NuGet packages. Simply install the SAP.CertificateProvider package.

10. Now we can insert our C# class called "FileCertificateProvider" into the project "CertProviderWRC". I added the source for this certificate provider sample to my github. You can download/clone it here: https://github.com/MarvinHoffmann/kapsel in folder KapselCertificateProviderWindows. Copy this class into the "CertProviderWRC" project. This sample provider is reading a user certificate from within the app itself and storing it into the app's keychain. Thus you need to copy your user certificate into the assets folder and adapt the name and the password of the certificate inside the CertificateProvider class.

11. Finally we need to reference the CertProviderWRC project. So right click on "CordovApp.Windows > References" and choose "Add Reference"

12. And select the CertProviderWRC project

13. Because by default the debugging is set to "Script only" you cannot see the output produce by our native Certificate Provider class. Thus it makes sense to change the debugging mode. After that setting break points and debugging the certificate provider is possible as well (right click on project and choose "Properties". Then set the "Debugger Type" to "Mixed (Managed and Native)"

14. Start/run your app and check your "Output" window. (If you have the same app previously already installed, it might be better to uninstall the old app). You should see the log entries produced by our certificate provider

15. The app registration is successfully finished and the testapp can be used to send some requests and receive data by using mutual authentication

2 Comments