cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
509
Views
0
Helpful
1
Replies
Highlighted
Beginner

TLS Pinning Guide - Java

TLS got you in the slumps? Try TLS Pinning!

Using the onePK SDK version 1.2 or greater, you have this functionality called "TLS Pinning" bundled with the SDK which will greatly reduce the efforts to connect to the onePK enabled Network Element. TLS Pinning allows you bypass all of the fuss with certificates, allowing your application to directly connect to the TLS connection.

Let's take a closer on what exactly do we mean by using TLS Pinning. Throughout this guide, we will be using the Java SDK.

If you are looking for the Python TLS Pinning guide, see this link below:

TLS Pinning Guide - Python

First, we need to create a Java file. Let's create a file called HelloTLSPinning.java.

If you are using an IDE such as Eclipse, you should already have some of the basic skeleton code written out for you. If not, it should look something like this:

public class HelloTLSPinning {

}

Let's also add the main method which will be where our code will execute when compiled. The file should now look like this:

public class HelloTLSPinning {

     public static void main(String[] args) {

     }

}

Next, we need to import the TLS Pinning libraries from the onePK Java SDK. Following the Java conventions, the import below should be at the top of the file.

import com.cisco.onep.core.util.TLSUnverifiedElementHandler;

This simple one line code is technically all you need! But you wouldn't be able to do much with just this line!

Let's add the rest of the libraries that we will be needing later on in this guide.

import java.net.UnknownHostException;

// Import the onePK libraries

import com.cisco.onep.core.exception.OnepConnectionException;

import com.cisco.onep.core.exception.OnepDuplicateElementException;

import com.cisco.onep.core.exception.OnepIllegalArgumentException;

import com.cisco.onep.core.exception.OnepInvalidSettingsException;

import com.cisco.onep.element.NetworkApplication;

import com.cisco.onep.element.NetworkElement;

import com.cisco.onep.element.SessionConfig;

import com.cisco.onep.element.SessionConfig.SessionTransportMode;

Throughout the rest of this guide, we will have all of our code inside of the main method from simplicity sake. Of course, we should be using Java's best practices but in this case, we will cheat a little and have all of our code in one place.

Next, the TLS Pinning requires you to write your own callback (also known as a handler) for whenever the TLS connection is being established by the application and the Network Element. There is a interface called TLSUnverifiedElementHandler which will represent our callback / handler for the incoming TLS connection.

In this particular guide, we will be using a Java trick called Anonymous Class to implement this interface.

TLSUnverifiedElementHandler myHandler = new TLSUnverifiedElementHandler() {

}

Now that we have a basic skeleton, let's fill in the blanks. We are required to implement the handleVerfiy method as this is an interface object. Let's add in that method to the body of the anonymous class.

TLSUnverifiedElementHandler myHandler = new TLSUnverifiedElementHandler() {

     public Decision handleVerify(String host, String hashType, String fingerPrint,

                                  boolean changed) {

     }

}

Awesome, now we need to implement the handleVerify function. This method is our callback, which is going to be the brains and logic in our application on how to handle the incoming TLS connection coming from the Network Device. This function requires us to return Decision value, which is essentially an enum to either REJECT, ACCEPT_ONCE, or ACCEPT_AND_PIN the incoming TLS connection. REJECT is to reject the TLS connection. ACCEPT_ONCE, is to accept the TLS connection. ACCEPT_AND_PIN is to accept the TLS connection and "pin" it to our pinningFile that in order to store and use it for later, essentially this will whitelist our TLS connection.

For now, we will just ACCEPT_ONCE this connection and not bother with pinning it to our file. So the code will look like this:

TLSUnverifiedElementHandler myHandler = new TLSUnverifiedElementHandler() {

     public Decision handleVerify(String host, String hashType, String fingerPrint,

                                 boolean changed) {

          return TLSUnverifiedElementHandler.Decision.ACCEPT_ONCE;

     }

}

DISCLAIMER:  For production network, you should NOT pin and/or accept the certificate if the fingerprint has not been verified. Verify the fingerprint by using the "show onep status" CLI command to ensure that the device to which you are connecting is the correct device.

Great we have just finished our handler! Just a little bit more and we can get things rocking.

The last piece of this puzzle is to now have our onePK SessionConfig to use our myHandler whenever we are establishing a TLS connection to the Network Device.

In the onePK SessionConfig class, we have a method called setTLSPinning which will essentially take 2 things, the String path to our pinningFile, and handler that we have just created. So this is what our connect code will look like:

// Connection to my onePK enabled Network Element

NetworkApplication app = NetworkApplication.getInstance();

NetworkElement ne = app.getNetworkElement("10.10.100.110");

SessionConfig config = new SessionConfig(SessionTransportMode.TLS);

config.setTLSPinning("", myHandler);

ne.connect("admin", "lab", config);

Notice that our path to the pinningFile is empty. This is OK for us since we are doing nothing with the pinningFile in our handler that we specified above. Mainly, we were using the enum ACCEPT_ONCE, which was not pinning the session to the file. Note that if we did ACCEPT_AND_PIN we are required to specify the path to the pinningFile, note onePK will create that file for you if it does not exist.

Alright just a little bit more. Let's print out the information of the Network Device then disconnect to make this Java program a little useful.

// Print the information of the Network Element

System.out.println(ne);

// Finally have the application disconnect from the Network Element

ne.disconnect();

If you are using an IDE, such as Eclipse, you should notice that there are some errors about unhandled exceptions. This is expected since we are using the onePK libraries to throw various errors that could possibly happen on both in the application and/or in the Network Element and we need to handle these different kind of exceptions. In this case, we will just throw the exceptions out to console. This means that we will add the throws keyword and all of the exceptions that we need to handle in the main method. Thus it would look like this:

public static void main(String[] args) throws OnepIllegalArgumentException,

     OnepInvalidSettingsException, OnepConnectionException, UnknownHostException,

     OnepDuplicateElementException {

Whew! We are finally done! Now when we put everything together, our full Java program will look like this

import java.net.UnknownHostException;

// Import the onePK libraries

import com.cisco.onep.core.exception.OnepConnectionException;

import com.cisco.onep.core.exception.OnepDuplicateElementException;

import com.cisco.onep.core.exception.OnepIllegalArgumentException;

import com.cisco.onep.core.exception.OnepInvalidSettingsException;

import com.cisco.onep.core.util.TLSUnverifiedElementHandler;

import com.cisco.onep.element.NetworkApplication;

import com.cisco.onep.element.NetworkElement;

import com.cisco.onep.element.SessionConfig;

import com.cisco.onep.element.SessionConfig.SessionTransportMode;

public class HelloTLSPinning {

     public static void main(String[] args) throws OnepIllegalArgumentException,

     OnepInvalidSettingsException, OnepConnectionException, UnknownHostException,

     OnepDuplicateElementException {

          // TLS Handler that is using the Java Anonymous class

          TLSUnverifiedElementHandler myHandler = new TLSUnverifiedElementHandler() {

               public Decision handleVerify(String host, String hashType, String fingerPrint,

                                            boolean changed) {

                    return TLSUnverifiedElementHandler.Decision.ACCEPT_ONCE;

               }

          };

          // Connection to my onePK enabled Network Element

          NetworkApplication app = NetworkApplication.getInstance();

          NetworkElement ne = app.getNetworkElement("10.10.100.110");

          SessionConfig config = new SessionConfig(SessionTransportMode.TLS);

          config.setTLSPinning("", myHandler);

          ne.connect("admin", "lab", config);

          // Print the information of the Network Element

          System.out.println(ne);

          // Finally have the application disconnect from the Network Element

          ne.disconnect();

     }

}

Cheers,

Jerry

Everyone's tags (4)
1 REPLY 1
Contributor

Re: TLS Pinning Guide - Java

Thanks Jerry! I’ve passed this along to our onePK support team.

Thanks,

Brett

Content for Community-Ad
August's Community Spotlight Awards
This widget could not be displayed.