SSLeay Programmer Reference

SSLeay 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-Jan-96. The documentation version number is 1.1.

The version of SSLeay at the time of writing was 0.4.2.

This documentation is Copyright Tim Hudson (tjh@mincom.oz.au). See the COPYRIGHT file for the usage and redistribution restrictions.

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, SSL 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. Also full source trees for most of these are available in the same location as people have had difficulty finding the same version of the source that I've patched.

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).

This documentation is Copyright Tim Hudson (tjh@mincom.oz.au). See the COPYRIGHT file for the usage and redistribution restrictions.

Note: a nicely formatted postscript version of this document is included in the file SSLeay.doc-version.tar.gz in the same directory as the SSLeay source.


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] www.psy.uq.oz.au:/~ftp/Crypto/ - online documentation
[5] ftp.bond.edu.au:/pub/Crypto/SSLapps - SSL applications
[6] www.psy.uq.oz.au:/~ftp/Crypto/ - online documentation
[7] Secure RPC Authentication (SRA) for TELNET and FTP
[8] RFC1409 Telnet Authentication Option
[9] ietf ftpsec draft FTP Security Extensions

Note: the primary site for fetching the SSL applications code is ftp.psy.uq.oz.au, however I push the initial versions and other interesting stuff to ftp.bond.edu.au first as that is where I have best access.


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

The new error handling stuff is (from the callers point of view) a much simplier interface:

 void SSL_load_error_strings(void);
 unsigned long ERR_get_error(void);
 char *ERR_error_string(unsigned long error);
 void ERR_print_errors(FILE *fp);

So on application initialisation if you want non-numeric error string you simply call SSL_load_error_strings() and then use either of the two different interfaces for getting at the error information:

 error_code=ERR_get_error();
 string=ERR_error_string(error_code);
    OR
 ERR_print_errors(stderr);

5.3 Create SSL Context

All information that is likely to be of use on more than one SSL connection is now stored in a context structure. You specify the binding between an SSL connection and it's context when you call SSL_new(). The context can (and should) be shared between SSL connections.

 SSL_CTX *SSL_CTX_new(void)

5.4 Create SSL Handle

Before anything useful can be done on an SSL connection you must have created and initialise the context data structure for SSL state using SSL_CTX_new(). SSL_new() simply allocates the required SSL data structure and initialises all the right things.


 SSL *SSL_new(SSL_CTX *ssl_ctx)

5.5 Release Handle

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

 void SSL_free(SSL *s)

5.6 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.7 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.8 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.9 Bind descriptor

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

 void SSL_set_fd(SSL *s, int fd)

5.10 Set read-ahead

By default, SSL does not read more data from the network than is requested. However if you are not using select() to determine the availability of data, you can get a significant throughput improvement by simply switch read-ahead on. See SSL_pending() for a mechanism for determining if there is more data available.


 void SSL_set_read_ahead(SSL *s, int yes)

5.11 Get read-ahead

To find out the current setting of the read-ahead flag:

 int SSL_get_read_ahead(SSL *s)

5.12 Check for more data

When using read-ahead mode you cannot rely on select() to determine if more data is available as SSL_read() may have already read data off the wire that has not been read by the caller (the caller will get this data returned in future calls to SSL_read()).

 int SSL_pending(SSL *s)

5.13 Get descriptor binding

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

 int SSL_get_fd(SSL *s)

5.14 Client connect

 int SSL_connect(SSL *s)

5.15 Server accept

 int SSL_accept(SSL *s)

5.16 Read

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

5.17 Write

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

Note: SSL_write() will not sent any data if len is less than or equal to 0.

5.18 Copy session ID

 int SSL_copy_session_id(SSL *to,SSL *from)

5.19 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.20 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 via the following:

 SSL_set_pref_cipher(s,getenv("SSL_CIPHER"))

5.21 Get Negotiated Information

Once SSL_connect() has returned there are a number of functions that can be used to get hold of information about the server and the negotiated cipher.

5.21.1 Negotiated Cipher

Which of the ciphers was actually negotiated.

 char *SSL_get_cipher(SSL *s)

5.21.2 Common Ciphers

To find out what ciphers are in common (and hence could have been negotiated)

 char *SSL_get_shared_ciphers(SSL *s,char *buf,int bufsize)

5.22 Using standard locations

The values in rsa/location.h are accessible via the following functions.

 char *X509_get_default_cert_area(void)
 char *X509_get_default_cert_dir(void)
 char *X509_get_default_cert_file(void)
 char *X509_get_default_cert_dir_env(void)
 char *X509_get_default_cert_file_env(void)
 char *X509_get_default_private_dir(void)

i.e. X509_get_default_cert_area() will return /usr/local/ssl by default.

These settings can also be changed by using the following environment variables:

 SSL_CERT_DIR
 SSL_CERT_FILE

 

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.

  • DES library (if you want to support DES)

  • RSA/X509 library (key generation, certificate management)

  • MD library (for message digest encoding MD2, MD4)

  • SSL library (layered on top of the above)

  • RC4 library (if you want to support RC4)

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, md5)
 rc4/    rc4 implementation
 lhash/  hashing library
 ssl/    SSL itself
 idea/   IDEA

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.

Note: there are a number of compile options that define what is built into the library and which RSA routines are used - you should see the documentation (and the Makefile) for SSLeay for more details.


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
 CBC-IDEA-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:

  • key generation - any size

  • certificate signing

  • connection negotiation

  • stream I/O rates

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:



Solaris 2.4 x86 - gcc 2.6.3 - gcc -O3
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             12.95k       18.19k       46.88k       60.92k       
61.30k
md5            226.03k      439.38k     1402.02k     2319.18k     
2351.77k
rc4           1040.14k     1116.69k     1205.12k     1212.14k     
1196.87k
cfb des        216.49k      221.09k      226.43k      226.79k      
224.93k
cbc des        233.05k      245.25k      256.75k      259.01k      
249.32k
ede3 des        90.06k       96.29k       98.77k       99.32k       
99.30k
cbc idea       165.36k      165.32k      171.28k      172.03k      
171.01k
rsa  512 bits   0.457s
rsa 1024 bits   2.973s
rsa 2048 bits  21.410s
 
Solaris 2.3 sparc - gcc 2.5.7 - gcc -O3 -mv8
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             33.20k       44.80k      109.14k      133.83k      
138.34k
md5            514.25k     1039.74k     3234.35k     4966.93k     
5238.34k
rc4           2946.26k     3114.17k     2886.20k     3092.48k     
3219.07k
cfb des        665.60k      676.08k      687.70k      687.79k      
680.30k
cbc des        711.15k      740.48k      765.26k      760.15k      
761.08k
ede3 des       270.81k      280.86k      284.46k      285.94k      
281.60k
cbc idea       651.28k      657.08k      676.77k      674.86k      
674.47k
rsa  512 bits   0.101s
rsa 1024 bits   0.585s
rsa 2048 bits   4.237s
 
Solaris 2.3 sparc - SC3.0 cc - cc -fast 
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             34.50k       46.64k      113.79k      139.29k      
141.78k
md5            479.50k      987.80k     3147.73k     4837.54k     
5081.77k
rc4           2366.90k     2677.52k     3041.88k     3107.74k     
3003.73k
cfb des        521.83k      537.12k      548.46k      542.61k      
546.13k
cbc des        555.03k      576.64k      603.85k      598.65k      
600.75k
ede3 des       202.03k      207.19k      211.22k      209.58k      
210.26k
cbc idea       581.17k      589.48k      603.56k      606.21k      
604.78k
 
md2             39.73k       54.04k      130.50k      162.47k      
165.55k
md5            478.68k      970.31k     3057.22k     4794.37k     
5087.81k
rc4           2615.54k     2733.65k     2891.73k     2922.70k     
2795.73k
cfb des        479.33k      495.55k      497.95k      498.94k      
502.37k
cbc des        509.65k      528.76k      547.06k      549.01k      
553.51k
ede3 des       180.58k      187.39k      190.84k      188.20k      
187.67k
cbc idea       561.00k      578.81k      591.07k      600.06k      
598.10k
 
 
HPUX 9 - cc - cc +O3
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             58.31k       76.77k      203.38k      232.73k      
239.77k
md5            380.53k      777.80k     2880.53k     4833.42k     
5207.34k
rc4           3455.43k     3742.07k     3775.95k     3827.38k     
3841.96k
cfb des        785.14k      808.87k      828.74k      812.76k      
822.03k
cbc des        842.67k      923.14k      996.71k     1026.41k     
1015.70k
ede3 des       370.38k      374.39k      400.43k      390.04k      
390.92k
cbc idea       286.95k      286.86k      297.07k      280.16k      
301.51k
 
HPUX 9 - gcc 2.7.0 - gcc -O3 -mpa-risc-1-1 (BAD)
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             45.20k       61.45k      133.25k      181.69k      
174.97k
md5            395.22k      811.37k     3365.22k     5636.30k     
6148.28k
rc4           3407.66k     3768.79k     3701.22k     3663.92k     
3808.96k
cfb des        558.30k      588.51k      596.95k      601.76k      
615.16k
cbc des        627.24k      657.47k      714.88k      712.23k      
724.22k
ede3 des       248.47k      263.49k      274.00k      244.59k      
261.69k
cbc idea       583.64k      593.64k      624.32k      621.35k      
628.35k
 
DGUX - gcc 2.6.3 - gcc -O3 (BAD)
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             18.39k       25.10k       60.63k       74.63k       
76.46k
md5            201.13k      400.35k     1710.60k     3260.01k     
3667.54k
rc4           1483.17k     1534.55k     1591.68k     1602.69k     
1598.11k
cfb des        507.36k      529.14k      552.97k      553.97k      
553.30k
cbc des        555.89k      619.98k      689.14k      695.98k      
695.65k
ede3 des       230.74k      243.56k      254.36k      255.83k      
256.17k
cbc idea       458.73k      488.09k      523.71k      528.79k      
530.86k
 
DEC Alpha - gcc 2.7.0 - gcc -O3
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             55.46k       75.96k      185.86k      228.01k      
233.54k
md5            407.02k      793.80k     3266.90k     5732.35k     
6307.38k
rc4           3379.32k     3513.16k     3637.21k     3653.63k     
3604.48k
cfb des        845.70k      887.00k      925.53k      930.82k      
925.70k
cbc des        888.97k      974.52k     1075.80k     1097.00k     
1092.88k
ede3 des       366.57k      386.89k      402.22k      404.48k      
404.14k
cbc idea       683.40k      697.03k      729.17k      733.87k      
735.91k
rsa  512 bits   0.048s
rsa 1024 bits   0.279s
rsa 2048 bits   1.900s
 
IRIX 5.3 r4400 200mhz - gcc 2.6.3 - gcc -O2
type           8 bytes     16 bytes    128 bytes   1024 bytes   8192 
bytes
md2             64.57k       87.03k      213.49k      261.34k      
267.61k
md5            784.47k     1509.64k     5466.85k     8371.29k     
8961.55k
rc4           5257.28k     5541.73k     5827.62k     5854.10k     
5864.34k
cfb des       1298.87k     1333.31k     1366.11k     1373.47k     
1363.50k
cbc des       1421.39k     1492.68k     1572.82k     1583.90k     
1577.72k
ede3 des       558.68k      572.53k      583.90k      585.63k      
582.79k
cbc idea      1197.72k     1218.11k     1265.38k     1274.16k     
1275.53k
rsa  512 bits   0.053s
rsa 1024 bits   0.300s
rsa 2048 bits   2.074s

 

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.

Free licenses for commercial products using this library would naturally be greatly appreciated; however there is no legal requirement to do so.

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 factotum 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:

  • commercial-ca.text

  • netscape-test-ca.text

  • secure-server-ca.text

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. If you do not have a certificate signed by one of the above then the current version of the Netscape browser will not work with the patched NCSA httpd server.

If you do have a signed key then the patches I've done to NCSA httpd 1.3 work with the current version of SSLeay according to reliable reports.

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 (and naturally to the patched NCSA httpd) 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 enable this in the code however you will need to figure out how you are going to manage certificate issuing before you do this).


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:

  • the specification is publically available

  • the protocol is extensible

  • it is (now) available to all users in source form

  • it is application independant

  • it is easy to add to existing applications

  • it is already in use in a number of commercial applications

  • it now can be linked with RSAref (and it works too according to reports we have had) to enable US residents access to this code

14.1 Privacy Enhanced Mail

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

    • some nice encoding ideas and much of what is required to do PEM is in this SSL implementation. This was not the original aim of writing this library. A number of good ideas were taken from the way in which PEM handles things.

PEM and PGP style tools layered on top of this library are a logical step that is planned - and it is not all that much work; however both Eric and myself have been concentrating on other issues.

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:

  • central certificate issuing machine

  • client generates a public and private key

  • client sends via an SSL connection (and hence using the standard certificate exchange) their Unix credentials including their password (details encoded with private key)

  • certificate issuing machines checks the password against the normal Unix password database and if it is correct returns a signed certificate

  • client stores this certificate and uses it to connect to whatever service they wish to ... the private key must be stored encrypted somehow ... we need a daemon that is given a password and can then return the key any number of times to the user without the password being required.

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


17. Patent Issues and other such ramblings

Ramblings from Eric Young


18. Change history

CHANGES