You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
6.2 KiB
150 lines
6.2 KiB
=pod |
|
|
|
=head1 NAME |
|
|
|
SSL_CTX_set_generate_session_id, SSL_set_generate_session_id, SSL_has_matching_session_id - manipulate generation of SSL session IDs (server only) |
|
|
|
=head1 SYNOPSIS |
|
|
|
#include <openssl/ssl.h> |
|
|
|
typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id, |
|
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, |
|
unsigned int id_len); |
|
|
|
=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. |
|
The length of the session id is 16 bytes for SSLv2 sessions and between |
|
1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical |
|
but must be unique for the server. Additionally, the session id is |
|
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. |
|
|
|
If a SSLv2 session id is generated and B<id_len> is reduced, it will be |
|
restored after the callback has finished and the session id will be padded |
|
with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions. |
|
The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function |
|
to check, whether the session is of type SSLv2. |
|
|
|
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 |
|
of generating the same session id is extremely small (2^128 possible ids |
|
for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the |
|
uniqueness of the generated session id, the callback must call |
|
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. |
|
|
|
When calling SSL_has_matching_session_id() for an SSLv2 session with |
|
reduced B<id_len>, the match operation will be performed using the |
|
fixed length required and with a 0x00 padded id. |
|
|
|
The callback must return 0 if it cannot generate a session id for whatever |
|
reason and return 1 on success. |
|
|
|
=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 |
|
static int generate_session_id(const SSL *ssl, unsigned char *id, |
|
unsigned int *id_len) |
|
{ |
|
unsigned int count = 0; |
|
const char *version; |
|
|
|
version = SSL_get_version(ssl); |
|
if (!strcmp(version, "SSLv2")) |
|
/* we must not change id_len */; |
|
|
|
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 |
|
* anyway, eg. the server could only possibly create 1 session |
|
* ID (ie. the prefix!) so all future session negotiations will |
|
* 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; |
|
} |
|
|
|
|
|
=head1 RETURN VALUES |
|
|
|
SSL_CTX_set_generate_session_id() and SSL_set_generate_session_id() |
|
always return 1. |
|
|
|
SSL_has_matching_session_id() returns 1 if another session with the |
|
same id is already in the cache. |
|
|
|
=head1 SEE ALSO |
|
|
|
L<ssl(3)|ssl(3)>, L<SSL_get_version(3)|SSL_get_version(3)> |
|
|
|
=head1 HISTORY |
|
|
|
SSL_CTX_set_generate_session_id(), SSL_set_generate_session_id() |
|
and SSL_has_matching_session_id() have been introduced in |
|
OpenSSL 0.9.7. |
|
|
|
=cut
|
|
|