mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			244 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| =pod
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| SSL_CTX_set_tlsext_ticket_key_evp_cb,
 | |
| SSL_CTX_set_tlsext_ticket_key_cb
 | |
| - set a callback for session ticket processing
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  #include <openssl/tls1.h>
 | |
| 
 | |
|  int SSL_CTX_set_tlsext_ticket_key_evp_cb(SSL_CTX sslctx,
 | |
|      int (*cb)(SSL *s, unsigned char key_name[16],
 | |
|                unsigned char iv[EVP_MAX_IV_LENGTH],
 | |
|                EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hctx, int enc));
 | |
| 
 | |
| Deprecated since OpenSSL 3.0, can be hidden entirely by defining
 | |
| B<OPENSSL_API_COMPAT> with a suitable version value, see
 | |
| L<openssl_user_macros(7)>:
 | |
| 
 | |
|  int 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_evp_cb() sets a callback function 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 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 L<EVP_CIPHER_CTX_reset(3)> and L<EVP_MAC_new_ctx(3)>
 | |
| respectively.
 | |
| 
 | |
| For new sessions tickets, when the client doesn't present a session ticket, or
 | |
| an attempted retrieval 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 arbitrary 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 B<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(3)>. The hmac context and digest can be set using
 | |
| L<EVP_MAC_set_ctx_params(3)> with the B<OSSL_MAC_PARAM_KEY> and
 | |
| B<OSSL_MAC_PARAM_DIGEST> parameters respectively.
 | |
| 
 | |
| 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 retrieve 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 retrieved parameters and the initialization vector
 | |
| I<iv>. using a function like L<EVP_DecryptInit_ex(3)>. The key material and
 | |
| digest for I<hctx> need to be set using L<EVP_MAC_set_ctx_params(3)> with the
 | |
| B<OSSL_MAC_PARAM_KEY> and B<OSSL_MAC_PARAM_DIGEST> parameters respectively.
 | |
| 
 | |
| 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 argument 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 negotiating 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
 | |
| 
 | |
| The SSL_CTX_set_tlsext_ticket_key_cb() function is identical to
 | |
| SSL_CTX_set_tlsext_ticket_key_evp_cb() except that it takes a deprecated
 | |
| HMAC_CTX pointer instead of an EVP_MAC_CTX one.
 | |
| Before this callback function is started I<hctx> will have been
 | |
| initialised with L<EVP_MAC_new_ctx(3)> and the digest set with
 | |
| L<EVP_MAC_set_ctx_params(3)>.
 | |
| The I<hctx> key material can be set using L<HMAC_Init_ex(3)>.
 | |
| 
 | |
| =head1 NOTES
 | |
| 
 | |
| Session resumption shortcuts the TLS so that the client certificate
 | |
| negotiation 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 negotiation had occurred.
 | |
| 
 | |
| 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 cipher suite 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 cipher suite 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 RETURN VALUES
 | |
| 
 | |
| returns 0 to indicate the callback function was set.
 | |
| 
 | |
| =head1 EXAMPLES
 | |
| 
 | |
| Reference Implementation:
 | |
| 
 | |
|  SSL_CTX_set_tlsext_ticket_key_evp_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,
 | |
|                                      EVP_MAC_CTX *hctx, int enc)
 | |
|  {
 | |
|      OSSL_PARAM params[3];
 | |
| 
 | |
|      if (enc) { /* create new session */
 | |
|          if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0)
 | |
|              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);
 | |
| 
 | |
|          params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
 | |
|                                                        key->hmac_key, 16);
 | |
|          params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
 | |
|                                                       "sha256", 0);
 | |
|          params[2] = OSSL_PARAM_construct_end();
 | |
|          EVP_MAC_set_ctx_params(hctx, params);
 | |
| 
 | |
|          return 1;
 | |
| 
 | |
|      } else { /* retrieve session */
 | |
|          key = findkey(name);
 | |
| 
 | |
|          if (key == NULL || key->expire < now())
 | |
|              return 0;
 | |
| 
 | |
|          params[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
 | |
|                                                        key->hmac_key, 16);
 | |
|          params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
 | |
|                                                       "sha256", 0);
 | |
|          params[2] = OSSL_PARAM_construct_end();
 | |
|          EVP_MAC_set_ctx_params(hctx, params);
 | |
| 
 | |
|          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;
 | |
|      }
 | |
|  }
 | |
| 
 | |
| =head1 SEE ALSO
 | |
| 
 | |
| L<ssl(7)>, L<SSL_set_session(3)>,
 | |
| 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)>,
 | |
| 
 | |
| =head1 HISTORY
 | |
| 
 | |
| The SSL_CTX_set_tlsext_ticket_key_cb() function was deprecated in OpenSSL 3.0.
 | |
| 
 | |
| The SSL_CTX_set_tlsext_ticket_key_evp_cb() function was introduced in
 | |
| OpenSSL 3.0.
 | |
| 
 | |
| =head1 COPYRIGHT
 | |
| 
 | |
| Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
 | |
| 
 | |
| Licensed under the Apache License 2.0 (the "License").  You may not use
 | |
| 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
 |