DTLSv1.2, fixed DTLS socket timeout

pull/1/head
John Safranek 2013-03-06 23:02:33 -08:00
parent 49e67487e7
commit 591e1fc772
6 changed files with 77 additions and 27 deletions

View File

@ -452,6 +452,7 @@ enum Misc {
DTLS_MAJOR = 0xfe, /* DTLS major version number */
DTLS_MINOR = 0xff, /* DTLS minor version number */
DTLSv1_2_MINOR = 0xfd, /* DTLS minor version number */
SSLv3_MAJOR = 3, /* SSLv3 and TLSv1+ major version number */
SSLv3_MINOR = 0, /* TLSv1 minor version number */
TLSv1_MINOR = 1, /* TLSv1 minor version number */
@ -655,6 +656,7 @@ CYASSL_LOCAL ProtocolVersion MakeTLSv1_2(void);
#ifdef CYASSL_DTLS
CYASSL_LOCAL ProtocolVersion MakeDTLSv1(void);
CYASSL_LOCAL ProtocolVersion MakeDTLSv1_2(void);
#endif

View File

@ -92,6 +92,8 @@ typedef CYASSL_X509_STORE_CTX X509_STORE_CTX;
#ifdef CYASSL_DTLS
#define DTLSv1_client_method CyaDTLSv1_client_method
#define DTLSv1_server_method CyaDTLSv1_server_method
#define DTLSv1_2_client_method CyaDTLSv1_2_client_method
#define DTLSv1_2_server_method CyaDTLSv1_2_server_method
#endif

View File

@ -149,6 +149,8 @@ CYASSL_API CYASSL_METHOD *CyaTLSv1_2_client_method(void);
#ifdef CYASSL_DTLS
CYASSL_API CYASSL_METHOD *CyaDTLSv1_client_method(void);
CYASSL_API CYASSL_METHOD *CyaDTLSv1_server_method(void);
CYASSL_API CYASSL_METHOD *CyaDTLSv1_2_client_method(void);
CYASSL_API CYASSL_METHOD *CyaDTLSv1_2_server_method(void);
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)

View File

@ -123,6 +123,8 @@ int IsAtLeastTLSv1_2(const CYASSL* ssl)
{
if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
return 1;
if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
return 1;
return 0;
}
@ -357,7 +359,7 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
ctx->CBIOSend = EmbedSend;
#ifdef CYASSL_DTLS
if (method->version.major == DTLS_MAJOR
&& method->version.minor == DTLS_MINOR) {
&& method->version.minor >= DTLSv1_2_MINOR) {
ctx->CBIORecv = EmbedReceiveFrom;
ctx->CBIOSend = EmbedSendTo;
}
@ -591,8 +593,10 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
}
#ifdef CYASSL_DTLS
if (pv.major == DTLS_MAJOR && pv.minor == DTLS_MINOR)
tls = 1;
if (pv.major == DTLS_MAJOR) {
tls = 1;
tls1_2 = pv.minor <= DTLSv1_2_MINOR;
}
#endif
#ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
@ -1299,7 +1303,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->heap = ctx->heap; /* defaults to self */
ssl->options.tls = 0;
ssl->options.tls1_1 = 0;
if (ssl->version.major == DTLS_MAJOR && ssl->version.minor == DTLS_MINOR)
if (ssl->version.major == DTLS_MAJOR
&& ssl->version.minor >= DTLSv1_2_MINOR)
ssl->options.dtls = 1;
else
ssl->options.dtls = 0;
@ -1951,6 +1956,15 @@ ProtocolVersion MakeDTLSv1(void)
return pv;
}
ProtocolVersion MakeDTLSv1_2(void)
{
ProtocolVersion pv;
pv.major = DTLS_MAJOR;
pv.minor = DTLSv1_2_MINOR;
return pv;
}
#endif /* CYASSL_DTLS */

View File

@ -136,16 +136,6 @@
#endif
#ifdef CYASSL_DTLS
/* sizeof(struct timeval) will pass uninit bytes to setsockopt if padded */
#ifdef USE_WINDOWS_API
#define TIMEVAL_BYTES sizeof(timeout)
#else
#define TIMEVAL_BYTES sizeof(timeout.tv_sec) + sizeof(timeout.tv_usec)
#endif
#endif
/* Translates return codes returned from
* send() and recv() if need be.
*/
@ -201,7 +191,7 @@ int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx)
struct timeval timeout = {dtls_timeout, 0};
#endif
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
TIMEVAL_BYTES) != 0) {
sizeof(timeout)) != 0) {
CYASSL_MSG("setsockopt rcvtimeo failed");
}
}
@ -329,7 +319,7 @@ int EmbedReceiveFrom(CYASSL *ssl, char *buf, int sz, void *ctx)
struct timeval timeout = { dtls_timeout, 0 };
#endif
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
TIMEVAL_BYTES) != 0) {
sizeof(timeout)) != 0) {
CYASSL_MSG("setsockopt rcvtimeo failed");
}
}

View File

@ -2562,6 +2562,17 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
InitSSL_Method(method, MakeDTLSv1());
return method;
}
CYASSL_METHOD* CyaDTLSv1_2_client_method(void)
{
CYASSL_METHOD* method =
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
DYNAMIC_TYPE_METHOD);
CYASSL_ENTER("DTLSv1_2_client_method");
if (method)
InitSSL_Method(method, MakeDTLSv1_2());
return method;
}
#endif
@ -2583,7 +2594,7 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
#ifdef CYASSL_DTLS
if (ssl->version.major == DTLS_MAJOR &&
ssl->version.minor == DTLS_MINOR) {
ssl->version.minor >= DTLSv1_2_MINOR) {
ssl->options.dtls = 1;
ssl->options.tls = 1;
ssl->options.tls1_1 = 1;
@ -2656,10 +2667,14 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
/* re-init hashes, exclude first hello and verify request */
InitMd5(&ssl->hashMd5);
InitSha(&ssl->hashSha);
#ifndef NO_SHA256
if (IsAtLeastTLSv1_2(ssl))
if (IsAtLeastTLSv1_2(ssl)) {
#ifndef NO_SHA256
InitSha256(&ssl->hashSha256);
#endif
#endif
#ifdef CYASSL_SHA384
InitSha384(&ssl->hashSha384);
#endif
}
if ( (ssl->error = SendClientHello(ssl)) != 0) {
CYASSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;
@ -2799,6 +2814,19 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
}
return method;
}
CYASSL_METHOD* CyaDTLSv1_2_server_method(void)
{
CYASSL_METHOD* method =
(CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
DYNAMIC_TYPE_METHOD);
CYASSL_ENTER("DTLSv1_2_server_method");
if (method) {
InitSSL_Method(method, MakeDTLSv1_2());
method->side = SERVER_END;
}
return method;
}
#endif
@ -2846,7 +2874,7 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
#ifdef CYASSL_DTLS
if (ssl->version.major == DTLS_MAJOR &&
ssl->version.minor == DTLS_MINOR) {
ssl->version.minor >= DTLSv1_2_MINOR) {
ssl->options.dtls = 1;
ssl->options.tls = 1;
ssl->options.tls1_1 = 1;
@ -2900,10 +2928,14 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl)
/* re-init hashes, exclude first hello and verify request */
InitMd5(&ssl->hashMd5);
InitSha(&ssl->hashSha);
#ifndef NO_SHA256
if (IsAtLeastTLSv1_2(ssl))
InitSha256(&ssl->hashSha256);
#endif
if (IsAtLeastTLSv1_2(ssl)) {
#ifndef NO_SHA256
InitSha256(&ssl->hashSha256);
#endif
#ifdef CYASSL_SHA384
InitSha384(&ssl->hashSha384);
#endif
}
while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
if ( (ssl->error = ProcessReply(ssl)) < 0) {
@ -5415,8 +5447,16 @@ int CyaSSL_set_compression(CYASSL* ssl)
return "unknown";
}
}
else if (ssl->version.major == DTLS_MAJOR)
return "DTLS";
else if (ssl->version.major == DTLS_MAJOR) {
switch (ssl->version.minor) {
case DTLS_MINOR :
return "DTLS";
case DTLSv1_2_MINOR :
return "DTLSv1.2";
default:
return "unknown";
}
}
return "unknown";
}