SSL Programmer Reference

SSL Programmer Reference

T J Hudson tjh@mincom.oz.au

E A Young eay@mincom.oz.au

Table of Contents


1. Introduction

Document Last updated 31-May-95.

1.1 Purpose

This document describes an implementation of the Secure Sockets Layer (SSL) protocol. This implementation will be refered to a SSLeay for simplicity.

This implementation was coded from scratch using only the publically available documentation of the various protocols by Eric Young eay@mincom.oz.au.

The initial prompting to tackle an SSL implementation, the alpha testing, developer (i.e. Eric) hassling, and documentation was done by Tim Hudson tjh@mincom.oz.au.

This implementation has been used by Tim Hudson tjh@mincom.oz.au to add SSL support to the following:

Patch kits for each of these are stored in the same location (actually a separate directory) as this implementation of SSL.

The aims of the document are:

Refer to [1] for details of the SSL protocol. Refer to [2] for details of the location of this implementation.

1.2 Disclaimer

The development and distribution of this code has nothing to do with Mincom Pty Ltd in any way whatsoever. Eric Young and Tim Hudson are currently employed by Mincom Pty Ltd.

The call interface is probably not the same as SSLREF but it shouldn't be too hard to put together a wrapper that makes this look the same. We would appreciate that anyone who does this emails the patch to us (or alternatively perhaps someone can put together a wrapper for SSLREF to make it look like this library).


2. References

[1] http://www.netscape.com/info/SSL.html Draft specification
[2] ftp.psy.uq.oz.au:/pub/Crypto/SSL - current source + documentation
[3] ftp.psy.uq.oz.au:/pub/Crypto/SSLapps - SSL applications
[4] Secure RPC Authentication (SRA) for TELNET and FTP
[5] RFC1409 Telnet Authentication Option
[6] ietf ftpsec draft FTP Security Extensions

3. Description

The SSL Protocol is designed to provide privacy between two communicating applications (a client and a server). Second, the protocol is designed to authenticate the server, and optionally the client. SSL requires a reliable transport protocol (e.g. TCP) for data transmission and reception.

The advantage of the SSL Protocol is that it is "application protocol" independent. A "higher level" application protocol (e.g. HTTP, FTP, TELNET, etc.) can layer on top of the SSL Protocol transparently.


4. Portability

SSL is written in a portable manner with no major assumptions about the underlying environment (except for the fact that long must be at least 32 bits [this code works on 64 bit machines too])

It is intended that the following environments be supported:

SSL has been compiled and tested on the following platforms

See PORTING for the current list.

This implementation has triggered C compiler bugs on a number of platforms. We have worked around all those we have found so far at "normal" -O level optimisation. These bugs are documented with test programs in bugs/


5. Interface Description

The SSL interface itself is documented here ... the "best" approach is to read ssl/client.c and ssl/server.c to see what is done there (and perhaps also look at the patches done to SRA telnet). You will also need to read through the Certificates section.

5.1 Key Encoding Types

All the keys and certificates used in SSL can be encoded via the following different mechanisms:

The corresponding C "constants" are:

The "prefered" encoding format is PEM.

5.2 Error handling

Rather standard stuff here ... most functions return <=0 on error and set SSL_errno.

 int SSL_errno
 char *SSL_error_string(int SSL_errno)
 char *SSL_error_func_string(int SSL_errno)

For the other libraries

 int RSA_errno
 char *RSA_error_string(int RSA_errno);
 int X509_errno
 char *X509_error_string(int X509_errno);
 int PEM_errno
 char *PEM_error_string(int PEM_errno);

5.3 Create SSL Handle

Before anything useful can be done on an SSL connection you must create and initialise the data structure that records SSL state.

 SSL *SSL_new(void)

5.4 Release Handle

If you wish to remove all allocated memory for a given SSL connection

 void SSL_free(SSL *s)

5.5 Establish keys

You must register a callback via PEM_set_getkey_callback() if you do not wish to be prompted for a password on /dev/tty when the pass phrase is required when loading the key file if it is stored in PEM format with encryption enabled. Note that this callback will be invoked prior to the call to SSL_use_RSAPrivateKey() returning.

 int SSL_use_RSAPrivateKey(SSL *s, RSA *key)

See PEM_read_RSA() for the interface for loading.

 int SSL_use_RSAPrivateKey_file(SSL *s, char *file,int type)
 int SSL_use_RSAPrivateKey_fp(SSL *s, FILE *fp,int type)
 int PEM_set_getkey_callback(int (*callback)(char *buf,int len))

callback is passed a buffer into which is can store the value of the key up to len bytes. The length of the key must be returned. On error return -1.

5.6 Register Certificates

The server must have a certificate. The client can (and probably should) have a certificate.

 int SSL_use_certificate(SSL *s, X509 *cert)

See PEM_read_X590() for the interface for loading.

 int SSL_use_certificate_file(SSL *s, char *file, int type)
 int SSL_use_certificate_fp(SSL *s, FILE *fp, int type)

5.7 Set Verification policy

See the Certificate Verification Process section as that describes this function in more detail.

 void SSL_set_verify(SSL *s,int mode, int (*callback)() )

5.8 Bind descriptor

To set the association between an SSL connection and the underlying file descriptor:

 void SSL_set_fd(SSL *s)

5.9 Get descriptor binding

To get the association between an SSL connection and the underlying file descriptor:

 int SSL_get_fd(SSL *s)

5.10 Client connect

 int SSL_connect(SSL *s)

5.11 Server accept

 int SSL_accept(SSL *s)

5.12 Read

 int SSL_read(SSL *s,char *buf,int len)

5.13 Write

 int SSL_write(SSL *s,char *buf,int len)

5.14 Copy session ID

 int SSL_copy_session_id(SSL *to,SSL *from)

5.15 Formatted Output

To make life easier in porting programs that use the stdio library interface tjh put the following together ... so you cannot blame eay for this one ;-)

 void SSL_fprintf(SSL *s, char *format, ...)

5.16 Set Preferred Cipher

 int SSL_set_pref_cipher(SSL *s, char *str)

A colon separated list of cipher names as per the defines

The default preference sequence for cipher negotiation is:

It is probably a good idea to allow the user to override the setting of the preferred cipher via an environment variable. We have been standardising on using SSL_CIPHER for this purpose.


6. Guide to adding SSL to an existing protocol

The basic decision that has to be made is whether or not you are going to transparently layer SSL on top of an existing protocol/application or if you are going to dynamically negotiate SSL using whatever mechanisms already exist in the protocol that you are extending. The authors have talking the approach of doing both where the existing protocol supported such a negotiation model.

Both telnet and ftp have been extended in the past to support additional authentication models. See RFC1409 for TELNET and IETF ftpsec for FTP so it is only logical to use the existing mechanism for these particular programs.

6.1 Client Program Structure

/* create an SSL structure */
 con=(SSL *)SSL_new();
 
 - do normal socket(), [bind()] connect()
 
 /* give it a file descriptor to use */
 SSL_set_fd(con,s);
 /* do connection */
 SSL_connect(con);
 
 - then use SSL_read() and SSL_write() rather
   than read() and write()
 
 e.g.
   SSL_write(con,"bye\n",4);    /* start reading and writting */

6.2 Server Program Structure

 con=(SSL *)SSL_new();
 
 - do normal socket(), bind(), listen(), accept()
 
 SSL_set_fd(con,s);
 
 /* specify private key */
 SSL_use_RSAPrivateKey(con,"server.rsa");
 
 /* specify certificate */
 SSL_use_certificate(con,"server.cert");
 SSL_accept(con);
 
 - then use SSL_read() and SSL_write() rather than
   read() and write()
 
 e.g.
   SSL_read(con,buf,1024);
     for the client example this will return the 4 bytes
     written "bye\n" (possibly in multiple packets)
 


7. Library implementation details

In order to have a working implementation of SSL a number of components are required.

This implementation of SSL is structured as per:

 des/    Eric Young's libdes DES library
 rsa/    RSA and X509 stuff
 md/     message digest things (md2, md4)
 rc4/    rc4 implementation
 lhash/  hashing library
 ssl/    SSL itself

There is a top level Makefile that has the usual targets of all, clean, tags, tar, and install. By default, this implementation expects to be installed in /usr/local/ssl.


8. Supported Cipher Modes

Note: the overheads in bytes per block for supported encryption modes are different and are indicated beside each mode in terms of the header and fixed SSL header and any padding required.

The following are currently supported:

 RC4-MD5        2 + 16 + N
 EXP-RC4-MD5    2 + 16 + N
 CBC-DES-MD5    3 + 16 + ( (N+7) / 8 ) * 8
 CBC3-DES-MD5   3 + 16 + ( (N+7) / 8 ) * 8
 CFB-DES-MD5    2 + N

Refer to SSL_set_pref_cipher() for details of the #defines that match the particular cipher.


9. Performance Characteristics

The current timings for each of the machines we have had access to are listed in times/times along with the required support files to generate your own timing figures.

We really need to include details on the following:

However we do have figures for private key encryption and support files (including 512, 1024, 2048, 3072, and 4096 bit keys) are included in the times/ directory. The following is an indication of relative performance:

Times to do a private key encryption, done via the 
x509 -signkey test1024 <testcert
LLONG stands for the LONGLONG variable being defined in rsa/bn.h
 
80486dx/50MHz Solaris 2.4 - gcc -O2 (gcc 2.6.3)
     Normal   LLONG
 512   0.77    0.52
1024   5.03    3.10
2048  37.81   22.11
3072          73.75
 
RS6000/??? AIX 3.2 - cc -O (LLONG generate bad code)
     Normal
 512   0.48
1024   2.91
2048  20.92
 
Sparc 10 Solaris 2.3 - gcc -O2 (gcc 2.6.3) / cc -fast (SC3.0)
        gcc gccLLONG       cc  ccLLONG
 512   0.60     0.43     0.24     0.33
1024   4.25     2.89     1.52     2.15
2048  31.95    21.74    10.86    15.95
3072                    36.22
 
DGUX 8500/88110 gcc -O2 (gcc 2.5.7)
     Normal   LLONG
 512   0.20    0.25
1024   1.19    1.63
2048   8.43   11.86
3072  27.96   33.66
 
SGI challange IRIX 5.3 (200mhz MIPS R4400) cc -O2
     Normal   LLONG
 512   0.11    0.13
1024   0.72    0.88
2048   5.29    6.46
3072  17.76   21.68
4096  41.78
 
HP-UX 9000/887 HPUX 9.04 cc +O4 / gcc -O2 (gcc 2.5.7)
         cc     gcc gccLLONG
 512   0.44    0.14     0.09
1024   3.21    0.88     0.48

2048  24.45    6.30     3.17
3072          21.05    10.44
4096                   24.17
 
DEC Alpha OSF1 V3.0 cc -O2 (64bit) (LLONG generates bad code)
      64bit   32bit
 512   0.05    0.16
1024   0.31    1.20
2048   2.18    8.85
3072   7.15   29.93
4096  16.78
 


10. Distribution and Usage Restrictions

For the exact details you need to refer to the file COPYRIGHT in the top-level directory.

Basically, this implementation of SSL is being distributed under a slightly modified version of the UCB license. Attribution is mandatory. Commercial usage is permitted.

The license and distribution terms for any publically available version or derivative of this code cannot be changed. i.e. this code cannot simply be copied and put under another distrubution license [including the GNU Public License.]

The reason behind this being stated in this direct manner is past experience in code simply being copied and the attribution removed from it and then being distributed as part of other packages. This implementation was a non-trivial and unpaid effort.

We would appreciate feedback on any use of this implementation in either, public domain, shareware or commercial software.

Donations of almost any form to the author(s) will naturally be gratefully accepted and may even result in you joining our Christmas card list ;-)

Given the amount of effort that has been put into this implementation by the authors, any extensions or bug fixes should be forwarded to ssl-bugs@mincom.oz.au.

The majordomo based mailing list for discussions of this implementation is ssl-users@mincom.oz.au and can be joined by sending email to ssl-users-request@mincom.oz.au which will forward instructions for using the majordomo varient that manages these lists.


11. Authentication Model

Both the server and the client can validate each other. The currently shipping Netscape client authenticates any server that it connects to by checking that the certificate offered has been either obtained from Netscape or RSA Data Security Inc.

The current list of certificates are available directly from Netscape and include:

In order for a server implementation based on this implementation (perhaps using the patches to NCSA httpd version 1.3) to work with the current Netscape client, all that should be required is a certificate signed by one of the above trusted list.

The authors have been unable to test this functionality as we do not have such a key.

The patches to NCSA Mosaic version 2.5, however mean that it will connect to Netscape servers using https. This has been tested. Currently we do not bother to authenticate the server (in what we have released) as for our purposes this is not required during testing (one extra function call will enabled this code).


12. Key Management

How do we secure the private key of the user? It must be encrypted as access to it is equivalent to access to the plaintext version of a password. Read the PEM and PGP FAQs for a clear discussion of this. Currently we encrypt the PEM format of the key with a pass phrase using DES.


13. Certificate Management

How do we set things up so that servers and clients can cross-authenticate without ending up with servers and clients that will not communicate across logical security zones? This is one of the unresolved challenges for SSL and other proposed commercial Internet security protocols.


14. Future Directions

SSL is the answer to a number of problems. It should enable most applications to be adapted with little effort to be able to run across non-trusted networks in a secure manner.

A reference implementation (known as SSLREF) is available free of charge for non commercial use for US residents from Netscape. A commercial license for SSLREF is also available from Netscape.

This implementation enables those of us who are not blessed with being US residents to participate in the use of and development of SSL enabled applications. It should also end some of the apparent reluctance to adopt SSL now that it is more freely available.

The key attributes of SSL from the point of view of the authors of this distribution:

14.1 Privacy Enhanced Mail

There are lots of things in common here that should be looked at

14.2 Secure Unix-Unix authentication

We intend to layer a kerberos-style security mechanism on top of this such that we can have secure machine to machine login without the requirement of a password exchange or requiring hosts to trust each other. This is a logical extension of the certificate management stuff. The basic outline is as follows:

14.3 Link level security

It should be possible to implement an auto-pushed STREAMS module that provides transparent SSL support for all applications in any modern SVR4 based kernel. Implementation of this is left as an exercise for the reader :-)

Alternatively, for those environments that support pre-load libraries (e.g. SunOS 5.x), a wrapper to perform SSL is fairly straight forward to implement. The author of this document has already implemented SOCKS support in such a manner.


15. Certificates

Certificate Handling Interface


16. Porting Notes

NCSA Mosaic 2.5

SRA Telnet

NCSA HTTPD 1.3