diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2009-09-04 17:53:30 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2009-09-04 17:53:30 +0000 |
commit | 197ab47bdd7e9d5b897091132dd6c05b0a06360a (patch) | |
tree | bef5a81642a3b6d66ffc010d9e2d1b3460970467 /apps | |
parent | e8cce0babef182f70944a74025a8ec4f9a7b2167 (diff) | |
download | openssl-new-197ab47bdd7e9d5b897091132dd6c05b0a06360a.tar.gz |
PR: 2028
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>
Approved by: steve@openssl.org
Fix DTLS cookie management bugs.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/s_apps.h | 3 | ||||
-rw-r--r-- | apps/s_cb.c | 88 | ||||
-rw-r--r-- | apps/s_server.c | 4 |
3 files changed, 95 insertions, 0 deletions
diff --git a/apps/s_apps.h b/apps/s_apps.h index 08fbbc2229..f5a39bae66 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -171,3 +171,6 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, unsigned char *data, int len, void *arg); #endif + +int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len); +int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len); diff --git a/apps/s_cb.c b/apps/s_cb.c index 974ed5d0a5..8c388afd3f 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -117,12 +117,17 @@ #undef NON_MAIN #undef USE_SOCKETS #include <openssl/err.h> +#include <openssl/rand.h> #include <openssl/x509.h> #include <openssl/ssl.h> #include "s_apps.h" +#define COOKIE_SECRET_LENGTH 16 + int verify_depth=0; int verify_error=X509_V_OK; +unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; +int cookie_initialized=0; int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) { @@ -646,3 +651,86 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, BIO_dump(bio, (char *)data, len); (void)BIO_flush(bio); } + +int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) + { + unsigned char *buffer, result[EVP_MAX_MD_SIZE]; + unsigned int length, resultlength; + struct sockaddr_in peer; + + /* Initialize a random secret */ + if (!cookie_initialized) + { + if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH)) + { + BIO_printf(bio_err,"error setting random cookie secret\n"); + return 0; + } + cookie_initialized = 1; + } + + /* Read peer information */ + (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + + /* Create buffer with peer's address and port */ + length = sizeof(peer.sin_addr); + length += sizeof(peer.sin_port); + buffer = OPENSSL_malloc(length); + + if (buffer == NULL) + { + BIO_printf(bio_err,"out of memory\n"); + return 0; + } + + memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); + memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); + + /* Calculate HMAC of buffer using the secret */ + HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, + buffer, length, result, &resultlength); + OPENSSL_free(buffer); + + memcpy(cookie, result, resultlength); + *cookie_len = resultlength; + + return 1; + } + +int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) + { + unsigned char *buffer, result[EVP_MAX_MD_SIZE]; + unsigned int length, resultlength; + struct sockaddr_in peer; + + /* If secret isn't initialized yet, the cookie can't be valid */ + if (!cookie_initialized) + return 0; + + /* Read peer information */ + (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + + /* Create buffer with peer's address and port */ + length = sizeof(peer.sin_addr); + length += sizeof(peer.sin_port); + buffer = (unsigned char*) OPENSSL_malloc(length); + + if (buffer == NULL) + { + BIO_printf(bio_err,"out of memory\n"); + return 0; + } + + memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); + memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); + + /* Calculate HMAC of buffer using the secret */ + HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, + buffer, length, result, &resultlength); + OPENSSL_free(buffer); + + if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) + return 1; + + return 0; + } diff --git a/apps/s_server.c b/apps/s_server.c index 5c5168aad4..cedd64c43c 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1497,6 +1497,10 @@ bad: SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, sizeof s_server_session_id_context); + /* Set DTLS cookie generation and verification callbacks */ + SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); + SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); + #ifndef OPENSSL_NO_TLSEXT if (ctx2) { |