=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 sslctx,
        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 tickets for the ssl context I<sslctx>. Session tickets, defined in 
RFC5077 provide an enhanced session resumption capability where the server
implementation is not required to maintain per session state. It only applies
to TLS and there is no SSLv3 implementation.

The callback is available when the OpenSSL library was built without 
I<OPENSSL_NO_TLSEXT> being defined.

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

The OpenSSL library uses your callback function to help implement a common TLS 
ticket construction state according to RFC5077 Section 4 such that per session
state is unnecessary and a small set of cryptographic variables needs to be 
maintained by the callback function implementation.

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

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 tickets, when the client doesn't present a session ticket, or
an attempted retreival of the ticket failed, or a renew option was indicated,
the callback function will be called with I<enc> equal to 1. The OpenSSL
library expects that the function will set an arbitary I<name>, initialize
I<iv>, and set the cipher context I<ctx> and the hash context I<hctx>.

The I<name> is 16 characters long and is used as a key identifier.

The I<iv> length is the length of the IV of the corresponding cipher. The
maximum IV length is L<EVP_MAX_IV_LENGTH> bytes 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 ticket, the callback function with be called 
with I<enc> set to 0 indicating that the I<cb> function should retreive a set
of parameters. In this case I<name> and I<iv> have already been parsed out of
the session ticket. 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 set with the retreived parameters and the initialization vector
I<iv>. using a function like L<EVP_DecryptInit_ex>. The I<hctx> needs to be set
using L<HMAC_Init_ex>.

If the I<name> is still valid but a renewal of the ticket is required the
callback function should return 2. The library will call the callback again
with an arguement of enc equal to 1 to set the new ticket.

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 Z<>2

This indicates that the I<ctx> and I<hctx> have been set and the session can 
continue on those parameters. Additionally it indicates that the session
ticket is in a renewal period and should be replaced. The OpenSSL library will
call I<cb> again with an enc argument of 1 to set the new ticket (see RFC5077
3.3 paragraph 2).

=item Z<>1

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

=item Z<>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 or using the alternate SSL/TLS resumption mechanism, session ids.

If called with enc equal to 0 the library will call the I<cb> again to get
a new set of parameters.

=item less than 0

This indicates an error.

=back

=head1 NOTES

Session resumption shortcuts the TLS so that the client certificate
negiotation don't occur. It makes up for this by storing client certificate
an all other negotiated state information encrypted within the ticket. In a
resumed session the applications will have all this state information available
exactly as if a full negiotation had occured.

If an attacker can obtain the key used to encrypt a session ticket, they can
obtain the master secret for any ticket using that key and decrypt any traffic
using that session: even if the ciphersuite supports forward secrecy. As
a result applications may wish to use multiple keys and avoid using long term
keys stored in files.

Applications can use longer keys to maintain a consistent level of security.
For example if a ciphersuite uses 256 bit ciphers but only a 128 bit ticket key
the overall security is only 128 bits because breaking the ticket key will
enable an attacker to obtain the session keys.

=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 */
          if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) ) {
              return -1; /* insufficient random */
          }
  
          key = currentkey(); /* something that you need to implement */
          if ( !key ) {
              /* current key doesn't exist or isn't valid */
              key = createkey(); /* something that you need to implement.
                                   * createkey needs to initialise, a name,
                                   * an aes_key, a hmac_key and optionally
                                   * an expire time. */
              if ( !key ) { /* key couldn't be created */
                  return 0;
              }
          }
          memcpy(key_name, key->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 < now() ) {
              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 < ( now() - 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
