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
abdfdb029e
commit
28418076b2
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 char *buffer, result[EVP_MAX_MD_SIZE];
|
||||||
unsigned int length, resultlength;
|
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;
|
struct sockaddr_in peer;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize a random secret */
|
/* Initialize a random secret */
|
||||||
if (!cookie_initialized)
|
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);
|
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
||||||
|
|
||||||
/* Create buffer with peer's address and port */
|
/* 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_addr);
|
||||||
length += sizeof(peer.sin_port);
|
length += sizeof(peer.sin_port);
|
||||||
|
#endif
|
||||||
buffer = OPENSSL_malloc(length);
|
buffer = OPENSSL_malloc(length);
|
||||||
|
|
||||||
if (buffer == NULL)
|
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");
|
BIO_printf(bio_err,"out of memory\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
|
#if OPENSSL_USE_IPV6
|
||||||
memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
|
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 */
|
/* Calculate HMAC of buffer using the secret */
|
||||||
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
|
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 char *buffer, result[EVP_MAX_MD_SIZE];
|
||||||
unsigned int length, resultlength;
|
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;
|
struct sockaddr_in peer;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If secret isn't initialized yet, the cookie can't be valid */
|
/* If secret isn't initialized yet, the cookie can't be valid */
|
||||||
if (!cookie_initialized)
|
if (!cookie_initialized)
|
||||||
return 0;
|
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);
|
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
||||||
|
|
||||||
/* Create buffer with peer's address and port */
|
/* 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_addr);
|
||||||
length += sizeof(peer.sin_port);
|
length += sizeof(peer.sin_port);
|
||||||
|
#endif
|
||||||
buffer = OPENSSL_malloc(length);
|
buffer = OPENSSL_malloc(length);
|
||||||
|
|
||||||
if (buffer == NULL)
|
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");
|
BIO_printf(bio_err,"out of memory\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
|
#if OPENSSL_USE_IPV6
|
||||||
memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
|
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 */
|
/* 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, result, &resultlength);
|
||||||
OPENSSL_free(buffer);
|
OPENSSL_free(buffer);
|
||||||
|
|
||||||
if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
|
if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -108,7 +108,11 @@ static BIO_METHOD methods_dgramp=
|
|||||||
|
|
||||||
typedef struct bio_dgram_data_st
|
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 connected;
|
||||||
unsigned int _errno;
|
unsigned int _errno;
|
||||||
unsigned int mtu;
|
unsigned int mtu;
|
||||||
@ -274,7 +278,11 @@ static int dgram_read(BIO *b, char *out, int outl)
|
|||||||
int ret=0;
|
int ret=0;
|
||||||
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
|
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);
|
int peerlen = sizeof(peer);
|
||||||
|
|
||||||
if (out != NULL)
|
if (out != NULL)
|
||||||
@ -287,7 +295,7 @@ static int dgram_read(BIO *b, char *out, int outl)
|
|||||||
* compiler warnings.
|
* compiler warnings.
|
||||||
*/
|
*/
|
||||||
dgram_adjust_rcv_timeout(b);
|
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);
|
dgram_reset_rcv_timeout(b);
|
||||||
|
|
||||||
if ( ! data->connected && ret >= 0)
|
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;
|
bio_dgram_data *data = (bio_dgram_data *)b->ptr;
|
||||||
clear_socket_error();
|
clear_socket_error();
|
||||||
|
|
||||||
if ( data->connected )
|
if ( data->connected )
|
||||||
ret=writesocket(b->num,in,inl);
|
ret=writesocket(b->num,in,inl);
|
||||||
else
|
else
|
||||||
|
#if OPENSSL_USE_IPV6
|
||||||
|
if (data->peer.ss_family == AF_INET)
|
||||||
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
BIO_clear_retry_flags(b);
|
BIO_clear_retry_flags(b);
|
||||||
@ -405,7 +428,11 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#endif
|
#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
|
#if 0
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -510,27 +537,44 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
if ( to != NULL)
|
if ( to != NULL)
|
||||||
{
|
{
|
||||||
data->connected = 1;
|
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
|
else
|
||||||
{
|
{
|
||||||
data->connected = 0;
|
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;
|
break;
|
||||||
case BIO_CTRL_DGRAM_GET_PEER:
|
case BIO_CTRL_DGRAM_GET_PEER:
|
||||||
to = (struct sockaddr *) ptr;
|
to = (struct sockaddr *) ptr;
|
||||||
|
|
||||||
memcpy(to, &(data->peer), sizeof(struct sockaddr));
|
#if OPENSSL_USE_IPV6
|
||||||
ret = sizeof(struct sockaddr);
|
memcpy(to, &(data->peer), sizeof(struct sockaddr_storage));
|
||||||
break;
|
ret = sizeof(struct sockaddr_storage);
|
||||||
case BIO_CTRL_DGRAM_SET_PEER:
|
#else
|
||||||
to = (struct sockaddr *) ptr;
|
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));
|
#if OPENSSL_USE_IPV6
|
||||||
break;
|
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:
|
case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
|
||||||
memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
|
memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
|
||||||
break;
|
break;
|
||||||
#if defined(SO_RCVTIMEO)
|
#if defined(SO_RCVTIMEO)
|
||||||
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
|
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user