Add SSL in RSocket

How Do I manage SSL in RSocket?

Hi @ayudovin!

Thanks for having interest in RSocket! RSocket is actually a protocol that uses existing transports, like TCP or Websocket. Both of these transport protocols typically have their own mechanism for starting their connections with some sort of SSL handler or context. This decouples RSocket from ever worrying about SSL.

Is there a particular programming language you’re trying out RSocket with so that we could show you an example of how this works with real code?

Could you provide example on Java?

Hi-

Here is a link to client side RSocket code that creates SSL:
(https://github.com/netifi/netifi-java/blob/bbed5f6069aa12cfe6777223f4ed2cd5138fd9fe/netifi-spring-boot-autoconfigure/src/main/java/com/netifi/spring/boot/BrokerClientAutoConfiguration.java#L185)

And here is a snippet to do it on the server:

 final SslContext sslServer;
    if (ConfigUtil.isSslDisabled()) {
      logger.warn("SSL is disabled; will use unencrypted transport.");
      sslServer = null;
      sslContext = null;
    } else {
      final SslProvider sslProvider;
      if (OpenSsl.isAvailable()) {
        logger.info("Native SSL provider is available; will use native provider.");
        sslProvider = SslProvider.OPENSSL_REFCNT;
      } else {
        logger.info("Native SSL provider not available; will use JDK SSL provider.");
        sslProvider = SslProvider.JDK;
      }

      if (ConfigUtil.hasSslCertificate() && ConfigUtil.hasSslPrivateKey()) {
        File keyCertChainFile = new File(ConfigUtil.getSslCertificate());
        File keyFile = new File(ConfigUtil.getSslPrivateKey());
        logger.info("Using SSL certificate: " + keyCertChainFile);
        sslServer =
            SslContextBuilder.forServer(
                    keyCertChainFile,
                    keyFile,
                    ConfigUtil.hasSslPassword() ? ConfigUtil.getSslPassword() : null)
                .sslProvider(sslProvider)
                .build();
        sslContext = SslContextBuilder.forClient().sslProvider(sslProvider).build();
      } else {
        logger.info("Using self-signed SSL certificate.");
        SecureRandom random = new SecureRandom();
        SelfSignedCertificate ssc = new SelfSignedCertificate("netifi.io", random, 1024);
        sslServer =
            SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
                .sslProvider(sslProvider)
                .build();
        sslContext =
            SslContextBuilder.forClient()
                .trustManager(InsecureTrustManagerFactory.INSTANCE)
                .sslProvider(sslProvider)
                .build();
      }
    }

...

// TCP
RSocketFactory.receive()
            .frameDecoder(PayloadDecoder.ZERO_COPY)
            .errorConsumer(
                throwable -> errorConsumer.accept("unhandled exception", throwable))
            .acceptor(cluster)
            .transport(
                () -> {
                  TcpServer tcpServer =
                      TcpServer.create()
                          .host("127.0.0.1")
                          .port(8001);

                  return TcpServerTransport.create(
                      sslServer != null ? tcpServer.secure(sslServer) : tcpServer);
                })
            .start()


// WebSocket
RSocketFactory.receive()
            .frameDecoder(PayloadDecoder.ZERO_COPY)
            .errorConsumer(
                throwable -> errorConsumer.accept("Server: unhandled exception", throwable))
            .acceptor(acceptor)
            .transport(
                () -> {
                  HttpServer httpServer =
                      HttpServer.create()
                          .host("127.0.0.1")
                          .port(8001);

                  return new WebsocketRouteTransport(
                      sslServer != null
                          ? httpServer.secure(
                              sslContextSpec -> sslContextSpec.sslContext(sslServer))
                          : httpServer,
                      routes -> {
                        routes.get(
                            "/health",
                            (request, response) ->
                                response.status(200).sendString(Mono.just("WS:OK")));
                      },
                      "/");
                })
            .start()

Thanks,
Robert