Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 1 | =pod |
| 2 | |
| 3 | =head1 NAME |
| 4 | |
Rich Salz | 121677b | 2016-12-27 15:00:06 -0500 | [diff] [blame] | 5 | SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, |
| 6 | SSL_has_matching_session_id, GEN_SESSION_CB |
| 7 | - manipulate generation of SSL session IDs (server only) |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 8 | |
| 9 | =head1 SYNOPSIS |
| 10 | |
| 11 | #include <openssl/ssl.h> |
| 12 | |
| 13 | typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id, |
| 14 | unsigned int *id_len); |
| 15 | |
| 16 | int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb); |
| 17 | int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB, cb); |
| 18 | int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, |
Rich Salz | 1bc7451 | 2016-05-20 08:11:46 -0400 | [diff] [blame] | 19 | unsigned int id_len); |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 20 | |
| 21 | =head1 DESCRIPTION |
| 22 | |
| 23 | SSL_CTX_set_generate_session_id() sets the callback function for generating |
| 24 | new session ids for SSL/TLS sessions for B<ctx> to be B<cb>. |
| 25 | |
| 26 | SSL_set_generate_session_id() sets the callback function for generating |
| 27 | new session ids for SSL/TLS sessions for B<ssl> to be B<cb>. |
| 28 | |
| 29 | SSL_has_matching_session_id() checks, whether a session with id B<id> |
| 30 | (of length B<id_len>) is already contained in the internal session cache |
| 31 | of the parent context of B<ssl>. |
| 32 | |
| 33 | =head1 NOTES |
| 34 | |
| 35 | When a new session is established between client and server, the server |
| 36 | generates a session id. The session id is an arbitrary sequence of bytes. |
Kurt Roeckx | 45f55f6 | 2014-11-30 15:35:22 +0100 | [diff] [blame] | 37 | The length of the session id is between 1 and 32 bytes. The session id is not |
| 38 | security critical but must be unique for the server. Additionally, the session id is |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 39 | transmitted in the clear when reusing the session so it must not contain |
| 40 | sensitive information. |
| 41 | |
| 42 | Without a callback being set, an OpenSSL server will generate a unique |
| 43 | session id from pseudo random numbers of the maximum possible length. |
| 44 | Using the callback function, the session id can be changed to contain |
| 45 | additional information like e.g. a host id in order to improve load balancing |
| 46 | or external caching techniques. |
| 47 | |
| 48 | The callback function receives a pointer to the memory location to put |
| 49 | B<id> into and a pointer to the maximum allowed length B<id_len>. The |
| 50 | buffer at location B<id> is only guaranteed to have the size B<id_len>. |
| 51 | The callback is only allowed to generate a shorter id and reduce B<id_len>; |
| 52 | the callback B<must never> increase B<id_len> or write to the location |
| 53 | B<id> exceeding the given limit. |
| 54 | |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 55 | The location B<id> is filled with 0x00 before the callback is called, so the |
| 56 | callback may only fill part of the possible length and leave B<id_len> |
| 57 | untouched while maintaining reproducibility. |
| 58 | |
| 59 | Since the sessions must be distinguished, session ids must be unique. |
| 60 | Without the callback a random number is used, so that the probability |
Kurt Roeckx | 45f55f6 | 2014-11-30 15:35:22 +0100 | [diff] [blame] | 61 | of generating the same session id is extremely small (2^256 for SSLv3/TLSv1). |
| 62 | In order to assure the uniqueness of the generated session id, the callback must call |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 63 | SSL_has_matching_session_id() and generate another id if a conflict occurs. |
| 64 | If an id conflict is not resolved, the handshake will fail. |
| 65 | If the application codes e.g. a unique host id, a unique process number, and |
| 66 | a unique sequence number into the session id, uniqueness could easily be |
| 67 | achieved without randomness added (it should however be taken care that |
| 68 | no confidential information is leaked this way). If the application can not |
| 69 | guarantee uniqueness, it is recommended to use the maximum B<id_len> and |
| 70 | fill in the bytes not used to code special information with random data |
| 71 | to avoid collisions. |
| 72 | |
| 73 | SSL_has_matching_session_id() will only query the internal session cache, |
| 74 | not the external one. Since the session id is generated before the |
| 75 | handshake is completed, it is not immediately added to the cache. If |
| 76 | another thread is using the same internal session cache, a race condition |
| 77 | can occur in that another thread generates the same session id. |
| 78 | Collisions can also occur when using an external session cache, since |
| 79 | the external cache is not tested with SSL_has_matching_session_id() |
| 80 | and the same race condition applies. |
| 81 | |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 82 | The callback must return 0 if it cannot generate a session id for whatever |
| 83 | reason and return 1 on success. |
| 84 | |
| 85 | =head1 EXAMPLES |
| 86 | |
| 87 | The callback function listed will generate a session id with the |
| 88 | server id given, and will fill the rest with pseudo random bytes: |
| 89 | |
| 90 | const char session_id_prefix = "www-18"; |
| 91 | |
| 92 | #define MAX_SESSION_ID_ATTEMPTS 10 |
| 93 | static int generate_session_id(const SSL *ssl, unsigned char *id, |
Beat Bolli | 2947af3 | 2016-11-19 00:10:05 +0100 | [diff] [blame] | 94 | unsigned int *id_len) |
FdaSilvaYY | 2f8e53d | 2016-06-29 00:19:46 +0200 | [diff] [blame] | 95 | { |
Beat Bolli | 2947af3 | 2016-11-19 00:10:05 +0100 | [diff] [blame] | 96 | unsigned int count = 0; |
Beat Bolli | e9b7724 | 2017-01-20 19:58:49 +0100 | [diff] [blame] | 97 | |
Beat Bolli | 2947af3 | 2016-11-19 00:10:05 +0100 | [diff] [blame] | 98 | do { |
| 99 | RAND_pseudo_bytes(id, *id_len); |
| 100 | /* |
| 101 | * Prefix the session_id with the required prefix. NB: If our |
| 102 | * prefix is too long, clip it - but there will be worse effects |
| 103 | * anyway, eg. the server could only possibly create 1 session |
| 104 | * ID (ie. the prefix!) so all future session negotiations will |
| 105 | * fail due to conflicts. |
| 106 | */ |
| 107 | memcpy(id, session_id_prefix, strlen(session_id_prefix) < *id_len ? |
| 108 | strlen(session_id_prefix) : *id_len); |
| 109 | } while (SSL_has_matching_session_id(ssl, id, *id_len) |
| 110 | && ++count < MAX_SESSION_ID_ATTEMPTS); |
| 111 | if (count >= MAX_SESSION_ID_ATTEMPTS) |
| 112 | return 0; |
| 113 | return 1; |
| 114 | } |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 115 | |
| 116 | |
| 117 | =head1 RETURN VALUES |
| 118 | |
| 119 | SSL_CTX_set_generate_session_id() and SSL_set_generate_session_id() |
| 120 | always return 1. |
| 121 | |
| 122 | SSL_has_matching_session_id() returns 1 if another session with the |
| 123 | same id is already in the cache. |
| 124 | |
| 125 | =head1 SEE ALSO |
| 126 | |
Richard Levitte | b97fdb5 | 2016-11-11 09:33:09 +0100 | [diff] [blame] | 127 | L<ssl(7)>, L<SSL_get_version(3)> |
Lutz Jänicke | 3cdc8ad | 2001-02-23 21:38:42 +0000 | [diff] [blame] | 128 | |
Rich Salz | e2f9261 | 2016-05-18 11:44:05 -0400 | [diff] [blame] | 129 | =head1 COPYRIGHT |
| 130 | |
| 131 | Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. |
| 132 | |
| 133 | Licensed under the OpenSSL license (the "License"). You may not use |
| 134 | this file except in compliance with the License. You can obtain a copy |
| 135 | in the file LICENSE in the source distribution or at |
| 136 | L<https://www.openssl.org/source/license.html>. |
| 137 | |
| 138 | =cut |