Back to index

courier  0.68.2
libcouriertls.h
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2002-2008 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #ifndef libcouriertls_h
00007 #define libcouriertls_h
00008 
00009 #include      "config.h"
00010 #include      <stdio.h>
00011 #include      <string.h>
00012 #include      <sys/types.h>
00013 #include      <sys/time.h>
00014 #if    HAVE_SYS_SELECT_H
00015 #include      <sys/select.h>
00016 #endif
00017 #if    HAVE_UNISTD_H
00018 #include      <unistd.h>
00019 #endif
00020 #if    HAVE_FCNTL_H
00021 #include      <fcntl.h>
00022 #endif
00023 
00024 #ifdef COURIERTCPD_EXPOSE_OPENSSL
00025 
00026 #define       DEBUG_SAFESTACK      1      /* For openssl 0.9.6 */
00027 
00028 #include      <openssl/ssl.h>
00029 #include      <openssl/err.h>
00030 
00031 typedef SSL_CTX *ssl_context;
00032 typedef SSL *ssl_handle;
00033 #else
00034 
00035 struct ssl_context_t;
00036 struct ssl_handle_t;
00037 
00038 typedef struct ssl_context_t *ssl_context;
00039 typedef struct ssl_handle_t *ssl_handle;
00040 #endif
00041 
00042 #ifdef  __cplusplus
00043 extern "C" {
00044 #endif
00045 
00046 
00047 /*
00048 **                   High level TLS interface library
00049 **
00050 ** This library implements a higher level OpenSSL API, taking care of any gory
00051 ** low level details.
00052 */
00053 
00054 /*
00055 ** This tls_info structure must be initialized before calling tls_create().
00056 */
00057 
00058 struct CACHE;
00059 
00060 struct tls_info {
00061 
00062        /*
00063        ** For SSL/TLS clients that wish to validate the server's certificate,
00064        ** set 'peer_verify_domain' to the required certificate CN field.
00065        ** Leave peer_verify_domain at NULL if server's certificate should
00066        ** not be verified.
00067        */
00068 
00069        const char *peer_verify_domain;
00070 
00071        /*
00072        ** If the following function is not NULL, it will be called
00073        ** after SSL negotiation completes.  If this function returns 0,
00074        ** the SSL connection gets torn down.
00075        */
00076 
00077        int (*connect_callback)(ssl_handle , void *);
00078 
00079        /*
00080        ** When libcouriertls.a feels the urge to report an error, this
00081        ** function gets called with an error message.
00082        */
00083 
00084        void (*tls_err_msg)(const char *err_msg,
00085                          void *app_data /* see below */);
00086 
00087        /*
00088        ** The plethora of OpenSSL configuration settings are wrapped up
00089        ** in this function.  libcouriertls.a will call the following function
00090        ** to obtain a particular configuration setting, represented by a
00091        ** label.  The function should return the setting's configuration
00092        ** value, as a text string.
00093        **
00094        ** In most cases, calling getenv() will be sufficient here.
00095        ** See below for a complete list of currently defined configuration
00096        ** settings.
00097        */
00098 
00099        const char * (*getconfigvar)(const char *, void *);
00100 
00101        /*
00102        ** Retrieve client SSL TLS certificates. If this function pointer is
00103        ** not NULL, this callback gets invoked repeatedly, with the first
00104        ** parameter starting at zero and increasing until the callback
00105        ** function returns 0.
00106        **
00107        ** A non-zero return means that the callback function initialized
00108        ** *cert_array_ret and *cert_array_size_ret to a pointer to a
00109        ** PEM-formatted client SSL certificate, and its size in bytes.
00110        ** The PEM file should contain a "BEGIN CERTIFICATE" followed by a
00111        ** "BEGIN * PRIVATE KEY" (passphrase-protected keys and certs are
00112        ** not yet supported. A zero return means that a cert/key is not
00113        ** available.
00114        **
00115        ** The first parameter is the certificate index number. 0 puts
00116        ** the first available client certificate into cert_array_ret
00117        ** and cert_array_size_ret and returns non-zero, or a zero return
00118        ** if no SSL client certificates are available. If a client certificate
00119        ** is returned, the callback function MAY get invoked again with
00120        ** the first parameter set to 1, to retrieve the second client
00121        ** certificate (if available). This continues until the callback
00122        ** function returns zero, or until the returned SSL certificate's
00123        ** issuer matches the acceptable issuers, as requested by the peer.
00124        **
00125        ** The callback function cannot expect that all available SSL client
00126        ** certs will get retrieved. If a suitable cert is found, no more
00127        ** will be requested.
00128        */
00129 
00130        int (*getpemclientcert4ca)(size_t i,
00131                                const char **cert_array_ret,
00132                                size_t *cert_array_size_ret,
00133                                void *dummy_arg);
00134        /*
00135        ** If this callback function is defined, it gets invoked before
00136        ** the first SSL client certificate gets requested. Its typical
00137        ** purpose is to load all the available client certificates into
00138        ** readily-available memory buffer of some sorts.
00139        */
00140        void (*loadpemclientcert4ca)(void *dummy_arg);
00141 
00142        /*
00143        ** Once a suitable SSL certificate is returned, or after all
00144        ** certificates are returned (getpemclientcert4ca returned zero),
00145        ** this function gets invoked. Its typical purpose is to unload
00146        ** all memory buffers used by loaded client certs, and release all
00147        ** memory allocated by loadpemclient4ca.
00148        */
00149 
00150        void (*releasepemclientcert4ca)(void *dummy_arg);
00151 
00152        /*
00153        ** app_data is a transparent pointer that's passed along as the last
00154        ** argument to the callback functions above.
00155        */
00156 
00157        void *app_data;
00158 
00159        /*
00160        ** Everything below is internal data.
00161        */
00162        struct CACHE *tlscache;
00163        int isserver;
00164 
00165        int connect_interrupted;
00166        int accept_interrupted;
00167 
00168        int certificate_verified;
00169 };
00170 
00171 /*
00172 ** tls_get_default_info() returns a default tls_info structure, with their
00173 ** default values.
00174 */
00175 const struct tls_info *tls_get_default_info();
00176 
00177 /*
00178 ** Create or destroy an SSL context.  'isserver' is non-zero for a server
00179 ** context, zero for a client context.  tls_create() makes a copy of the
00180 ** tls_info structure, for its own internal use.  The functions and data
00181 ** in the tls_info structure will continue to be used until the context is
00182 ** destroyed, from the internally-maintained copy, though.
00183 **
00184 ** Do not call tls_destroy until all sessions are similarly destroyed.
00185 */
00186 
00187 ssl_context tls_create(int isserver, const struct tls_info *);
00188 void tls_destroy(ssl_context ctx);
00189 
00190 /*
00191 ** SSL connect/disconnect.  tls_connect() creates a new SSL connection on
00192 ** an existing file descriptor.
00193 */
00194 
00195 ssl_handle tls_connect(ssl_context ctx, int fd);
00196 
00197 void tls_disconnect(ssl_handle ssl, int fd);
00198 
00199 /*
00200 ** Return non-zero if connection is still in progress
00201 */
00202 
00203 int tls_connecting(ssl_handle );
00204 
00205 /*
00206 ** Return non-zero if the certificate was verified
00207 */
00208 
00209 int tls_certificate_verified(ssl_handle);
00210 
00211 /*
00212 ** Once an SSL/TLS session is established, use the following structure to
00213 ** read or write to the SSL/TLS socket.  The tls_transfer function reads
00214 ** and/or writes to the SSL/TLS socket, simultaneously.
00215 **
00216 ** To read SSL data, set readptr to point to the buffer, and readleft to the
00217 ** # of bytes in the buffer.  Both readptr and readleft are updated if data
00218 ** was read from the socket by tls_transfer().  tls_transfer() will not read
00219 ** from the socket if readleft is zero.
00220 **
00221 ** To write SSL data, set writeptr and writeleft to point to the buffer to
00222 ** be written out.  tls_transfer() will update writeptr/writeleft, if it
00223 ** wrote succesfully.  tls_transfer() may end up writing out only a portion
00224 ** of the buffer.  Do not reset writeptr and writeleft until tls_transfer()
00225 ** updates writeleft to 0, which indicates that the data has been written out
00226 ** succesfully.
00227 **
00228 ** A tls_transfer_info object is initialized by tls_connect().
00229 */
00230 
00231 struct tls_transfer_info {
00232 
00233        char *readptr;
00234        size_t readleft;
00235 
00236        const char *writeptr;
00237        size_t writeleft;
00238 
00239        int read_interrupted;
00240        int write_interrupted;
00241 
00242        int shutdown;
00243        int shutdown_interrupted;
00244 };
00245 
00246 #define tls_transfer_init(i) memset((i), 0, sizeof(*i));
00247 
00248 /*
00249 **  Read and/or write from the SSL/TLS socket.  tls_transfer() updates
00250 **  the info object, after reading or writing 'ssl', on 'fd'.
00251 **
00252 **  tls_transfer returns 0 if the read/write operation was processed
00253 **  succesfully (the write operation may not be written out in entirety,
00254 **  check writeleft).
00255 **
00256 **  tls_transfer returns a negative value if there was an SSL/TLS protocol
00257 **  error, or the SSL/TLS connection closed. The SSL connection should be
00258 **  destroyed by calling tls_disconnect().
00259 **
00260 **  tls_transfer returns a positive value if tls_transfer() could not complete
00261 **  a read or a write operation because no data was available on
00262 **  the socket and/or the socket's output buffer is full.
00263 **  The file descriptor sets 'r' and 'w' are updated to indicate the
00264 **  desired socket state, and the tls_inprogress() macro will return true.
00265 **
00266 **  tls_transfer returns a positive value, and tls_inprogress() macro will
00267 **  return false if there was nothing to read or write on the socket
00268 **  (both readleft and writeleft were zero).
00269 */
00270 
00271 int    tls_transfer(struct tls_transfer_info *info, ssl_handle ssl, int fd,
00272                    fd_set *r, fd_set *w);
00273 
00274 #define tls_inprogress(s) ((s)->read_interrupted || (s)->write_interrupted || \
00275                      (s)->shutdown_interrupted)
00276 
00277 void tls_dump_connection_info(ssl_handle ssl,
00278                            int server,
00279                            void (*dump_func)(const char *, int cnt, void *),
00280                            void *dump_arg);
00281 
00282 char *tls_get_encryption_desc(ssl_handle ssl);
00283 
00284 char *tls_cert_name(const char *buf, size_t buf_size);
00285 
00286 /*
00287 ** Start orderly SSL/TLS connection disconnect.
00288 */
00289 
00290 #define tls_closing(s) ((s)->shutdown_interrupted=1)
00291 #define tls_isclosing(s) ((s)->shutdown_interrupted)
00292 #define tls_isclosed(s) ((s)->shutdown)
00293 
00294 
00295 int tls_validate_pem_cert(const char *buf, size_t buf_size);
00296 
00297 #ifdef  __cplusplus
00298 }
00299 #endif
00300 
00301 /******************  Configuration variables ******************************
00302 
00303 
00304 TLS_PROTOCOL sets the protocol version.  The possible versions are:
00305 
00306 SSL2 - SSLv2
00307 SSL3 - SSLv3
00308 TLS1 - TLS1
00309 
00310 
00311 TLS_CIPHER_LIST optionally sets the list of ciphers to be used by the
00312 OpenSSL library.  In most situations you can leave TLS_CIPHER_LIST
00313 undefined.
00314 
00315 TLS_TIMEOUT - session timeout fot TLS1
00316 
00317 TLS_DHCERTFILE - PEM file that stores our Diffie-Hellman cipher pair.
00318 When OpenSSL is compiled to use Diffie-Hellman ciphers instead of RSA
00319 you must generate a DH pair that will be used.  In most situations the
00320 DH pair is to be treated as confidential, and the file specified by
00321 TLS_DHCERTFILE must not be world-readable.
00322 
00323 TLS_CERTFILE - PEM file that stores the RSA secret key and certificate.
00324 TLS_CERTFILE is required for SSL/TLS servers, and is optional for SSL/TLS
00325 clients.  TLS_CERTFILE is usually treated as confidential, and must not be
00326 world-readable.
00327 
00328 TLS_TRUSTCERTS=pathname - load trusted root certificates from pathname.
00329 pathname can be a file or a directory. If a file, the file should
00330 contain a list of trusted certificates, in PEM format. If a
00331 directory, the directory should contain the trusted certificates,
00332 in PEM format, one per file and hashed using OpenSSL's c_rehash
00333 script. TLS_TRUSTCERTS is used by SSL/TLS clients (by specifying
00334 the -domain option) and by SSL/TLS servers (TLS_VERIFYPEER is set
00335 to PEER or REQUIREPEER).
00336 
00337 TLS_VERIFYPEER - how to verify client certificates.  The possible values of
00338 this setting are:
00339 
00340 NONE - do not verify anything
00341 PEER - verify the client certificate, if one's presented
00342 REQUIREPEER - require a client certificate, fail if one's not presented
00343 
00344 TLS_CACHEFILE - if defined, specifies the pathname to a file that is used to
00345 SSL/TLS sessions.  Some clients that open multiple SSL connections can take
00346 advantage of SSL/TLS session caching.
00347 
00348 TLS_CACHESIZE - the size of the TLS_CACHEFILE to create, if it does not
00349 exist.
00350 
00351 TLS_INTCACHESIZE - the size of the internal OpenSSL SSL session cache.
00352 OpenSSL's documentations states that the default size is 20,000 sessions.
00353 Use this configuration setting to reduce the default size in order to reduce
00354 the memory footprint of SSL-enabled processes.
00355 
00356 TCPLOCALIP - the local IP address.  Used in server settings.  If
00357 TLS_CERTFILE/TLS_DHCERTFILE does not exist, append ".TCPLOCALIP" and try
00358 again.
00359 
00360 *************************************************************************/
00361 
00362 #endif