VPP/HostStack/TLS

From fd.io
< VPP‎ | HostStack
Jump to: navigation, search

TLS App

TLS service is offered by the stack to other client applications via a custom builtin application. The TLS application implements a special transport type that allows it to behave as an application, from the underlying TCP transport perspective, but also as a transport, from the client application perspective. We refer to this shim layer as a TLS context. The app does not directly implement the TLS protocol, i.e., the record layer, handshaking protocols and the cryptographic computations and suites [1], instead it relies on libraries like mbedtls [2] and openssl [3]. A high level view of the architecture can be seen lower:

TLS Application Architecture

Because encryption and decryption operations result in the increase and decrease of number of bytes, respectively, a single client session requires four fifos. That is, in each direction encrypted and unencrypted data is buffered in distinct fifos.

To establish a client session, the following steps are typically taken:

  • Client app requests a TLS connection to a remote session endpoint. Apart from the TLS transport the app must specify the peer's: ip, port and hostname, which is needed for certificate validation. If no hostname is provided, all server certificates are accepted as valid.
  • The TLS app, acting as a transport, is notified of the connections request. A TLS context is allocated and then, acting as an application, the TLS app opens a TCP connection to the remote transport endpoint.
  • Once the TCP connection is established and the TLS app is notified, the mbedtls/openssl context is initialized as a TLS client and the handshake protocol is started.
  • When the handshake is finished, the TLS app uses a configured CA cert to verify the server's certificate and notifies the client application.

At this point, if the connection is successful, the client app can start exchanging data with the remote peer. Data pushed into the TX fifo is read by the TLS app, written into mbedtls/openssl and once encrypted, pushed into the TCP connection's TX fifo. The converse is done on reception.

To initialize a listen session, an application must be configured with a server certificate, which will be provided to clients, and a private key.

Configuration

The TLS application registers with the session layer at VPP startup time. The following can be currently configured via the startup configuration file:

  • ca-cert-path: The path to the CA certificate. By default /etc/ssl/certs/ca-certificates.crt is used
  • use-test-cert-in-ca: Flag that indicates if the embedded TLS server certificate should be added to the the CA chain for testing.

Applications that want to act as TLS servers must be configured with a TLS certificate and private key. These can be provided after the application attachment either via the native C API functions vnet_app_add_tls_cert/vnet_app_add_tls_key or via the APPLICATION_TLS_CERT_ADD/APPLICATION_TLS_KEY_ADD binary API calls.

Examples

HTTP Server

To start the server do:

# test http server uri tls://local-ip/port

In a browser that has connectivity to the server execute

https://vpp_ip/port/sh/run

If all went well, vpp should have returned the results of the show run command. Note that because the embedded server certificate is self-signed the browser will most probably complain about its validity.

Echo Client/Server

On the vpp instance the server is attached to, from the cli do:

# test echo server uri tls://server_ip/port

and on second vpp instance, the client is attached to:

# test echo client uri tls://server_ip/port

This should succeed because if no server hostname is provided any certificate is accepted as valid. To verify the server's certificate pass a host name like below. The host name in the embedded certificate is testtls.fd.io:

# test echo client uri tls://[testtls.fd.io]server_ip/port

References

[1] RFC5246 The Transport Layer Security (TLS) Protocol Version 1.2

[2] mbedtls library

[3] openssl library