A-Stack Security and Trust Manager

1. Introduction

2. Adding Custom Trust Manager


1. Introduction

Currently, the A-Stack platform does not provide a means to establish trust among the peer nodes. So There is a possibility that an unauthorized peer can establish a communication channel within the platform cluster and can maliciously manipulate the network data resulting in the failure of the system. So it is very important to have a mechanism so that all the peers in the platform ecosystem should validate each other's identify before establishing the communication channel. This ensures the integrity of the whole A-Stack echo system.

Apparently, there is a need for a dedicated component (i.e.Trust Manager) within the A-Stack platform which set the rules of authentication and by using this rule, a peer ensures the authenticity of another side peer.

Before we go ahead into the details of the Trust Manager. Let us get familiarize ourselves with some knowledge of Cryptography, Secure Socket Communication, and Transport Layer Security.

              

2. Adding Custom Trust Manager


v1.1.1.201806160000 introduces support for custom configurations and/or implementations of TLS’s KeyManager and TrustManager classes.

You can read more about how Java TLS works here: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html.


It appeared that you can do quite a bit just with JDK configurations (e.g. install your own factories and providers into the JDK itself). For the cases when this is not an option, engine now supports implementations of KeyManager and TrustManger interfaces placed in OSGi bundles. That is, you can develop you own implementation, create a bundle and configure engine to use your custom implementation instead of default one implemented by the engine itself. Recall that default engine implementation simply trusts any server certificate and uses either JDK default or configured *single* key store. So if you want to use more than one key store or refuse some certificates based on your esoteric conditions, you’d have to implement your own TLS key/trust managers.


You can find documentation on how to build your own bundle elsewhere, but the content of the bundle itself could not be simpler. You just need to define a class implementing required interface and declare it as an OSGi component implementing KeyManager or TrustManager interfaces, e.g.



I.e. if you want to check certificates you’ll need to implement javax.net.ssl.X509TrustManager interface. You can define multiple managers (in one or more bundles), one for each type of trust material. JDK will select proper instance based on the concrete type.


Once the bundle jar is built you simply drop it into sff.auto.launch folder.


Now you need to configure the engine to use your custom manager. Four new config parameters are now available, corresponding to two first parameters of a server and client TLS context’s init() method:


  <sff.server.tls.KeyManagers/>

  <sff.server.tls.TrustManagers/>

  <sff.client.tls.KeyManagers/>

  <sff.client.tls.TrustManagers/>


Each parameter can be

  • “jdk” – use JDK configuration. Null will be passed to the corresponding TLS context parameter (see the doc above about how JDK process null parameters)
  • “bundle” – use provided custom implementation from the deployed custom bundle. If no custom implementation is deployed, fall back to default.
  • Absent, null, or “default” – default engine configuration: this is business as usual.


For example, if you have a custom implementation of TrustManager and you want to use it for client communications, you’d deploy your bundle and set <sff.client.tls.TrustManagers>bundle</sff.client.tls.TrustManagers>.

The same goes for KeyManager implementations.