diff --git a/cyassl/error.h b/cyassl/error.h index 7ad273910..2f222051a 100644 --- a/cyassl/error.h +++ b/cyassl/error.h @@ -110,6 +110,7 @@ enum CyaSSL_ErrorCodes { SANITY_CIPHER_E = -275, /* sanity check on cipher error */ RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */ GEN_COOKIE_E = -277, /* Generate Cookie Error */ + NO_PEER_VERIFY = -278, /* Need peer cert verify Error */ /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ diff --git a/cyassl/internal.h b/cyassl/internal.h index 5865025b9..0c3a76114 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1317,6 +1317,7 @@ typedef struct Options { byte haveECDSAsig; /* server ECDSA signed cert */ byte haveStaticECC; /* static server ECC private key */ 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 sendAlertState; /* nonblocking resume */ byte processReply; /* nonblocking resume */ diff --git a/src/internal.c b/src/internal.c index 7cbf03ca2..01610c56c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1191,7 +1191,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->options.haveNTRU = ctx->haveNTRU; ssl->options.haveECDSAsig = ctx->haveECDSAsig; ssl->options.haveStaticECC = ctx->haveStaticECC; - ssl->options.havePeerCert = 0; + ssl->options.havePeerCert = 0; + ssl->options.havePeerVerify = 0; ssl->options.usingPSK_cipher = 0; ssl->options.sendAlertState = 0; #ifndef NO_PSK @@ -1221,6 +1222,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->dtls_pool = NULL; ssl->dtls_msg_list = NULL; #endif + ssl->keys.encryptSz = 0; ssl->keys.encryptionOn = 0; /* initially off */ ssl->keys.decryptedCur = 0; /* initially off */ ssl->options.sessionCacheOff = ctx->sessionCacheOff; @@ -1301,6 +1303,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->rng = NULL; ssl->arrays = NULL; InitCiphers(ssl); + InitCipherSpecs(&ssl->specs); /* all done with init, now can return errors, call other stuff */ /* increment CTX reference count */ @@ -1340,8 +1343,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) return MEMORY_E; } - if ( (ret = InitRng(ssl->rng)) != 0) + if ( (ret = InitRng(ssl->rng)) != 0) { + CYASSL_MSG("RNG Init error"); return ret; + } /* suites */ ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, @@ -4279,6 +4284,17 @@ int ProcessReply(CYASSL* ssl) CYASSL_MSG("Malicious or corrupted ChangeCipher msg"); return LENGTH_ERROR; } + #ifndef NO_CERTS + if (ssl->options.side == SERVER_END && + ssl->options.verifyPeer && + ssl->options.havePeerCert) + if (!ssl->options.havePeerVerify) { + CYASSL_MSG("client didn't send cert verify"); + return NO_PEER_VERIFY; + } + #endif + + ssl->buffers.inputBuffer.idx++; ssl->keys.encryptionOn = 1; @@ -5433,6 +5449,10 @@ void SetErrorString(int error, char* str) XSTRNCPY(str, "Generate Cookie Error", max); break; + case NO_PEER_VERIFY: + XSTRNCPY(str, "Need peer certificate verify Error", max); + break; + default : XSTRNCPY(str, "unknown error number", max); } @@ -8772,7 +8792,7 @@ int SetCipherList(Suites* s, const char* list) byte* out; int outLen; byte hashAlgo = sha_mac; - byte sigAlgo; + byte sigAlgo = anonymous_sa_algo; #ifdef CYASSL_CALLBACKS if (ssl->hsInfoOn) @@ -8813,6 +8833,10 @@ int SetCipherList(Suites* s, const char* list) int typeH = SHAh; int digestSz = SHA_DIGEST_SIZE; + if (sigAlgo != rsa_sa_algo) { + CYASSL_MSG("Oops, peer sent RSA key but not in verify"); + } + if (hashAlgo == sha256_mac) { #ifndef NO_SHA256 digest = ssl->certHashes.sha256; @@ -8851,6 +8875,9 @@ int SetCipherList(Suites* s, const char* list) CYASSL_MSG("Doing ECC peer cert verify"); if (IsAtLeastTLSv1_2(ssl)) { + if (sigAlgo != ecc_dsa_sa_algo) { + CYASSL_MSG("Oops, peer sent ECC key but not in verify"); + } if (hashAlgo == sha256_mac) { #ifndef NO_SHA256 digest = ssl->certHashes.sha256; @@ -8871,6 +8898,9 @@ int SetCipherList(Suites* s, const char* list) ret = 0; /* verified */ } #endif + if (ret == 0) + ssl->options.havePeerVerify = 1; + return ret; } #endif /* !NO_RSA || HAVE_ECC */ diff --git a/src/ssl.c b/src/ssl.c index b2d0b0d55..d096e324b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -147,6 +147,7 @@ void CyaSSL_CTX_free(CYASSL_CTX* ctx) CYASSL* CyaSSL_new(CYASSL_CTX* ctx) { CYASSL* ssl = NULL; + int ret = 0; CYASSL_ENTER("SSL_new"); @@ -155,12 +156,12 @@ CYASSL* CyaSSL_new(CYASSL_CTX* ctx) ssl = (CYASSL*) XMALLOC(sizeof(CYASSL), ctx->heap,DYNAMIC_TYPE_SSL); if (ssl) - if (InitSSL(ssl, ctx) < 0) { + if ( (ret = InitSSL(ssl, ctx)) < 0) { FreeSSL(ssl); ssl = 0; } - CYASSL_LEAVE("SSL_new", 0); + CYASSL_LEAVE("SSL_new", ret); return ssl; } @@ -2714,7 +2715,7 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) CYASSL_MSG("connect state: FIRST_REPLY_SECOND"); case FIRST_REPLY_SECOND : - #ifndef NO_RSA + #ifndef NO_CERTS if (ssl->options.sendVerify) if ( (ssl->error = SendCertificateVerify(ssl)) != 0) { CYASSL_ERROR(ssl->error); diff --git a/tests/include.am b/tests/include.am index 5b420fc42..c061320c1 100644 --- a/tests/include.am +++ b/tests/include.am @@ -28,6 +28,9 @@ EXTRA_DIST += tests/test.conf \ tests/test-aesgcm-ecc.conf \ tests/test-aesgcm-openssl.conf \ tests/test-aesccm.conf \ + tests/test-aesccm-ecc.conf \ + tests/test-camellia.conf \ + tests/test-camellia-openssl.conf \ tests/test-dtls.conf \ tests/test-rabbit.conf \ tests/test-null.conf \