=pod

=head1 NAME

SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, SSL_has_matching_session_id - manipulate generation of SSL session IDs (server only)

=head1 SYNOPSIS

 #include <openssl/ssl.h>

 typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
                               unsigned int *id_len);

 int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb);
 int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB, cb);
 int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
				 unsigned int id_len);

=head1 DESCRIPTION

SSL_CTX_set_generate_session_id() sets the callback function for generating
new session ids for SSL/TLS sessions for B<ctx> to be B<cb>.

SSL_set_generate_session_id() sets the callback function for generating
new session ids for SSL/TLS sessions for B<ssl> to be B<cb>.

SSL_has_matching_session_id() checks, whether a session with id B<id>
(of length B<id_len>) is already contained in the internal session cache
of the parent context of B<ssl>.

=head1 NOTES

When a new session is established between client and server, the server
generates a session id. The session id is an arbitrary sequence of bytes.
The length of the session id is 16 bytes for SSLv2 sessions and between
1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical
but must be unique for the server. Additionally, the session id is
transmitted in the clear when reusing the session so it must not contain
sensitive information.

Without a callback being set, an OpenSSL server will generate a unique
session id from pseudo random numbers of the maximum possible length.
Using the callback function, the session id can be changed to contain
additional information like e.g. a host id in order to improve load balancing
or external caching techniques.

The callback function receives a pointer to the memory location to put
B<id> into and a pointer to the maximum allowed length B<id_len>. The
buffer at location B<id> is only guaranteed to have the size B<id_len>.
The callback is only allowed to generate a shorter id and reduce B<id_len>;
the callback B<must never> increase B<id_len> or write to the location
B<id> exceeding the given limit.

If a SSLv2 session id is generated and B<id_len> is reduced, it will be
restored after the callback has finished and the session id will be padded
with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions.
The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function
to check, whether the session is of type SSLv2.

The location B<id> is filled with 0x00 before the callback is called, so the
callback may only fill part of the possible length and leave B<id_len>
untouched while maintaining reproducibility.

Since the sessions must be distinguished, session ids must be unique.
Without the callback a random number is used, so that the probability
of generating the same session id is extremely small (2^128 possible ids
for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the
uniqueness of the generated session id, the callback must call
SSL_has_matching_session_id() and generate another id if a conflict occurs.
If an id conflict is not resolved, the handshake will fail.
If the application codes e.g. a unique host id, a unique process number, and
a unique sequence number into the session id, uniqueness could easily be
achieved without randomness added (it should however be taken care that
no confidential information is leaked this way). If the application can not
guarantee uniqueness, it is recommended to use the maximum B<id_len> and
fill in the bytes not used to code special information with random data
to avoid collisions.

SSL_has_matching_session_id() will only query the internal session cache,
not the external one. Since the session id is generated before the
handshake is completed, it is not immediately added to the cache. If
another thread is using the same internal session cache, a race condition
can occur in that another thread generates the same session id.
Collisions can also occur when using an external session cache, since
the external cache is not tested with SSL_has_matching_session_id()
and the same race condition applies.

When calling SSL_has_matching_session_id() for an SSLv2 session with
reduced B<id_len>, the match operation will be performed using the
fixed length required and with a 0x00 padded id.

The callback must return 0 if it cannot generate a session id for whatever
reason and return 1 on success.

=head1 EXAMPLES

The callback function listed will generate a session id with the
server id given, and will fill the rest with pseudo random bytes:

 const char session_id_prefix = "www-18";

 #define MAX_SESSION_ID_ATTEMPTS 10
 static int generate_session_id(const SSL *ssl, unsigned char *id,
                              unsigned int *id_len)
      {
      unsigned int count = 0;
      const char *version;

      version = SSL_get_version(ssl);
      if (!strcmp(version, "SSLv2"))
	  /* we must not change id_len */;

      do      {
              RAND_pseudo_bytes(id, *id_len);
              /* Prefix the session_id with the required prefix. NB: If our
               * prefix is too long, clip it - but there will be worse effects
               * anyway, eg. the server could only possibly create 1 session
               * ID (ie. the prefix!) so all future session negotiations will
               * fail due to conflicts. */
              memcpy(id, session_id_prefix,
                      (strlen(session_id_prefix) < *id_len) ?
                      strlen(session_id_prefix) : *id_len);
              }
      while(SSL_has_matching_session_id(ssl, id, *id_len) &&
              (++count < MAX_SESSION_ID_ATTEMPTS));
      if(count >= MAX_SESSION_ID_ATTEMPTS)
              return 0;
      return 1;
      }


=head1 RETURN VALUES

SSL_CTX_set_generate_session_id() and SSL_set_generate_session_id()
always return 1.

SSL_has_matching_session_id() returns 1 if another session with the
same id is already in the cache.

=head1 SEE ALSO

L<ssl(3)|ssl(3)>, L<SSL_get_version(3)|SSL_get_version(3)>

=head1 HISTORY

SSL_CTX_set_generate_session_id(), SSL_set_generate_session_id()
and SSL_has_matching_session_id() have been introduced in
OpenSSL 0.9.7.

=cut
