# module OpenSSL

##
Overview

##
OpenSSL Integration

- TLS sockets need a context, potentially with keys (required for servers) and configuration.
- TLS sockets will wrap the underlying TCP socket, and any further communication must happen through the `OpenSSL::SSL::Socket` only.

##
Usage Example

Recommended ciphers can be taken from:

- OWASP Wiki
- Cipherli.st
- A full list is available at the OpenSSL Docs

Do note that:

- Crystal does its best to provide sane configuration defaults (see Mozilla-Intermediate).
- Linked version of OpenSSL need to be checked for supporting specific protocols and ciphers.
- If any configurations or choices in Crystal regarding SSL settings and security are found to be lacking or need improvement please open an issue and let us know.

###
Server side

NOTE For the below example to work, a key pair should be attained.

    require "socket"
    require "openssl"

    def server
      # Bind new TCPSocket to port 5555
      socket = TCPServer.new(5555)

      context = OpenSSL::SSL::Context::Server.new
      context.private_key = "/path/to/private.key"
      context.certificate_chain = "/path/to/public.cert"

      puts "Server is up"

      socket.accept do |client|
        puts "Got client"

        bytes = Bytes.new(20)

        ssl_socket = OpenSSL::SSL::Socket::Server.new(client, context)
        ssl_socket.read(bytes)

        puts String.new(bytes)
      end
    end

###
Client side

    require "socket"
    require "openssl"

    def client
      socket = TCPSocket.new("127.0.0.1", 5555)
      context = OpenSSL::SSL::Context::Client.new

      ssl_socket = OpenSSL::SSL::Socket::Client.new(socket, context)
      ssl_socket << "Testing"
    end

##
Defined in: