| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | =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, | 
					
						
							| 
									
										
										
										
											2017-01-21 02:58:49 +08:00
										 |  |  |      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)); | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 DESCRIPTION | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | SSL_CTX_set_tlsext_ticket_key_cb() sets a callback function I<cb> for handling | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | session tickets for the ssl context I<sslctx>. Session tickets, defined in | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 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 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | The OpenSSL library uses your callback function to help implement a common TLS | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | ticket construction state according to RFC5077 Section 4 such that per session | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | state is unnecessary and a small set of cryptographic variables needs to be | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | Before the callback function is started I<ctx> and I<hctx> have been | 
					
						
							| 
									
										
										
										
											2018-10-18 04:30:32 +08:00
										 |  |  | initialised with L<EVP_CIPHER_CTX_reset(3)> and L<HMAC_CTX_reset(3)> respectively. | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | For new sessions tickets, when the client doesn't present a session ticket, or | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | an attempted retrieval of the ticket failed, or a renew option was indicated, | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | the callback function will be called with I<enc> equal to 1. The OpenSSL | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | library expects that the function will set an arbitrary I<name>, initialize | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | I<iv>, and set the cipher context I<ctx> and the hash context I<hctx>. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 21:50:08 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2016-03-19 18:39:47 +08:00
										 |  |  | maximum IV length is B<EVP_MAX_IV_LENGTH> bytes defined in B<evp.h>. | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2016-03-19 18:39:47 +08:00
										 |  |  | set using L<EVP_EncryptInit_ex(3)>. The hmac context can be set using | 
					
						
							|  |  |  | L<HMAC_Init_ex(3)>. | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | When the client presents a session ticket, the callback function with be called | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | with I<enc> set to 0 indicating that the I<cb> function should retrieve a set | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | I<ctx> will be set with the retrieved parameters and the initialization vector | 
					
						
							| 
									
										
										
										
											2016-03-19 18:39:47 +08:00
										 |  |  | I<iv>. using a function like L<EVP_DecryptInit_ex(3)>. The I<hctx> needs to be | 
					
						
							|  |  |  | set using L<HMAC_Init_ex(3)>. | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | with an argument of enc equal to 1 to set the new ticket. | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-06 05:31:05 +08:00
										 |  |  | =item Z<>2 | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | This indicates that the I<ctx> and I<hctx> have been set and the session can | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 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). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-06 05:31:05 +08:00
										 |  |  | =item Z<>1 | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | This indicates that the I<ctx> and I<hctx> have been set and the session can | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | continue on those parameters. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-06 05:31:05 +08:00
										 |  |  | =item Z<>0 | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  | This indicates that it was not possible to set/retrieve a session ticket and | 
					
						
							| 
									
										
										
										
											2016-03-20 23:51:06 +08:00
										 |  |  | the SSL/TLS session will continue by negotiating a set of cryptographic | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | negotiation don't occur. It makes up for this by storing client certificate | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | an all other negotiated state information encrypted within the ticket. In a | 
					
						
							|  |  |  | resumed session the applications will have all this state information available | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | exactly as if a full negotiation had occurred. | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 21:50:08 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2017-03-30 05:38:30 +08:00
										 |  |  | using that session: even if the cipher suite supports forward secrecy. As | 
					
						
							| 
									
										
										
										
											2014-07-03 21:50:08 +08:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2017-03-30 05:38:30 +08:00
										 |  |  | For example if a cipher suite uses 256 bit ciphers but only a 128 bit ticket key | 
					
						
							| 
									
										
										
										
											2014-07-03 21:50:08 +08:00
										 |  |  | the overall security is only 128 bits because breaking the ticket key will | 
					
						
							|  |  |  | enable an attacker to obtain the session keys. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-26 13:11:10 +08:00
										 |  |  | =head1 RETURN VALUES | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | returns 0 to indicate the callback function was set. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | =head1 EXAMPLES | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 00:48:06 +08:00
										 |  |  | Reference Implementation: | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |  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 */ | 
					
						
							| 
									
										
										
										
											2018-04-17 14:54:26 +08:00
										 |  |  |          if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0) | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |              return -1; /* insufficient random */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          key = currentkey(); /* something that you need to implement */ | 
					
						
							|  |  |  |          if (key == NULL) { | 
					
						
							|  |  |  |              /* 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 == NULL) /* 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 == NULL || 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 one is still valid. | 
					
						
							|  |  |  |               */ | 
					
						
							|  |  |  |              return 2; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  |          return 1; | 
					
						
							|  |  |  |      } | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 SEE ALSO | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 16:33:09 +08:00
										 |  |  | L<ssl(7)>, L<SSL_set_session(3)>, | 
					
						
							| 
									
										
										
										
											2015-08-18 03:21:33 +08:00
										 |  |  | L<SSL_session_reused(3)>, | 
					
						
							|  |  |  | L<SSL_CTX_add_session(3)>, | 
					
						
							|  |  |  | L<SSL_CTX_sess_number(3)>, | 
					
						
							|  |  |  | L<SSL_CTX_sess_set_get_cb(3)>, | 
					
						
							|  |  |  | L<SSL_CTX_set_session_id_context(3)>, | 
					
						
							| 
									
										
										
										
											2014-07-03 10:42:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 23:44:05 +08:00
										 |  |  | =head1 COPYRIGHT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 20:34:30 +08:00
										 |  |  | Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2016-05-18 23:44:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 21:04:44 +08:00
										 |  |  | Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2016-05-18 23:44:05 +08:00
										 |  |  | this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  | in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  | L<https://www.openssl.org/source/license.html>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =cut |