1269670Sjkim=pod 2269670Sjkim 3269670Sjkim=head1 NAME 4269670Sjkim 5269670SjkimSSL_CTX_set_tlsext_ticket_key_cb - set a callback for session ticket processing 6269670Sjkim 7269670Sjkim=head1 SYNOPSIS 8269670Sjkim 9269670Sjkim #include <openssl/tls1.h> 10269670Sjkim 11269670Sjkim long SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX sslctx, 12269670Sjkim int (*cb)(SSL *s, unsigned char key_name[16], 13269670Sjkim unsigned char iv[EVP_MAX_IV_LENGTH], 14269670Sjkim EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)); 15269670Sjkim 16269670Sjkim=head1 DESCRIPTION 17269670Sjkim 18269670SjkimSSL_CTX_set_tlsext_ticket_key_cb() sets a callback fuction I<cb> for handling 19269670Sjkimsession tickets for the ssl context I<sslctx>. Session tickets, defined in 20269670SjkimRFC5077 provide an enhanced session resumption capability where the server 21269670Sjkimimplementation is not required to maintain per session state. It only applies 22269670Sjkimto TLS and there is no SSLv3 implementation. 23269670Sjkim 24269670SjkimThe callback is available when the OpenSSL library was built without 25269670SjkimI<OPENSSL_NO_TLSEXT> being defined. 26269670Sjkim 27269670SjkimThe callback function I<cb> will be called for every client instigated TLS 28269670Sjkimsession when session ticket extension is presented in the TLS hello 29269670Sjkimmessage. It is the responsibility of this function to create or retrieve the 30269670Sjkimcryptographic parameters and to maintain their state. 31269670Sjkim 32269670SjkimThe OpenSSL library uses your callback function to help implement a common TLS 33269670Sjkimticket construction state according to RFC5077 Section 4 such that per session 34269670Sjkimstate is unnecessary and a small set of cryptographic variables needs to be 35269670Sjkimmaintained by the callback function implementation. 36269670Sjkim 37269670SjkimIn order to reuse a session, a TLS client must send the a session ticket 38269670Sjkimextension to the server. The client can only send exactly one session ticket. 39269670SjkimThe server, through the callback function, either agrees to reuse the session 40269670Sjkimticket information or it starts a full TLS handshake to create a new session 41269670Sjkimticket. 42269670Sjkim 43269670SjkimBefore the callback function is started I<ctx> and I<hctx> have been 44269670Sjkiminitialised with EVP_CIPHER_CTX_init and HMAC_CTX_init respectively. 45269670Sjkim 46269670SjkimFor new sessions tickets, when the client doesn't present a session ticket, or 47269670Sjkiman attempted retreival of the ticket failed, or a renew option was indicated, 48269670Sjkimthe callback function will be called with I<enc> equal to 1. The OpenSSL 49269670Sjkimlibrary expects that the function will set an arbitary I<name>, initialize 50269670SjkimI<iv>, and set the cipher context I<ctx> and the hash context I<hctx>. 51269670Sjkim 52269670SjkimThe I<name> is 16 characters long and is used as a key identifier. 53269670Sjkim 54269670SjkimThe I<iv> length is the length of the IV of the corresponding cipher. The 55269670Sjkimmaximum IV length is L<EVP_MAX_IV_LENGTH> bytes defined in B<evp.h>. 56269670Sjkim 57269670SjkimThe initialization vector I<iv> should be a random value. The cipher context 58269670SjkimI<ctx> should use the initialisation vector I<iv>. The cipher context can be 59269670Sjkimset using L<EVP_EncryptInit_ex>. The hmac context can be set using L<HMAC_Init_ex>. 60269670Sjkim 61269670SjkimWhen the client presents a session ticket, the callback function with be called 62269670Sjkimwith I<enc> set to 0 indicating that the I<cb> function should retreive a set 63269670Sjkimof parameters. In this case I<name> and I<iv> have already been parsed out of 64269670Sjkimthe session ticket. The OpenSSL library expects that the I<name> will be used 65269670Sjkimto retrieve a cryptographic parameters and that the cryptographic context 66269670SjkimI<ctx> will be set with the retreived parameters and the initialization vector 67269670SjkimI<iv>. using a function like L<EVP_DecryptInit_ex>. The I<hctx> needs to be set 68269670Sjkimusing L<HMAC_Init_ex>. 69269670Sjkim 70269670SjkimIf the I<name> is still valid but a renewal of the ticket is required the 71269670Sjkimcallback function should return 2. The library will call the callback again 72269670Sjkimwith an arguement of enc equal to 1 to set the new ticket. 73269670Sjkim 74269670SjkimThe return value of the I<cb> function is used by OpenSSL to determine what 75269670Sjkimfurther processing will occur. The following return values have meaning: 76269670Sjkim 77269670Sjkim=over 4 78269670Sjkim 79269670Sjkim=item Z<>2 80269670Sjkim 81269670SjkimThis indicates that the I<ctx> and I<hctx> have been set and the session can 82269670Sjkimcontinue on those parameters. Additionally it indicates that the session 83269670Sjkimticket is in a renewal period and should be replaced. The OpenSSL library will 84269670Sjkimcall I<cb> again with an enc argument of 1 to set the new ticket (see RFC5077 85269670Sjkim3.3 paragraph 2). 86269670Sjkim 87269670Sjkim=item Z<>1 88269670Sjkim 89269670SjkimThis indicates that the I<ctx> and I<hctx> have been set and the session can 90269670Sjkimcontinue on those parameters. 91269670Sjkim 92269670Sjkim=item Z<>0 93269670Sjkim 94269670SjkimThis indicates that it was not possible to set/retrieve a session ticket and 95269670Sjkimthe SSL/TLS session will continue by by negiotationing a set of cryptographic 96269670Sjkimparameters or using the alternate SSL/TLS resumption mechanism, session ids. 97269670Sjkim 98269670SjkimIf called with enc equal to 0 the library will call the I<cb> again to get 99269670Sjkima new set of parameters. 100269670Sjkim 101269670Sjkim=item less than 0 102269670Sjkim 103269670SjkimThis indicates an error. 104269670Sjkim 105269670Sjkim=back 106269670Sjkim 107269670Sjkim=head1 NOTES 108269670Sjkim 109269670SjkimSession resumption shortcuts the TLS so that the client certificate 110269670Sjkimnegiotation don't occur. It makes up for this by storing client certificate 111269670Sjkiman all other negotiated state information encrypted within the ticket. In a 112269670Sjkimresumed session the applications will have all this state information available 113269670Sjkimexactly as if a full negiotation had occured. 114269670Sjkim 115269670SjkimIf an attacker can obtain the key used to encrypt a session ticket, they can 116269670Sjkimobtain the master secret for any ticket using that key and decrypt any traffic 117269670Sjkimusing that session: even if the ciphersuite supports forward secrecy. As 118269670Sjkima result applications may wish to use multiple keys and avoid using long term 119269670Sjkimkeys stored in files. 120269670Sjkim 121269670SjkimApplications can use longer keys to maintain a consistent level of security. 122269670SjkimFor example if a ciphersuite uses 256 bit ciphers but only a 128 bit ticket key 123269670Sjkimthe overall security is only 128 bits because breaking the ticket key will 124269670Sjkimenable an attacker to obtain the session keys. 125269670Sjkim 126269670Sjkim=head1 EXAMPLES 127269670Sjkim 128269670SjkimReference Implemention: 129269670Sjkim SSL_CTX_set_tlsext_ticket_key_cb(SSL,ssl_tlsext_ticket_key_cb); 130269670Sjkim .... 131269670Sjkim 132269670Sjkim 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) 133269670Sjkim { 134269670Sjkim if (enc) { /* create new session */ 135269670Sjkim if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) ) { 136269670Sjkim return -1; /* insufficient random */ 137269670Sjkim } 138269670Sjkim 139269670Sjkim key = currentkey(); /* something that you need to implement */ 140269670Sjkim if ( !key ) { 141269670Sjkim /* current key doesn't exist or isn't valid */ 142269670Sjkim key = createkey(); /* something that you need to implement. 143269670Sjkim * createkey needs to initialise, a name, 144269670Sjkim * an aes_key, a hmac_key and optionally 145269670Sjkim * an expire time. */ 146269670Sjkim if ( !key ) { /* key couldn't be created */ 147269670Sjkim return 0; 148269670Sjkim } 149269670Sjkim } 150269670Sjkim memcpy(key_name, key->name, 16); 151269670Sjkim 152269670Sjkim EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv); 153269670Sjkim HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL); 154269670Sjkim 155269670Sjkim return 1; 156269670Sjkim 157269670Sjkim } else { /* retrieve session */ 158269670Sjkim key = findkey(name); 159269670Sjkim 160269670Sjkim if (!key || key->expire < now() ) { 161269670Sjkim return 0; 162269670Sjkim } 163269670Sjkim 164269670Sjkim HMAC_Init_ex(&hctx, key->hmac_key, 16, EVP_sha256(), NULL); 165269670Sjkim EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv ); 166269670Sjkim 167269670Sjkim if (key->expire < ( now() - RENEW_TIME ) ) { 168269670Sjkim /* return 2 - this session will get a new ticket even though the current is still valid */ 169269670Sjkim return 2; 170269670Sjkim } 171269670Sjkim return 1; 172269670Sjkim 173269670Sjkim } 174269670Sjkim } 175269670Sjkim 176269670Sjkim 177269670Sjkim 178269670Sjkim=head1 RETURN VALUES 179269670Sjkim 180269670Sjkimreturns 0 to indicate the callback function was set. 181269670Sjkim 182269670Sjkim=head1 SEE ALSO 183269670Sjkim 184269670SjkimL<ssl(3)|ssl(3)>, L<SSL_set_session(3)|SSL_set_session(3)>, 185269670SjkimL<SSL_session_reused(3)|SSL_session_reused(3)>, 186269670SjkimL<SSL_CTX_add_session(3)|SSL_CTX_add_session(3)>, 187269670SjkimL<SSL_CTX_sess_number(3)|SSL_CTX_sess_number(3)>, 188269670SjkimL<SSL_CTX_sess_set_get_cb(3)|SSL_CTX_sess_set_get_cb(3)>, 189269670SjkimL<SSL_CTX_set_session_id_context(3)|SSL_CTX_set_session_id_context(3)>, 190269670Sjkim 191269670Sjkim=head1 HISTORY 192269670Sjkim 193269670SjkimThis function was introduced in OpenSSL 0.9.8h 194269670Sjkim 195269670Sjkim=cut 196