Refactor DTLS cookie generation and verification

DTLS cookie generation and verification were exact copies of each
other save the last few lines.  This refactors them to avoid code
copying.

Reviewed-by: Matt Caswell <matt@openssl.org>
This commit is contained in:
Richard Levitte 2015-12-23 11:40:43 +01:00
parent 7ab09630cd
commit 87a595e554

View File

@ -736,8 +736,8 @@ void tlsext_cb(SSL *s, int client_server, int type,
int generate_cookie_callback(SSL *ssl, unsigned char *cookie, int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
unsigned int *cookie_len) unsigned int *cookie_len)
{ {
unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned char *buffer;
unsigned int length, resultlength; unsigned int length;
union { union {
struct sockaddr sa; struct sockaddr sa;
struct sockaddr_in s4; struct sockaddr_in s4;
@ -797,78 +797,23 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
/* Calculate HMAC of buffer using the secret */ /* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
buffer, length, result, &resultlength); buffer, length, cookie, cookie_len);
OPENSSL_free(buffer); OPENSSL_free(buffer);
memcpy(cookie, result, resultlength);
*cookie_len = resultlength;
return 1; return 1;
} }
int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
unsigned int cookie_len) unsigned int cookie_len)
{ {
unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned char result[EVP_MAX_MD_SIZE];
unsigned int length, resultlength; unsigned int resultlength;
union {
struct sockaddr sa;
struct sockaddr_in s4;
#if OPENSSL_USE_IPV6
struct sockaddr_in6 s6;
#endif
} peer;
/* If secret isn't initialized yet, the cookie can't be valid */ /* Note: we check cookie_initialized because if it's not,
if (!cookie_initialized) * it cannot be valid */
return 0; if (cookie_initialized
&& generate_cookie_callback(ssl, result, &resultlength)
/* Read peer information */ && cookie_len == resultlength
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */
length = 0;
switch (peer.sa.sa_family) {
case AF_INET:
length += sizeof(struct in_addr);
length += sizeof(peer.s4.sin_port);
break;
#if OPENSSL_USE_IPV6
case AF_INET6:
length += sizeof(struct in6_addr);
length += sizeof(peer.s6.sin6_port);
break;
#endif
default:
OPENSSL_assert(0);
break;
}
buffer = app_malloc(length, "cookie verify buffer");
switch (peer.sa.sa_family) {
case AF_INET:
memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
memcpy(buffer + sizeof(peer.s4.sin_port),
&peer.s4.sin_addr, sizeof(struct in_addr));
break;
#if OPENSSL_USE_IPV6
case AF_INET6:
memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
memcpy(buffer + sizeof(peer.s6.sin6_port),
&peer.s6.sin6_addr, sizeof(struct in6_addr));
break;
#endif
default:
OPENSSL_assert(0);
break;
}
/* 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) && memcmp(result, cookie, resultlength) == 0)
return 1; return 1;