From 1742e0ddb61c4f4f36001b363c73950e7a8defc2 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 1 Dec 2014 11:44:32 -0800 Subject: [PATCH] Merge in the ADH-AES128-SHA changes and add a check for it during the packet order sanity checking. --- configure.ac | 21 ++++++- cyassl/internal.h | 12 ++++ cyassl/ssl.h | 5 ++ examples/client/client.c | 29 +++++++-- examples/server/server.c | 30 ++++++++-- src/internal.c | 126 ++++++++++++++++++++++++++------------- src/keys.c | 18 ++++++ src/ssl.c | 35 ++++++++++- tests/test-dtls.conf | 24 ++++++++ tests/test.conf | 30 ++++++++++ 10 files changed, 274 insertions(+), 56 deletions(-) diff --git a/configure.ac b/configure.ac index 67247ce04..d9c1fbd93 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,7 @@ CYASSL_LIBRARY_VERSION=6:0:1 # | | | # | | +- increment if interfaces have been added # | | set to zero if interfaces have been removed -# | or changed +# | | or changed # | +- increment if source code has changed # | set to zero if current is incremented # +- increment if interfaces have been added, removed or changed @@ -807,6 +807,24 @@ fi AM_CONDITIONAL([BUILD_DH], [test "x$ENABLED_DH" = "xyes"]) +# Anonymous +AC_ARG_ENABLE([anon], + [AS_HELP_STRING([--enable-anon],[Enable Anonymous (default: disabled)])], + [ ENABLED_ANON=$enableval ], + [ ENABLED_ANON=no ] + ) + + +if test "x$ENABLED_ANON" = "xyes" +then + if test "x$ENABLED_DH" != "xyes" + then + AC_MSG_ERROR([Anonymous suite requires DH.]) + fi + AM_CFLAGS="$AM_CFLAGS -DHAVE_ANON" +fi + + # ASN # turn off asn, which means no certs, no rsa, no dh, no dsa, no ecc, # and no big int, use this to disable all public key stuff @@ -1876,6 +1894,7 @@ echo " * ECC: $ENABLED_ECC" echo " * FPECC: $ENABLED_FPECC" echo " * ECC_ENCRYPT: $ENABLED_ECC_ENCRYPT" echo " * ASN: $ENABLED_ASN" +echo " * Anonymous cipher: $ENABLED_ANON" echo " * CODING: $ENABLED_CODING" echo " * MEMORY: $ENABLED_MEMORY" echo " * I/O POOL: $ENABLED_IOPOOL" diff --git a/cyassl/internal.h b/cyassl/internal.h index ce60cb3ef..06ff3c336 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -312,6 +312,10 @@ typedef byte word24[3]; #endif #endif +#if defined(HAVE_ANON) && !defined(NO_TLS) && !defined(NO_DH) && \ + !defined(NO_AES) && !defined(NO_SHA) + #define BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA +#endif #if !defined(NO_DH) && !defined(NO_PSK) && !defined(NO_TLS) #ifndef NO_SHA256 @@ -493,6 +497,7 @@ typedef byte word24[3]; enum { TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39, TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x33, + TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x34, TLS_RSA_WITH_AES_256_CBC_SHA = 0x35, TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F, TLS_RSA_WITH_NULL_SHA = 0x02, @@ -1423,6 +1428,9 @@ struct CYASSL_CTX { psk_server_callback server_psk_cb; /* server callback */ char server_hint[MAX_PSK_ID_LEN]; #endif /* NO_PSK */ +#ifdef HAVE_ANON + byte haveAnon; /* User wants to allow Anon suites */ +#endif /* HAVE_ANON */ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) pem_password_cb passwd_cb; void* userdata; @@ -1784,6 +1792,7 @@ typedef struct Options { byte havePeerCert; /* do we have peer's cert */ byte havePeerVerify; /* and peer's cert verify */ byte usingPSK_cipher; /* whether we're using psk as cipher */ + byte usingAnon_cipher; /* whether we're using an anon cipher */ byte sendAlertState; /* nonblocking resume */ byte processReply; /* nonblocking resume */ byte partialWrite; /* only one msg per write call */ @@ -1801,6 +1810,9 @@ typedef struct Options { psk_client_callback client_psk_cb; psk_server_callback server_psk_cb; #endif /* NO_PSK */ +#ifdef HAVE_ANON + byte haveAnon; /* User wants to allow Anon suites */ +#endif /* HAVE_ANON */ } Options; typedef struct Arrays { diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 6279aea58..e70e2f59b 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -715,6 +715,11 @@ enum { /* ssl Constants */ #endif /* NO_PSK */ +#ifdef HAVE_ANON + CYASSL_API int CyaSSL_CTX_allow_anon_cipher(CYASSL_CTX*); +#endif /* HAVE_ANON */ + + /* extra begins */ enum { /* ERR Constants */ diff --git a/examples/client/client.c b/examples/client/client.c index f7b27b040..7705b138b 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -167,6 +167,9 @@ static void Usage(void) #ifdef HAVE_PK_CALLBACKS printf("-P Public Key Callbacks\n"); #endif +#ifdef HAVE_ANON + printf("-a Anonymous client\n"); +#endif } THREAD_RETURN CYASSL_THREAD client_test(void* args) @@ -194,6 +197,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) int ch; int version = CLIENT_INVALID_VERSION; int usePsk = 0; + int useAnon = 0; int sendGET = 0; int benchmark = 0; int doDTLS = 0; @@ -252,7 +256,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) StackTrap(); while ((ch = mygetopt(argc, argv, - "?gdDusmNrRitfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) { + "?gdDusmNrRitfxUPh:p:v:l:A:c:k:b:zS:L:ToO:a")) != -1) { switch (ch) { case '?' : Usage(); @@ -416,6 +420,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) #endif break; + case 'a' : + #ifdef HAVE_ANON + useAnon = 1; + #endif + break; + default: Usage(); exit(MY_EX_USAGE); @@ -524,6 +534,17 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) useClientCert = 0; } + if (useAnon) { +#ifdef HAVE_ANON + if (cipherList == NULL) { + CyaSSL_CTX_allow_anon_cipher(ctx); + if (CyaSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA") != SSL_SUCCESS) + err_sys("client can't set cipher list 4"); + } +#endif + useClientCert = 0; + } + #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif @@ -568,15 +589,15 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) "from CyaSSL home dir"); } - if (!usePsk) { + if (!usePsk && !useAnon) { if (CyaSSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); } #endif #if !defined(NO_CERTS) - if (!usePsk && doPeerCheck == 0) + if (!usePsk && !useAnon && doPeerCheck == 0) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); - if (!usePsk && overrideDateErrors == 1) + if (!usePsk && !useAnon && overrideDateErrors == 1) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb); #endif diff --git a/examples/server/server.c b/examples/server/server.c index 6217dbb82..2c7c4134d 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -141,6 +141,9 @@ static void Usage(void) #ifdef HAVE_PK_CALLBACKS printf("-P Public Key Callbacks\n"); #endif +#ifdef HAVE_ANON + printf("-a Anonymous server\n"); +#endif } THREAD_RETURN CYASSL_THREAD server_test(void* args) @@ -161,6 +164,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int useAnyAddr = 0; word16 port = yasslPort; int usePsk = 0; + int useAnon = 0; int doDTLS = 0; int useNtruKey = 0; int nonBlocking = 0; @@ -198,7 +202,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) fdOpenSession(Task_self()); #endif - while ((ch = mygetopt(argc, argv, "?dbstnNufrPp:v:l:A:c:k:S:oO:")) != -1) { + while ((ch = mygetopt(argc, argv, "?dbstnNufraPp:v:l:A:c:k:S:oO:")) != -1) { switch (ch) { case '?' : Usage(); @@ -299,6 +303,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif break; + case 'a' : + #ifdef HAVE_ANON + useAnon = 1; + #endif + break; + default: Usage(); exit(MY_EX_USAGE); @@ -394,7 +404,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) - if (!usePsk) { + if (!usePsk && !useAnon) { if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" @@ -412,7 +422,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) - if (!useNtruKey && !usePsk) { + if (!useNtruKey && !usePsk && !useAnon) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server private key file, check file and run " @@ -437,9 +447,19 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif } + if (useAnon) { +#ifdef HAVE_ANON + CyaSSL_CTX_allow_anon_cipher(ctx); + if (cipherList == NULL) { + if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS) + err_sys("server can't set cipher list 4"); + } +#endif + } + #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) /* if not using PSK, verify peer with certs */ - if (doCliCertCheck && usePsk == 0) { + if (doCliCertCheck && usePsk == 0 && useAnon == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) @@ -494,7 +514,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) CloseSocket(sockfd); SSL_set_fd(ssl, clientfd); - if (usePsk == 0 || cipherList != NULL) { + if (usePsk == 0 || useAnon == 1 || cipherList != NULL) { #if !defined(NO_FILESYSTEM) && !defined(NO_DH) CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); #elif !defined(NO_DH) diff --git a/src/internal.c b/src/internal.c index 62e88aab3..700ddfa65 100644 --- a/src/internal.c +++ b/src/internal.c @@ -368,6 +368,9 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method) ctx->client_psk_cb = 0; ctx->server_psk_cb = 0; #endif /* NO_PSK */ +#ifdef HAVE_ANON + ctx->haveAnon = 0; +#endif /* HAVE_ANON */ #ifdef HAVE_ECC ctx->eccTempKeySz = ECDHE_SIZE; #endif @@ -626,7 +629,7 @@ void InitCipherSpecs(CipherSpecs* cs) } static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, - int haveRSAsig) + int haveRSAsig, int haveAnon) { int idx = 0; @@ -660,6 +663,13 @@ static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, #endif } + if (haveAnon) { + #ifdef HAVE_ANON + suites->hashSigAlgo[idx++] = sha_mac; + suites->hashSigAlgo[idx++] = anonymous_sa_algo; + #endif + } + suites->hashSigAlgoSz = (word16)idx; } @@ -1378,7 +1388,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, suites->suiteSz = idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig); + InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0); } @@ -1486,6 +1496,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) int ret; byte haveRSA = 0; byte havePSK = 0; + byte haveAnon = 0; ssl->ctx = ctx; /* only for passing to calls, options could change */ ssl->version = ctx->method->version; @@ -1607,6 +1618,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->options.havePeerCert = 0; ssl->options.havePeerVerify = 0; ssl->options.usingPSK_cipher = 0; + ssl->options.usingAnon_cipher = 0; ssl->options.sendAlertState = 0; #ifndef NO_PSK havePSK = ctx->havePSK; @@ -1614,6 +1626,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->options.client_psk_cb = ctx->client_psk_cb; ssl->options.server_psk_cb = ctx->server_psk_cb; #endif /* NO_PSK */ +#ifdef HAVE_ANON + haveAnon = ctx->haveAnon; + ssl->options.haveAnon = ctx->haveAnon; +#endif ssl->options.serverState = NULL_STATE; ssl->options.clientState = NULL_STATE; @@ -1866,8 +1882,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) if (ret != 0) return ret; #endif #ifndef NO_CERTS - /* make sure server has cert and key unless using PSK */ - if (ssl->options.side == CYASSL_SERVER_END && !havePSK) + /* make sure server has cert and key unless using PSK or Anon */ + if (ssl->options.side == CYASSL_SERVER_END && !havePSK && !haveAnon) if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) { CYASSL_MSG("Server missing certificate and/or private key"); return NO_PRIVATE_KEY; @@ -3785,6 +3801,12 @@ static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) return 1; break; #endif +#ifdef HAVE_ANON + case TLS_DH_anon_WITH_AES_128_CBC_SHA : + if (requirement == REQUIRES_DHE) + return 1; + break; +#endif default: CYASSL_MSG("Unsupported cipher suite, CipherRequires"); @@ -4811,7 +4833,8 @@ static int SanityCheckMsgReceived(CYASSL* ssl, byte type) ssl->msgsReceived.got_server_hello_done = 1; if (ssl->msgsReceived.got_certificate == 0) { - if (ssl->specs.kea == psk_kea) { + if (ssl->specs.kea == psk_kea || + ssl->options.usingAnon_cipher) { CYASSL_MSG("No Cert required"); } else { CYASSL_MSG("No Certificate before ServerHelloDone"); @@ -7377,7 +7400,8 @@ int SendCertificate(CYASSL* ssl) word32 certSz, listSz; byte* output = 0; - if (ssl->options.usingPSK_cipher) return 0; /* not needed */ + if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher) + return 0; /* not needed */ if (ssl->options.sendVerify == SEND_BLANK_CERT) { certSz = 0; @@ -7495,7 +7519,8 @@ int SendCertificateRequest(CYASSL* ssl) if (IsAtLeastTLSv1_2(ssl)) reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz; - if (ssl->options.usingPSK_cipher) return 0; /* not needed */ + if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher) + return 0; /* not needed */ sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz; @@ -8535,6 +8560,10 @@ static const char* const cipher_names[] = "DHE-RSA-CHACHA20-POLY1305", #endif +#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA + "ADH-AES128-SHA", +#endif + #ifdef HAVE_RENEGOTIATION_INDICATION "RENEGOTIATION-INFO", #endif @@ -8925,6 +8954,10 @@ static int cipher_name_idx[] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, #endif +#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA + TLS_DH_anon_WITH_AES_128_CBC_SHA, +#endif + #ifdef HAVE_RENEGOTIATION_INDICATION TLS_EMPTY_RENEGOTIATION_INFO_SCSV, #endif @@ -8960,6 +8993,7 @@ int SetCipherList(Suites* suites, const char* list) int idx = 0; int haveRSAsig = 0; int haveECDSAsig = 0; + int haveAnon = 0; const int suiteSz = GetCipherNamesSize(); char* next = (char*)list; @@ -8993,10 +9027,12 @@ int SetCipherList(Suites* suites, const char* list) suites->suites[idx++] = (byte)cipher_name_idx[i]; - /* The suites are either ECDSA, RSA, or PSK. The RSA suites - * don't necessarily have RSA in the name. */ + /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA + * suites don't necessarily have RSA in the name. */ if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA")) haveECDSAsig = 1; + else if (XSTRSTR(name, "ADH")) + haveAnon = 1; else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL)) haveRSAsig = 1; @@ -9010,7 +9046,7 @@ int SetCipherList(Suites* suites, const char* list) if (ret) { suites->setSuites = 1; suites->suiteSz = (word16)idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig); + InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon); } return ret; @@ -9993,8 +10029,9 @@ static void PickHashSigAlgo(CYASSL* ssl, #endif /* !NO_DH || !NO_PSK */ #if !defined(NO_DH) || defined(HAVE_ECC) - if (ssl->specs.kea == ecc_diffie_hellman_kea || - ssl->specs.kea == diffie_hellman_kea) + if (!ssl->options.usingAnon_cipher && + (ssl->specs.kea == ecc_diffie_hellman_kea || + ssl->specs.kea == diffie_hellman_kea)) { #ifndef NO_OLD_TLS #ifdef CYASSL_SMALL_STACK @@ -12062,18 +12099,19 @@ int DoSessionTicket(CYASSL* ssl, &ssl->buffers.serverDH_Pub.length); FreeDhKey(&dhKey); - if (ret == 0) { + if (ret != 0) return ret; + + length = LENGTH_SZ * 3; /* p, g, pub */ + length += ssl->buffers.serverDH_P.length + + ssl->buffers.serverDH_G.length + + ssl->buffers.serverDH_Pub.length; + + preSigIdx = idx; + preSigSz = length; + + if (!ssl->options.usingAnon_cipher) { ret = InitRsaKey(&rsaKey, ssl->heap); if (ret != 0) return ret; - } - if (ret == 0) { - length = LENGTH_SZ * 3; /* p, g, pub */ - length += ssl->buffers.serverDH_P.length + - ssl->buffers.serverDH_G.length + - ssl->buffers.serverDH_Pub.length; - - preSigIdx = idx; - preSigSz = length; /* sig length */ length += LENGTH_SZ; @@ -12087,14 +12125,14 @@ int DoSessionTicket(CYASSL* ssl, sigSz = RsaEncryptSize(&rsaKey); length += sigSz; } - } - if (ret != 0) { - FreeRsaKey(&rsaKey); - return ret; - } + else { + FreeRsaKey(&rsaKey); + return ret; + } - if (IsAtLeastTLSv1_2(ssl)) - length += HASH_SIG_SIZE; + if (IsAtLeastTLSv1_2(ssl)) + length += HASH_SIG_SIZE; + } sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; @@ -12108,7 +12146,8 @@ int DoSessionTicket(CYASSL* ssl, /* check for available size */ if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) { - FreeRsaKey(&rsaKey); + if (!ssl->options.usingAnon_cipher) + FreeRsaKey(&rsaKey); return ret; } @@ -12139,23 +12178,14 @@ int DoSessionTicket(CYASSL* ssl, ssl->buffers.serverDH_Pub.length); idx += ssl->buffers.serverDH_Pub.length; - /* Add signature */ - if (IsAtLeastTLSv1_2(ssl)) { - output[idx++] = ssl->suites->hashAlgo; - output[idx++] = ssl->suites->sigAlgo; - } - /* size */ - c16toa((word16)sigSz, output + idx); - idx += LENGTH_SZ; - #ifdef HAVE_FUZZER if (ssl->fuzzerCb) ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE, ssl->fuzzerCtx); #endif - /* do signature */ - { + /* Add signature */ + if (!ssl->options.usingAnon_cipher) { #ifndef NO_OLD_TLS #ifdef CYASSL_SMALL_STACK Md5* md5 = NULL; @@ -12189,6 +12219,17 @@ int DoSessionTicket(CYASSL* ssl, #endif #endif + /* Add hash/signature algo ID */ + if (IsAtLeastTLSv1_2(ssl)) { + output[idx++] = ssl->suites->hashAlgo; + output[idx++] = ssl->suites->sigAlgo; + } + + /* signature size */ + c16toa((word16)sigSz, output + idx); + idx += LENGTH_SZ; + + /* do signature */ #ifdef CYASSL_SMALL_STACK hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -12357,8 +12398,7 @@ int DoSessionTicket(CYASSL* ssl, #endif #endif - if (ret < 0) - return ret; + if (ret < 0) return ret; } #ifdef CYASSL_DTLS diff --git a/src/keys.c b/src/keys.c index fd90a6e54..264809179 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1732,6 +1732,24 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA + case TLS_DH_anon_WITH_AES_128_CBC_SHA : + ssl->specs.bulk_cipher_algorithm = cyassl_aes; + ssl->specs.cipher_type = block; + ssl->specs.mac_algorithm = sha_mac; + ssl->specs.kea = diffie_hellman_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AES_IV_SIZE; + + ssl->options.usingAnon_cipher = 1; + break; +#endif + default: CYASSL_MSG("Unsupported cipher suite, SetCipherSpecs"); return UNSUPPORTED_SUITE; diff --git a/src/ssl.c b/src/ssl.c index 7c84943b7..511c8e229 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -844,10 +844,11 @@ CYASSL_API int CyaSSL_get_SessionTicket(CYASSL* ssl, byte* buf, word32* bufSz) CYASSL_API int CyaSSL_set_SessionTicket(CYASSL* ssl, byte* buf, word32 bufSz) { - if (ssl == NULL || buf == NULL || bufSz == 0) + if (ssl == NULL || (buf == NULL && bufSz > 0)) return BAD_FUNC_ARG; - XMEMCPY(ssl->session.ticket, buf, bufSz); + if (bufSz > 0) + XMEMCPY(ssl->session.ticket, buf, bufSz); ssl->session.ticketLen = bufSz; return SSL_SUCCESS; @@ -5235,6 +5236,7 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) int CyaSSL_accept(CYASSL* ssl) { byte havePSK = 0; + byte haveAnon = 0; CYASSL_ENTER("SSL_accept()"); #ifdef HAVE_ERRNO_H @@ -5246,6 +5248,11 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) #endif (void)havePSK; + #ifdef HAVE_ANON + haveAnon = ssl->options.haveAnon; + #endif + (void)haveAnon; + if (ssl->options.side != CYASSL_SERVER_END) { CYASSL_ERROR(ssl->error = SIDE_ERROR); return SSL_FATAL_ERROR; @@ -5253,7 +5260,8 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) #ifndef NO_CERTS /* in case used set_accept_state after init */ - if (!havePSK && (ssl->buffers.certificate.buffer == NULL || + if (!havePSK && !haveAnon && + (ssl->buffers.certificate.buffer == NULL || ssl->buffers.key.buffer == NULL)) { CYASSL_MSG("accept error: don't have server cert and key"); ssl->error = NO_PRIVATE_KEY; @@ -6294,6 +6302,23 @@ int CyaSSL_set_compression(CYASSL* ssl) #endif /* NO_PSK */ +#ifdef HAVE_ANON + + int CyaSSL_CTX_allow_anon_cipher(CYASSL_CTX* ctx) + { + CYASSL_ENTER("CyaSSL_CTX_allow_anon_cipher"); + + if (ctx == NULL) + return SSL_FAILURE; + + ctx->haveAnon = 1; + + return SSL_SUCCESS; + } + +#endif /* HAVE_ANON */ + + #ifndef NO_CERTS /* used to be defined on NO_FILESYSTEM only, but are generally useful */ @@ -9232,6 +9257,10 @@ const char* CyaSSL_CIPHER_get_name(const CYASSL_CIPHER* cipher) case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 : return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"; #endif /* NO_RSA */ +#ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA + case TLS_DH_anon_WITH_AES_128_CBC_SHA : + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; +#endif default: return "NONE"; } /* switch */ diff --git a/tests/test-dtls.conf b/tests/test-dtls.conf index 887afb18d..7a9c041e5 100644 --- a/tests/test-dtls.conf +++ b/tests/test-dtls.conf @@ -882,3 +882,27 @@ -l ECDHE-ECDSA-AES256-CCM-8 -A ./certs/server-ecc.pem +# server DTLSv1.2 ADH-AES128-SHA +-u +-a +-v 3 +-l ADH-AES128-SHA + +# client DTLSv1.2 ADH-AES128-SHA +-u +-a +-v 3 +-l ADH-AES128-SHA + +# server DTLSv1.0 ADH-AES128-SHA +-u +-a +-v 2 +-l ADH-AES128-SHA + +# client DTLSv1.0 ADH-AES128-SHA +-u +-a +-v 2 +-l ADH-AES128-SHA + diff --git a/tests/test.conf b/tests/test.conf index b3656f112..c949c2024 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2003,3 +2003,33 @@ -v 3 -l DHE-PSK-AES256-CCM +# server TLSv1.2 ADH-AES128-SHA +-a +-v 3 +-l ADH-AES128-SHA + +# client TLSv1.2 ADH-AES128-SHA +-a +-v 3 +-l ADH-AES128-SHA + +# server TLSv1.1 ADH-AES128-SHA +-a +-v 2 +-l ADH-AES128-SHA + +# client TLSv1.1 ADH-AES128-SHA +-a +-v 2 +-l ADH-AES128-SHA + +# server TLSv1.0 ADH-AES128-SHA +-a +-v 1 +-l ADH-AES128-SHA + +# client TLSv1.0 ADH-AES128-SHA +-a +-v 1 +-l ADH-AES128-SHA +