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