PR: 2069
Submitted by: Michael Tuexen <tuexen@fh-muenster.de> Approved by: steve@openssl.org IPv6 support for DTLS.
This commit is contained in:
parent
2c55c0d367
commit
636b6b450d
118
apps/s_cb.c
118
apps/s_cb.c
@ -692,8 +692,16 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
|
||||
{
|
||||
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
|
||||
unsigned int length, resultlength;
|
||||
#if OPENSSL_USE_IPV6
|
||||
union {
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr_in6 s6;
|
||||
struct sockaddr_in s4;
|
||||
} peer;
|
||||
#else
|
||||
struct sockaddr_in peer;
|
||||
|
||||
#endif
|
||||
|
||||
/* Initialize a random secret */
|
||||
if (!cookie_initialized)
|
||||
{
|
||||
@ -709,8 +717,25 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
|
||||
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
||||
|
||||
/* Create buffer with peer's address and port */
|
||||
#if OPENSSL_USE_IPV6
|
||||
length = 0;
|
||||
switch (peer.ss.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
length += sizeof(struct in_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
length += sizeof(struct in6_addr);
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
length += sizeof(in_port_t);
|
||||
#else
|
||||
length = sizeof(peer.sin_addr);
|
||||
length += sizeof(peer.sin_port);
|
||||
#endif
|
||||
buffer = OPENSSL_malloc(length);
|
||||
|
||||
if (buffer == NULL)
|
||||
@ -718,9 +743,34 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
|
||||
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));
|
||||
|
||||
#if OPENSSL_USE_IPV6
|
||||
switch (peer.ss.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(buffer,
|
||||
&peer.s4.sin_port,
|
||||
sizeof(in_port_t));
|
||||
memcpy(buffer + sizeof(in_port_t),
|
||||
&peer.s4.sin_addr,
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(buffer,
|
||||
&peer.s6.sin6_port,
|
||||
sizeof(in_port_t));
|
||||
memcpy(buffer + sizeof(in_port_t),
|
||||
&peer.s6.sin6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
memcpy(buffer, &peer.sin_port, sizeof(peer.sin_port));
|
||||
memcpy(buffer + sizeof(peer.sin_port), &peer.sin_addr, sizeof(peer.sin_addr));
|
||||
#endif
|
||||
|
||||
/* Calculate HMAC of buffer using the secret */
|
||||
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
|
||||
@ -737,8 +787,16 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
|
||||
{
|
||||
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
|
||||
unsigned int length, resultlength;
|
||||
#if OPENSSL_USE_IPV6
|
||||
union {
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr_in6 s6;
|
||||
struct sockaddr_in s4;
|
||||
} peer;
|
||||
#else
|
||||
struct sockaddr_in peer;
|
||||
|
||||
#endif
|
||||
|
||||
/* If secret isn't initialized yet, the cookie can't be valid */
|
||||
if (!cookie_initialized)
|
||||
return 0;
|
||||
@ -747,8 +805,25 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
|
||||
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
||||
|
||||
/* Create buffer with peer's address and port */
|
||||
#if OPENSSL_USE_IPV6
|
||||
length = 0;
|
||||
switch (peer.ss.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
length += sizeof(struct in_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
length += sizeof(struct in6_addr);
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
length += sizeof(in_port_t);
|
||||
#else
|
||||
length = sizeof(peer.sin_addr);
|
||||
length += sizeof(peer.sin_port);
|
||||
#endif
|
||||
buffer = OPENSSL_malloc(length);
|
||||
|
||||
if (buffer == NULL)
|
||||
@ -756,15 +831,40 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
|
||||
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));
|
||||
|
||||
#if OPENSSL_USE_IPV6
|
||||
switch (peer.ss.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(buffer,
|
||||
&peer.s4.sin_port,
|
||||
sizeof(in_port_t));
|
||||
memcpy(buffer + sizeof(in_port_t),
|
||||
&peer.s4.sin_addr,
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(buffer,
|
||||
&peer.s6.sin6_port,
|
||||
sizeof(in_port_t));
|
||||
memcpy(buffer + sizeof(in_port_t),
|
||||
&peer.s6.sin6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
memcpy(buffer, &peer.sin_port, sizeof(peer.sin_port));
|
||||
memcpy(buffer + sizeof(peer.sin_port), &peer.sin_addr, sizeof(peer.sin_addr));
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
|
||||
|
@ -108,7 +108,11 @@ static BIO_METHOD methods_dgramp=
|
||||
|
||||
typedef struct bio_dgram_data_st
|
||||
{
|
||||
struct sockaddr peer;
|
||||
#if OPENSSL_USE_IPV6
|
||||
struct sockaddr_storage peer;
|
||||
#else
|
||||
struct sockaddr_in peer;
|
||||
#endif
|
||||
unsigned int connected;
|
||||
unsigned int _errno;
|
||||
unsigned int mtu;
|
||||
@ -274,7 +278,11 @@ static int dgram_read(BIO *b, char *out, int outl)
|
||||
int ret=0;
|
||||
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
|
||||
|
||||
struct sockaddr peer;
|
||||
#if OPENSSL_USE_IPV6
|
||||
struct sockaddr_storage peer;
|
||||
#else
|
||||
struct sockaddr_in peer;
|
||||
#endif
|
||||
int peerlen = sizeof(peer);
|
||||
|
||||
if (out != NULL)
|
||||
@ -287,7 +295,7 @@ static int dgram_read(BIO *b, char *out, int outl)
|
||||
* compiler warnings.
|
||||
*/
|
||||
dgram_adjust_rcv_timeout(b);
|
||||
ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen);
|
||||
ret=recvfrom(b->num,out,outl,0,(struct sockaddr *)&peer,(void *)&peerlen);
|
||||
dgram_reset_rcv_timeout(b);
|
||||
|
||||
if ( ! data->connected && ret >= 0)
|
||||
@ -312,13 +320,28 @@ static int dgram_write(BIO *b, const char *in, int inl)
|
||||
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
|
||||
clear_socket_error();
|
||||
|
||||
if ( data->connected )
|
||||
ret=writesocket(b->num,in,inl);
|
||||
else
|
||||
if ( data->connected )
|
||||
ret=writesocket(b->num,in,inl);
|
||||
else
|
||||
#if OPENSSL_USE_IPV6
|
||||
if (data->peer.ss_family == AF_INET)
|
||||
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
|
||||
ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer));
|
||||
ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
|
||||
#else
|
||||
ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer));
|
||||
ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
else
|
||||
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
|
||||
ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in6));
|
||||
#else
|
||||
ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in6));
|
||||
#endif
|
||||
#else
|
||||
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
|
||||
ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
|
||||
#else
|
||||
ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
@ -405,7 +428,11 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
else
|
||||
{
|
||||
#endif
|
||||
memcpy(&(data->peer),to, sizeof(struct sockaddr));
|
||||
#if OPENSSL_USE_IPV6
|
||||
memcpy(&(data->peer),to, sizeof(struct sockaddr_storage));
|
||||
#else
|
||||
memcpy(&(data->peer),to, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
@ -510,27 +537,44 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
if ( to != NULL)
|
||||
{
|
||||
data->connected = 1;
|
||||
memcpy(&(data->peer),to, sizeof(struct sockaddr));
|
||||
#if OPENSSL_USE_IPV6
|
||||
memcpy(&(data->peer),to, sizeof(struct sockaddr_storage));
|
||||
#else
|
||||
memcpy(&(data->peer),to, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
data->connected = 0;
|
||||
memset(&(data->peer), 0x00, sizeof(struct sockaddr));
|
||||
#if OPENSSL_USE_IPV6
|
||||
memset(&(data->peer), 0x00, sizeof(struct sockaddr_storage));
|
||||
#else
|
||||
memset(&(data->peer), 0x00, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case BIO_CTRL_DGRAM_GET_PEER:
|
||||
to = (struct sockaddr *) ptr;
|
||||
case BIO_CTRL_DGRAM_GET_PEER:
|
||||
to = (struct sockaddr *) ptr;
|
||||
|
||||
memcpy(to, &(data->peer), sizeof(struct sockaddr));
|
||||
ret = sizeof(struct sockaddr);
|
||||
break;
|
||||
case BIO_CTRL_DGRAM_SET_PEER:
|
||||
to = (struct sockaddr *) ptr;
|
||||
#if OPENSSL_USE_IPV6
|
||||
memcpy(to, &(data->peer), sizeof(struct sockaddr_storage));
|
||||
ret = sizeof(struct sockaddr_storage);
|
||||
#else
|
||||
memcpy(to, &(data->peer), sizeof(struct sockaddr_in));
|
||||
ret = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
break;
|
||||
case BIO_CTRL_DGRAM_SET_PEER:
|
||||
to = (struct sockaddr *) ptr;
|
||||
|
||||
memcpy(&(data->peer), to, sizeof(struct sockaddr));
|
||||
break;
|
||||
#if OPENSSL_USE_IPV6
|
||||
memcpy(&(data->peer), to, sizeof(struct sockaddr_storage));
|
||||
#else
|
||||
memcpy(&(data->peer), to, sizeof(struct sockaddr_in));
|
||||
#endif
|
||||
break;
|
||||
case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
|
||||
memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
|
||||
memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
|
||||
break;
|
||||
#if defined(SO_RCVTIMEO)
|
||||
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
|
||||
|
Loading…
x
Reference in New Issue
Block a user