You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
7.5 KiB
195 lines
7.5 KiB
=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
|
|
|