Securing the connection of gRPC Based Event Handler with server authentication SSL/TLS

Nuwanga Herath
5 min readJan 11, 2021

In this article, we will go through the steps of securing the implemented gRPC Based Event Handler with server authentication SSL/TLS. To do that we have to add some changes to the event handler implementation and also have to add changes to the identity-event.properties configuration of the WSO2 Identity Server. Addition to that, we will also have to add changes to the gRPC servers to make them as secured servers with SSL/TLS.

If you are not aware of the gRPC Based Event Handler, please spend little time on my blog on Writing a gRPC Based Event Handler using the WSO2 Identity Server Eventing Framework to get a clear idea.

You can also find git repositories of,

What is SSL/TLS?

  • Transport Layer Security (TLS) is the successor protocol to SSL. TLS is an improved version of SSL. It works in much the same way as the SSL, using encryption to protect the transfer of data and information.

gRPC Authentication with TLS

  • gRPC Authentication is the process of verifying the identity of the communicating parties, which usually be clients and servers. More specifically TLS uses asymmetric cryptography in the authentication process.

Here we use the Server-Side TLS for the authentication to create secured gRPC connection for the gRPC Based Event Handler.

Server-Side TLS

  • In Server-side TLS, all the transmitting data are encrypted and only the server needs to provide its TLS certificate to the client in the authentication process. In this case, the server does not care which client is calling its API.

Adding Server-Side TLS to the gRPC Based Event Handler

The gRPC Event Handler works as an extension end point of WSO2 Identity Server and works as client in the gRPC configuration. So what we need most is the verifying of the gRPC servers to make sure our gRPC Based Event Handler communicating with the right servers.

We can use mutual TLS to secure the connection as it verifies both client and the server by providing their TLS certificates to the other. But it does not seem feasible in our case as we intended to give gRPC Event Handler as an independent component without expecting any further implementation from users.

Follow the below steps to add server-side TLS implementation to the gRPC Based Event Handler.

Step 1 : Generating TLS Certificates

  • Make sure to have openssl installed in your PC.
# Check the installation and the version of the openssl$ openssl version
  • Write the following certGen.sh script or run the line by line in the terminal to generate TLS certificates.
rm *.pem

# 1. Generate CA's private key and self-signed certificate
openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=US/ST=CA/L=Mountain View/O=WSO2/OU=WSO2/CN=localhost/emailAddress=example1@gmail.com"

# 2. Generate web server's private key and certificate signing request (CSR)
openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=LK/ST=WP/L=Colombo/O=GRPC/OU=GRPC/CN=localhost/emailAddress=example2@gmail.com"

# 3. Use CA's private key to sign web server's CSR and get back the signed certificate
openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf

We have to provide identity information for the certificates. So we add the -subj (subject) option to the openssl req command as you can see above.

In the subject string,

  • /C for the country code
  • /ST for the state or province
  • /L for the locality name or city
  • /O for the organization
  • /OU for the organization unit
  • /CN for the common name or domain name
  • /emailAddress for the email address

Make sure to give different values as identity information for self-signed certificate and for server's certificate.

You can verify the certificate by running the following command.

$ openssl verify -CAfile ca-cert.pem server-cert.pem

Now we have 5 generated files,

  • ca-key.pem : The CA’s private key
  • ca-cert.pem : The CA’s certificate
  • server-key.pem : The server’s key
  • server-cert.pem : The server’s certificate
  • server-req.pem : The certificate signing request (CSR)

Here we only use the CA’s certificate, the server’s key and the server’s certificate in the implementation.

Step 2 : Enabling TLS on the Event Handler

We only have to add the netty-tcnative-boringssl-static dependency, a method to load TLS credentials and a small change to the channel building part to the existing Event Handler code.

In the client-side, it only needs the CA’s certificate to verify the authenticity of the certificate gets from the server to make sure that is the right server to communicate.

  1. Adding the netty-tcnative-boringssl-static dependency
  • Add followings to the dependency configuration section of the pom.xml file.
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.12.Final</version>
<scope>runtime</scope>
</dependency>

2. Changing the channel building part

  • Here we obtain the CA’s certificate file path from identity-event.properties file of the WSO2 Identity Server.
// Obtain certPath from identity-event properties.
this.caCertPath = grpcEventHandlerConfiguration.getModuleProperties()
.getProperty("grpcBasedEventHandler.certPath");

// Obtain the CA certificate file.
this.clientCACertFile = new File(caCertPath);

// Create the channel for gRPC server with server authentication SSL/TLS.
try {
this.channel = NettyChannelBuilder.forAddress(grpcServerHost, Integer.parseInt(grpcServerPort))
.sslContext(GrpcSslContexts.forClient().trustManager(clientCACertFile).build())
.build();
} catch (SSLException e) {
log.info("SSLException: ", e);
}

Step 3 : Configuring the Event Handler

  • Addition to the existing properties in the configuration of the event handler, we have to add pathname to the CA’s certificate as property to the event handler configuration.
  • Add following configuration to {wso2is-home}/repository/conf/deployment.toml file. Here I used an example path.
[[event_handler]]
name="grpcBasedEventHandler"
subscriptions=["POST_ADD_USER"]
enable=true
properties.host="localhost"
properties.port="8010"
properties.certPath="/home/nuwanga/wso2/custom-event-handler/src/main/java/org/wso2/grpc/event/handler/cert1/ca-cert.pem"
  • You can find the full project of the gRPC Based Event Handler here.

Now we have completely implemented the gRPC Based Event Handler with server-side TLS. Next, we have to enable TLS on the server. This is how to it.

Enabling TLS on the server

To use TLS on the server, we have to use the generated server’s certificate and server’s key files in PEM format. Here I show you a java example.

File certChainFile = new File("/home/nuwanga/wso2/event-handler-server/src/main/java/org/example/server/cert1/server-cert.pem");
File privateKeyFile = new File("/home/nuwanga/wso2/event-handler-server/src/main/java/org/example/server/cert1/server-key.pem");

// SSL/TLS Authenticated server.
Server server = ServerBuilder.forPort(8020)
.useTransportSecurity(certChainFile, privateKeyFile)
.addService(new Handler())
.build();

server.start();
server.awaitTermination();
server.shutdown();
  • You can find full server implementation in Java here.
  • You can find full server implementation in Python here.

Hope you have got clear idea on Securing the connection of gRPC Based Event Handler with server authentication SSL/TLS.

If you have faced any problem, put it in the comment section.

--

--

Nuwanga Herath

Former Software Engineering Intern @ WSO2, Computer Science and Engineering Undergraduate @ University of Moratuwa, Sri Lanka