diff --git a/examples/client/client.c b/examples/client/client.c index 63cf3bad1..12394ce68 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -75,7 +75,7 @@ void client_test(void* args) #if defined(CYASSL_DTLS) method = DTLSv1_client_method(); #elif !defined(NO_TLS) - method = TLSv1_client_method(); + method = SSLv23_client_method(); #else method = SSLv3_client_method(); #endif diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index bb7a38ef9..4726e99a1 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -122,11 +122,14 @@ THREAD_RETURN CYASSL_API echoserver_test(void* args) SSL_set_fd(ssl, clientfd); SetDH(ssl); if (SSL_accept(ssl) != SSL_SUCCESS) { - printf("SSL_accept failed"); + printf("SSL_accept failed\n"); SSL_free(ssl); CloseSocket(clientfd); continue; } +#ifdef ECHO_OUT + showPeer(ssl); +#endif while ( (echoSz = SSL_read(ssl, command, sizeof(command))) > 0) { diff --git a/src/cyassl_int.c b/src/cyassl_int.c index 5913ac2b3..33d91fd00 100644 --- a/src/cyassl_int.c +++ b/src/cyassl_int.c @@ -1259,9 +1259,12 @@ static int GetRecordHeader(SSL* ssl, const byte* input, word32* inOutIdx, if (rh->version.major != ssl->version.major || rh->version.minor != ssl->version.minor) { - if (ssl->options.side == SERVER_END && ssl->options.downgrade == 1 && + if (ssl->options.side == SERVER_END && ssl->options.acceptState == ACCEPT_BEGIN) - ; /* haven't negotiated yet */ + CYASSL_MSG("Client attempting to connect with different version"); + else if (ssl->options.side == CLIENT_END && ssl->options.downgrade && + ssl->options.connectState < FIRST_REPLY_DONE) + CYASSL_MSG("Server attempting to accept with different version"); else { CYASSL_MSG("SSL version error"); return VERSION_ERROR; /* only use requested version */ @@ -3731,6 +3734,34 @@ int SetCipherList(SSL_CTX* ctx, const char* list) #endif XMEMCPY(&pv, input + i, sizeof(pv)); i += sizeof(pv); + if (pv.minor > ssl->version.minor) { + CYASSL_MSG("Server using higher version, fatal error"); + return VERSION_ERROR; + } + else if (pv.minor < ssl->version.minor) { + CYASSL_MSG("server using lower version"); + if (!ssl->options.downgrade) { + CYASSL_MSG(" no downgrade allowed, fatal error"); + return VERSION_ERROR; + } + else if (pv.minor == SSLv3_MINOR) { + /* turn off tls */ + CYASSL_MSG(" downgrading to SSLv3"); + ssl->options.tls = 0; + ssl->options.tls1_1 = 0; + ssl->version.minor = SSLv3_MINOR; + } + else if (pv.minor == TLSv1_MINOR) { + /* turn off tls 1.1+ */ + CYASSL_MSG(" downgrading to TLSv1"); + ssl->options.tls1_1 = 0; + ssl->version.minor = TLSv1_MINOR; + } + else if (pv.minor == TLSv1_1_MINOR) { + CYASSL_MSG(" downgrading to TLSv1.1"); + ssl->version.minor = TLSv1_1_MINOR; + } + } XMEMCPY(ssl->arrays.serverRandom, input + i, RAN_LEN); i += RAN_LEN; b = input[i++]; @@ -4928,13 +4959,28 @@ int SetCipherList(SSL_CTX* ctx, const char* list) pv.minor = input[idx++]; ssl->chVersion = pv; /* store */ - if (ssl->version.minor > 0 && pv.minor == 0) { - if (!ssl->options.downgrade) + if (ssl->version.minor > pv.minor) { + if (!ssl->options.downgrade) { + CYASSL_MSG("Client trying to connect with lesser version"); return VERSION_ERROR; - /* turn off tls */ - ssl->options.tls = 0; - ssl->options.tls1_1 = 0; - ssl->version.minor = 0; + } + if (pv.minor == SSLv3_MINOR) { + /* turn off tls */ + CYASSL_MSG(" downgrading to SSLv3"); + ssl->options.tls = 0; + ssl->options.tls1_1 = 0; + ssl->version.minor = SSLv3_MINOR; + } + else if (pv.minor == TLSv1_MINOR) { + CYASSL_MSG(" downgrading to TLSv1"); + /* turn off tls 1.1+ */ + ssl->options.tls1_1 = 0; + ssl->version.minor = TLSv1_MINOR; + } + else if (pv.minor == TLSv1_1_MINOR) { + CYASSL_MSG(" downgrading to TLSv1.1"); + ssl->version.minor = TLSv1_1_MINOR; + } InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, FALSE, ssl->options.haveNTRU, ssl->options.haveECDSA, ssl->ctx->method->side); @@ -5037,13 +5083,28 @@ int SetCipherList(SSL_CTX* ctx, const char* list) XMEMCPY(&pv, input + i, sizeof(pv)); ssl->chVersion = pv; /* store */ i += sizeof(pv); - if (ssl->version.minor > 0 && pv.minor == 0) { - if (!ssl->options.downgrade) + if (ssl->version.minor > pv.minor) { + if (!ssl->options.downgrade) { + CYASSL_MSG("Client trying to connect with lesser version"); return VERSION_ERROR; - /* turn off tls */ - ssl->options.tls = 0; - ssl->options.tls1_1 = 0; - ssl->version.minor = 0; + } + if (pv.minor == SSLv3_MINOR) { + /* turn off tls */ + CYASSL_MSG(" downgrading to SSLv3"); + ssl->options.tls = 0; + ssl->options.tls1_1 = 0; + ssl->version.minor = SSLv3_MINOR; + } + else if (pv.minor == TLSv1_MINOR) { + /* turn off tls 1.1+ */ + CYASSL_MSG(" downgrading to TLSv1"); + ssl->options.tls1_1 = 0; + ssl->version.minor = TLSv1_MINOR; + } + else if (pv.minor == TLSv1_1_MINOR) { + CYASSL_MSG(" downgrading to TLSv1.1"); + ssl->version.minor = TLSv1_1_MINOR; + } InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, FALSE, ssl->options.haveNTRU, ssl->options.haveECDSA, ssl->ctx->method->side); diff --git a/src/tls.c b/src/tls.c index ed477afde..3f2874cc1 100644 --- a/src/tls.c +++ b/src/tls.c @@ -366,13 +366,14 @@ void TLS_hmac(SSL* ssl, byte* digest, const byte* buffer, word32 sz, } - /* TODO: add downgrade */ SSL_METHOD* SSLv23_client_method(void) { SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, DYNAMIC_TYPE_METHOD); - if (method) - InitSSL_Method(method, MakeTLSv1()); + if (method) { + InitSSL_Method(method, MakeTLSv1_2()); + method->downgrade = 1; + } return method; } @@ -424,7 +425,7 @@ void TLS_hmac(SSL* ssl, byte* digest, const byte* buffer, word32 sz, SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, DYNAMIC_TYPE_METHOD); if (method) { - InitSSL_Method(method, MakeTLSv1()); + InitSSL_Method(method, MakeTLSv1_2()); method->side = SERVER_END; method->downgrade = 1; }