=pod

=head1 NAME

SSL_CTX_set_tlsext_ticket_key_cb - set a callback for session ticket processing

=head1 SYNOPSIS

 #include <openssl/tls1.h>

 long SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX ctx, int (*cb)(SSL *s, unsigned char key_name[16], unsigned char iv[EVP_MAX_IV_LENGTH], EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc));

=head1 DESCRIPTION

SSL_CTX_set_tlsext_ticket_key_cb() sets a callback fuction I<cb> for handling 
session ids for I<ctx> in RFC 5077.

The callback function I<cb> will be called for every client instigated SSL/TLS
session when session ticket extension is presented in the SSLv3/TLS hello
message. It is the responsibility of this function to create or retrieve the
cryptographic parameters.

The OpenSSL library uses your callback function to help implement a common SSL/TLS 
session state according to RFC5077 such that per session state is unnecessary
and a small set of cryptographic variables needs to be maintained.

In order to reuse a session, a SSL/TLS client must send the session's id to the
server. The client can only send exactly one session id. The server, through 
the callback function, either agrees to reuse the session cryptographic 
information or it starts a full SSL/TLS handshake to create a new session.

If you have called this function to set a callback, and the session tickets
are enabled in the OpenSSL library, and the client supports session tickets
then the callback used.

Before the callback function is started I<ctx> and I<hctx> have been 
initialised with EVP_CIPHER_CTX_init and HMAC_CTX_init respectively.

For new sessions, when the client doesn't present a session id, the callback 
function will be called with I<enc> equal to 1. The OpenSSL library expects 
that the function will set an abitary I<name>, an initialization vector I<iv>,
a the cipher context I<ctx>, and the hash context I<hctx>.

The I<name> is only significant 16 characters long. The I<iv> is of length
L<EVP_MAX_IV_LENGTH> defined in B<evp.h>.

The initialization vector I<iv> should be a random value. The cipher context 
I<ctx> should use the initialisation vector I<iv>. The cipher context can be 
set using L<EVP_EncryptInit_ex>. The hmac context can be set using L<HMAC_Init_ex>.

When the client presents a session id, the callback function with be called 
with I<enc> set to 0. In this case I<name> and I<iv> will be parsed out of the 
session id. The OpenSSL library expects that the I<name> will be used to retrieve a 
cryptographic parameters and that the cryptographic context I<ctx> will be
initialized with the retreived parameters and the initialization vector I<iv>.
The L<EVP_DecryptInit_ex> function is used to extract the cryptographic keys
out of the 

If the I<name> doesn't exist, or has expired, in the storage implemented by
the callback function should return 0.

The return value of the I<cb> function is used by OpenSSL to determine what
further processing will occur. The following return values have meaning:

=over 4

=item 2

This indicates that the session ids are in renewal period and should be 
replaced. After returning this value, the OpenSSL library will call the callback
function again with a enc argument of 1.

=item 1

This indicates that the ctx and hctx have been set and the session can 
continue on those parameters.

=item 0

This indicates that it was not possible to set/retrieve a session ticket and 
the SSL/TLS session will continue by by negiotationing a set of cryptographic
parameters.

=item less than 0

This indicates an error.

=back

=head1 NOTES

Session resumption shortcuts the SSL/TLS so that the client certificate
negiotation don't occur. As such applications depending on client certificate
information will need to maintain this information mapped to the I<key_name> and
I<iv>.

=head1 EXAMPLES

Reference Implemention:
  SSL_CTX_set_tlsext_ticket_key_cb(SSL,ssl_tlsext_ticket_key_cb);
  ....

  static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
  {
      if (enc) { /* create new session */
          RAND_bytes(iv, 16);
  
          key = findkey(current_name); /* something that you need to implement */
          if ( !key ) {
              key = createkey(key_name); /* something that you need to implement */
          }
          memcpy(keyname, current_name,16);
  
          EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv);
          HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL);
  
          return 1;
  
      } else { /* retrieve session */
          key = findkey(name);
  
          if  (!key && key->expire < EXPIRE_TIME ) {
              return 0;
          }
  
          HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL);
          EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv );

          if  (key->expire < ( EXPIRE_TIME - RENEW_TIME ) ) {
              /* return 2 - this session will get a new ticket even though the current is still valid */
              return 2;
          }
          return 1;
  
      }
  }



=head1 RETURN VALUES

returns 0 to indicate the callback function was set.

=head1 SEE ALSO

L<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>,
L<SSL_session_reused(3)|SSL_session_reused(3)>,
L<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>,
L<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>,
L<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>,
L<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>,

=head1 HISTORY

This function was introduced in OpenSSL 0.9.8h

=cut
