SSL Tutorial

Go to the tutorial main page.

SSL stands for Secure Socket Layer. The protocol's name is now officially TLS but we will continue to use SSL since that's the better known name.

SSL was designed to permit web browsers and web servers to exchange sensitive information and prevent programs that could view the network traffic from reading the sensitive data.

The SSL documentation is in Secure Socket Layer (SSL) in socket.htm.

SSL has a notion of client and server. The client contacts the server and sends the first message. The first message causes the client and server to exchange a few messages to negotiate the encryption algorithm to use and to pick an encryption key to use for this connection. Then the client's data is sent to the server. After this is done the client and the server can exchange information at will.

The server must have an SSL certificate and the private key associated with that certificate. An SSL certificate contains the public key for the RSA encryption algorithm. This public key is sent to the client when it connects. The client will use the public key to encrypt a value and send it to the server. The server must then have the corresponding RSA private key so it can decode the client's message. Thus when creating an ssl server stream you must have a file that contains a concatenation of the SSL certificate and the private key associated with that certificate. We supply a sample file you can use to test ssl streams. If you want added privacy you should create or purchase your own SSL certificate. Note that SSL certificates contain other identifying information and have an expiration date. That information is ignored by the Allegro CL SSL interface code. You can use an expired SSL certificate that doesn't correspond to your machine. All the Allegro CL SSL interface cares about is the RSA public key in the certificate.

It is best to use two separate Lisps to test ssl connections. That is because when the client does the first write to the socket it will start a negotiation process that requires the client to write and read a few times. When the client writes the server must be sitting blocked waiting to read or the client write won't return. If you have a Lisp with multiple listener windows then you can test it in one Lisp as you need the server reading in one window and the client writing in another. In our tutorial we will assume that you have got multiple windows on one Lisp or are running two separate Lisp processes.

The first step in using SSL stream is creating a normal socket connection between the Lisps (see the socket tutorial).

It is best to load a module when you know you will need it. (Often you will find the module is already loaded.) The Socket module is named :sock. Evaluate the following in each Lisp:

(require :sock)

In Lisp One create a passive socket

The port number will be supplied by the call and shown in the representation of the socket object returned. In this case, it is 54505 (indicated by */54505). You must use this port number in Lisp 2.

cl-user(1): (setq passv (socket:make-socket :connect :passive))
#<multivalent stream socket waiting for connection at */54505 @ #x71abc482>
  ;;
  ;;  Note: port number 54505 assigned. We use that port number below.
  ;;  You should use whatever port number is assigned when you do this.
cl-user(2): 

In Lisp Two connect to that socket:

As noted above, the port number is 54505, so that is what we use at the value of the remote-port argument. The port number you will get when you try this will likely be different.

;;  Use the port number assigned in the call to MAKE-SOCKET in Lisp One
;;  above (54505 in this case but likely different in yours):
cl-user(1): (setq act (socket:make-socket :remote-host "localhost" :remote-port 54505))
#<multivalent stream socket connected from localhost/54507 to localhost/54505
  @ #x71b0ac8a>
cl-user(3): 

Back in Lisp One, accept that connection to create an active socket:

cl-user(2): (setq con   (socket:accept-connection passv))
; Fast loading /home/jkf/acl7/src/cl/src/code/acldns.fasl
#<multivalent stream socket connected from localhost/54505 to localhost/54507
  @ #x71ad6882>
cl-user(3): 

At this point the Lisps are connected via a socket and we have to decide which will be the SSL server and which will be the client. We arbitrarily choose Lisp One to be the SSL server.

In Lisp One

We create an SSL server stream and specify the file containing the certificate and private key (such a file is provided in the examples/ssl/ subdirectory of the Allegro CL distribution):

cl-user(3): (setq ssl-serve (socket:make-ssl-server-stream 
		con 
                :certificate 
                  (translate-logical-pathname 
                      "sys:;examples;ssl;server.pem")))
; [you may see messages about loading files]
#<excl::ssl-server-stream
   fd #<multivalent stream socket connected from localhost/54505 to
        localhost/54507 @ #x71c26902>
  @ #x71e621a2>
cl-user(4): 

Still in Lisp One

Next we start the server reading the first client message. It is important that the server be waiting for input otherwise the client cannot complete the first write to the SSL socket. The read will not return yet.

cl-user(4): (read ssl-serve)

In Lisp Two

We create an SSL client stream:

cl-user(2): (setq ssl-client (socket:make-ssl-client-stream act))
; [you may see messages about loading files]
#<excl::ssl-client-stream
   fd #<multivalent stream socket connected from localhost/54507 to
        localhost/54505 @ #x71c0132a>
  @ #x71e4e852>
cl-user(3): 

And we write the first message

cl-user(3): (format ssl-client "secret message ")
nil
cl-user(4): (force-output ssl-client)
nil
cl-user(5): 

In Lisp One

Now in Lisp one we see that the first read has returned with the first part of secret message:

cl-user(4): (read ssl-serve)
secret
cl-user(5): 

We read the second part of the secret message:

cl-user(5): (read ssl-serve)
message
cl-user(6): 

Now we show that you can send data in both directions by replying. Note that client does not have to be reading at the moment for the write to work. That is because the negotiation is done and now we are just sending data back and forth.

Still in Lisp One:

cl-user(6): (format ssl-serve "got-it ")
nil
cl-user(7): (force-output ssl-serve)
nil
cl-user(8): 

In Lisp Two we read the response:

cl-user(5): (read ssl-client)
got-it
cl-user(6): 

With the demonstration over we close the sockets:

In Lisp Two:

cl-user(6): (close ssl-client)
nil
cl-user(7): 

In Lisp One:

cl-user(8): (close ssl-serve)
nil
cl-user(9): (close passv)
#<multivalent stream socket closed, but was waiting for connection at */54505
  @ #x71c348ba>
cl-user(10): 

Again, the SSL documentation is in Secure Socket Layer (SSL) in socket.htm.

Go to the tutorial main page.