| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | =pod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 NAME | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 04:00:06 +08:00
										 |  |  | SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, | 
					
						
							|  |  |  | SSL_has_matching_session_id, GEN_SESSION_CB | 
					
						
							|  |  |  | - manipulate generation of SSL session IDs (server only) | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 SYNOPSIS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  #include <openssl/ssl.h> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 10:49:48 +08:00
										 |  |  |  typedef int (*GEN_SESSION_CB)(SSL *ssl, unsigned char *id, | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  |                                unsigned int *id_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb); | 
					
						
							|  |  |  |  int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB, cb); | 
					
						
							|  |  |  |  int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, | 
					
						
							| 
									
										
										
										
											2016-05-20 20:11:46 +08:00
										 |  |  |                                  unsigned int id_len); | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 DESCRIPTION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SSL_CTX_set_generate_session_id() sets the callback function for generating | 
					
						
							|  |  |  | new session ids for SSL/TLS sessions for B<ctx> to be B<cb>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SSL_set_generate_session_id() sets the callback function for generating | 
					
						
							|  |  |  | new session ids for SSL/TLS sessions for B<ssl> to be B<cb>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SSL_has_matching_session_id() checks, whether a session with id B<id> | 
					
						
							|  |  |  | (of length B<id_len>) is already contained in the internal session cache | 
					
						
							|  |  |  | of the parent context of B<ssl>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 NOTES | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When a new session is established between client and server, the server | 
					
						
							|  |  |  | generates a session id. The session id is an arbitrary sequence of bytes. | 
					
						
							| 
									
										
										
										
											2014-11-30 22:35:22 +08:00
										 |  |  | The length of the session id is between 1 and 32 bytes.  The session id is not | 
					
						
							|  |  |  | security critical but must be unique for the server. Additionally, the session id is | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | transmitted in the clear when reusing the session so it must not contain | 
					
						
							|  |  |  | sensitive information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Without a callback being set, an OpenSSL server will generate a unique | 
					
						
							|  |  |  | session id from pseudo random numbers of the maximum possible length. | 
					
						
							|  |  |  | Using the callback function, the session id can be changed to contain | 
					
						
							|  |  |  | additional information like e.g. a host id in order to improve load balancing | 
					
						
							|  |  |  | or external caching techniques. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The callback function receives a pointer to the memory location to put | 
					
						
							|  |  |  | B<id> into and a pointer to the maximum allowed length B<id_len>. The | 
					
						
							|  |  |  | buffer at location B<id> is only guaranteed to have the size B<id_len>. | 
					
						
							|  |  |  | The callback is only allowed to generate a shorter id and reduce B<id_len>; | 
					
						
							|  |  |  | the callback B<must never> increase B<id_len> or write to the location | 
					
						
							|  |  |  | B<id> exceeding the given limit. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The location B<id> is filled with 0x00 before the callback is called, so the | 
					
						
							|  |  |  | callback may only fill part of the possible length and leave B<id_len> | 
					
						
							|  |  |  | untouched while maintaining reproducibility. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Since the sessions must be distinguished, session ids must be unique. | 
					
						
							|  |  |  | Without the callback a random number is used, so that the probability | 
					
						
							| 
									
										
										
										
											2014-11-30 22:35:22 +08:00
										 |  |  | of generating the same session id is extremely small (2^256 for SSLv3/TLSv1). | 
					
						
							|  |  |  | In order to assure the uniqueness of the generated session id, the callback must call | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | SSL_has_matching_session_id() and generate another id if a conflict occurs. | 
					
						
							|  |  |  | If an id conflict is not resolved, the handshake will fail. | 
					
						
							|  |  |  | If the application codes e.g. a unique host id, a unique process number, and | 
					
						
							|  |  |  | a unique sequence number into the session id, uniqueness could easily be | 
					
						
							|  |  |  | achieved without randomness added (it should however be taken care that | 
					
						
							|  |  |  | no confidential information is leaked this way). If the application can not | 
					
						
							|  |  |  | guarantee uniqueness, it is recommended to use the maximum B<id_len> and | 
					
						
							|  |  |  | fill in the bytes not used to code special information with random data | 
					
						
							|  |  |  | to avoid collisions. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SSL_has_matching_session_id() will only query the internal session cache, | 
					
						
							|  |  |  | not the external one. Since the session id is generated before the | 
					
						
							|  |  |  | handshake is completed, it is not immediately added to the cache. If | 
					
						
							|  |  |  | another thread is using the same internal session cache, a race condition | 
					
						
							|  |  |  | can occur in that another thread generates the same session id. | 
					
						
							|  |  |  | Collisions can also occur when using an external session cache, since | 
					
						
							|  |  |  | the external cache is not tested with SSL_has_matching_session_id() | 
					
						
							|  |  |  | and the same race condition applies. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The callback must return 0 if it cannot generate a session id for whatever | 
					
						
							|  |  |  | reason and return 1 on success. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-26 13:11:10 +08:00
										 |  |  | =head1 RETURN VALUES | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SSL_CTX_set_generate_session_id() and SSL_set_generate_session_id() | 
					
						
							| 
									
										
										
										
											2022-12-02 15:43:01 +08:00
										 |  |  | return 1 on success and 0 for failure. | 
					
						
							| 
									
										
										
										
											2019-02-26 13:11:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | SSL_has_matching_session_id() returns 1 if another session with the | 
					
						
							| 
									
										
										
										
											2022-12-02 15:43:01 +08:00
										 |  |  | same id is already in the cache, or 0 otherwise. | 
					
						
							| 
									
										
										
										
											2019-02-26 13:11:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | =head1 EXAMPLES | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The callback function listed will generate a session id with the | 
					
						
							|  |  |  | server id given, and will fill the rest with pseudo random bytes: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  const char session_id_prefix = "www-18"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  #define MAX_SESSION_ID_ATTEMPTS 10 | 
					
						
							| 
									
										
										
										
											2019-06-07 10:49:48 +08:00
										 |  |  |  static int generate_session_id(SSL *ssl, unsigned char *id, | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |                                 unsigned int *id_len) | 
					
						
							| 
									
										
										
										
											2016-06-29 06:19:46 +08:00
										 |  |  |  { | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |      unsigned int count = 0; | 
					
						
							| 
									
										
										
										
											2017-01-21 02:58:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |      do { | 
					
						
							|  |  |  |          RAND_pseudo_bytes(id, *id_len); | 
					
						
							|  |  |  |          /* | 
					
						
							|  |  |  |           * Prefix the session_id with the required prefix. NB: If our | 
					
						
							|  |  |  |           * prefix is too long, clip it - but there will be worse effects | 
					
						
							| 
									
										
										
										
											2020-06-30 03:13:07 +08:00
										 |  |  |           * anyway, e.g. the server could only possibly create 1 session | 
					
						
							|  |  |  |           * ID (i.e. the prefix!) so all future session negotiations will | 
					
						
							| 
									
										
										
										
											2016-11-19 07:10:05 +08:00
										 |  |  |           * fail due to conflicts. | 
					
						
							|  |  |  |           */ | 
					
						
							|  |  |  |          memcpy(id, session_id_prefix, strlen(session_id_prefix) < *id_len ? | 
					
						
							|  |  |  |                                        strlen(session_id_prefix) : *id_len); | 
					
						
							|  |  |  |      } while (SSL_has_matching_session_id(ssl, id, *id_len) | 
					
						
							|  |  |  |                && ++count < MAX_SESSION_ID_ATTEMPTS); | 
					
						
							|  |  |  |      if (count >= MAX_SESSION_ID_ATTEMPTS) | 
					
						
							|  |  |  |          return 0; | 
					
						
							|  |  |  |      return 1; | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 SEE ALSO | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 16:33:09 +08:00
										 |  |  | L<ssl(7)>, L<SSL_get_version(3)> | 
					
						
							| 
									
										
										
										
											2001-02-24 05:38:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 23:44:05 +08:00
										 |  |  | =head1 COPYRIGHT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 20:47:04 +08:00
										 |  |  | Copyright 2001-2020 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 |