diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-03-28 01:04:46 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-03-28 01:04:46 +0200 |
commit | 20e706689df1eb87c696304797e9d6184c0a75bb (patch) | |
tree | ff3eab8fa3e060b34687c6e9819cb559ac67d5c5 /extra/yassl/src | |
parent | 3d0775e9af2fcf3fe92b7f19e299ea23068eca1e (diff) | |
parent | bfaebe3f5e4b917c4498e234bad7a9d45d07ca62 (diff) | |
download | mariadb-git-20e706689df1eb87c696304797e9d6184c0a75bb.tar.gz |
mysql-5.5.22 merge
mysql-test/suite/innodb/t/group_commit_crash.test:
remove autoincrement to avoid rbr being used for insert ... select
mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test:
remove autoincrement to avoid rbr being used for insert ... select
mysys/my_addr_resolve.c:
a pointer to a buffer is returned to the caller -> the buffer cannot be on the stack
mysys/stacktrace.c:
my_vsnprintf() is ok here, in 5.5
Diffstat (limited to 'extra/yassl/src')
-rw-r--r-- | extra/yassl/src/buffer.cpp | 12 | ||||
-rw-r--r-- | extra/yassl/src/cert_wrapper.cpp | 6 | ||||
-rw-r--r-- | extra/yassl/src/crypto_wrapper.cpp | 5 | ||||
-rw-r--r-- | extra/yassl/src/handshake.cpp | 47 | ||||
-rwxr-xr-x[-rw-r--r--] | extra/yassl/src/make.bat | 0 | ||||
-rw-r--r-- | extra/yassl/src/socket_wrapper.cpp | 23 | ||||
-rw-r--r-- | extra/yassl/src/ssl.cpp | 123 | ||||
-rw-r--r-- | extra/yassl/src/yassl.cpp | 6 | ||||
-rw-r--r-- | extra/yassl/src/yassl_error.cpp | 16 | ||||
-rw-r--r-- | extra/yassl/src/yassl_imp.cpp | 58 | ||||
-rw-r--r-- | extra/yassl/src/yassl_int.cpp | 52 |
11 files changed, 222 insertions, 126 deletions
diff --git a/extra/yassl/src/buffer.cpp b/extra/yassl/src/buffer.cpp index a5028e7bb53..d885c953207 100644 --- a/extra/yassl/src/buffer.cpp +++ b/extra/yassl/src/buffer.cpp @@ -35,14 +35,6 @@ namespace yaSSL { -// Checking Policy should implement a check function that tests whether the -// index is within the size limit of the array - -void Check::check(uint i, uint limit) -{ - assert(i < limit); -} - void NoCheck::check(uint, uint) { @@ -86,7 +78,6 @@ input_buffer::~input_buffer() // users can pass defualt zero length buffer and then allocate void input_buffer::allocate(uint s) { - assert(!buffer_); // find realloc error buffer_ = NEW_YS byte[s]; end_ = buffer_ + s; } @@ -144,7 +135,6 @@ void input_buffer::set_current(uint i) // user passes in AUTO index for ease of use const byte& input_buffer::operator[](uint i) { - assert (i == AUTO); check(current_, size_); return buffer_[current_++]; } @@ -241,7 +231,6 @@ void output_buffer::set_current(uint c) // users can pass defualt zero length buffer and then allocate void output_buffer::allocate(uint s) { - assert(!buffer_); // find realloc error buffer_ = NEW_YS byte[s]; end_ = buffer_ + s; } @@ -257,7 +246,6 @@ const byte* output_buffer::get_buffer() const // user passes in AUTO as index for ease of use byte& output_buffer::operator[](uint i) { - assert(i == AUTO); check(current_, get_capacity()); return buffer_[current_++]; } diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index d8660533f2e..7e73464001a 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -250,7 +250,8 @@ int CertManager::Validate() TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); - if (int err = cert.GetError().What()) + int err = cert.GetError().What(); + if ( err ) return err; const TaoCrypt::PublicKey& key = cert.GetPublicKey(); @@ -266,7 +267,7 @@ int CertManager::Validate() TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); int err = cert.GetError().What(); - if ( err ) + if ( err && err != TaoCrypt::SIG_OTHER_E) return err; uint sz = cert.GetPublicKey().size(); @@ -327,7 +328,6 @@ int CertManager::SetPrivateKey(const x509& key) // Store OpenSSL type peer's cert void CertManager::setPeerX509(X509* x) { - assert(peerX509_ == 0); if (x == 0) return; X509_NAME* issuer = x->GetIssuer(); diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index afb492c83c5..bdd5f60c4ea 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -954,10 +954,7 @@ x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info) } } // get blank line - if (fgets(line,sizeof(line), file) == 0) - { - /* Impossible case */ - } + if (fgets(line, sizeof(line), file)) begin = ftell(file); } diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 08fae4ac17d..c1ee61d043e 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -50,7 +50,7 @@ void buildClientHello(SSL& ssl, ClientHello& hello) hello.suite_len_ = ssl.getSecurity().get_parms().suites_size_; memcpy(hello.cipher_suites_, ssl.getSecurity().get_parms().suites_, hello.suite_len_); - hello.comp_len_ = 1; + hello.comp_len_ = 1; hello.set_length(sizeof(ProtocolVersion) + RAN_LEN + @@ -528,8 +528,9 @@ void ProcessOldClientHello(input_buffer& input, SSL& ssl) input.read(len, sizeof(len)); uint16 randomLen; ato16(len, randomLen); + if (ch.suite_len_ > MAX_SUITE_SZ || sessionLen > ID_LEN || - randomLen > RAN_LEN) { + randomLen > RAN_LEN) { ssl.SetError(bad_input); return; } @@ -707,7 +708,7 @@ int DoProcessReply(SSL& ssl) { // wait for input if blocking if (!ssl.useSocket().wait()) { - ssl.SetError(receive_error); + ssl.SetError(receive_error); return 0; } uint ready = ssl.getSocket().get_ready(); @@ -750,8 +751,8 @@ int DoProcessReply(SSL& ssl) if (static_cast<uint>(RECORD_HEADER) > buffer.get_remaining()) needHdr = true; else { - buffer >> hdr; - ssl.verifyState(hdr); + buffer >> hdr; + ssl.verifyState(hdr); } // make sure we have enough input in buffer to process this record @@ -789,9 +790,8 @@ int DoProcessReply(SSL& ssl) void processReply(SSL& ssl) { if (ssl.GetError()) return; - - if (DoProcessReply(ssl)) - { + + if (DoProcessReply(ssl)) { // didn't complete process if (!ssl.getSocket().IsNonBlocking()) { // keep trying now, blocking ok @@ -857,6 +857,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer) if (ssl.GetError()) return; ServerKeyExchange sk(ssl); sk.build(ssl); + if (ssl.GetError()) return; RecordLayerHeader rlHeader; HandShakeHeader hsHeader; @@ -875,8 +876,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer) // send change cipher void sendChangeCipher(SSL& ssl, BufferOutput buffer) { - if (ssl.getSecurity().get_parms().entity_ == server_end) - { + if (ssl.getSecurity().get_parms().entity_ == server_end) { if (ssl.getSecurity().get_resuming()) ssl.verifyState(clientKeyExchangeComplete); else @@ -913,7 +913,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) } else { if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) - GetSessions().add(ssl); // store session + GetSessions().add(ssl); // store session if (side == client_end) buildFinished(ssl, ssl.useHashes().use_verify(), server); // server } @@ -929,12 +929,22 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) // send data int sendData(SSL& ssl, const void* buffer, int sz) { + int sent = 0; + if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ)) ssl.SetError(no_error); + if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { + ssl.SetError(no_error); + ssl.SendWriteBuffered(); + if (!ssl.GetError()) { + // advance sent to prvevious sent + plain size just sent + sent = ssl.useBuffers().prevSent + ssl.useBuffers().plainSz; + } + } + ssl.verfiyHandShakeComplete(); if (ssl.GetError()) return -1; - int sent = 0; for (;;) { int len = min(sz - sent, MAX_RECORD_SIZE); @@ -943,6 +953,8 @@ int sendData(SSL& ssl, const void* buffer, int sz) Data data; + if (sent == sz) break; + if (ssl.CompressionOn()) { if (Compress(static_cast<const opaque*>(buffer) + sent, len, tmp) == -1) { @@ -957,9 +969,14 @@ int sendData(SSL& ssl, const void* buffer, int sz) buildMessage(ssl, out, data); ssl.Send(out.get_buffer(), out.get_size()); - if (ssl.GetError()) return -1; + if (ssl.GetError()) { + if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { + ssl.useBuffers().plainSz = len; + ssl.useBuffers().prevSent = sent; + } + return -1; + } sent += len; - if (sent == sz) break; } ssl.useLog().ShowData(sent, true); return sent; @@ -992,7 +1009,7 @@ int receiveData(SSL& ssl, Data& data, bool peek) if (peek) ssl.PeekData(data); else - ssl.fillData(data); + ssl.fillData(data); ssl.useLog().ShowData(data.get_length()); if (ssl.GetError()) return -1; diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat index cccd11dbd17..cccd11dbd17 100644..100755 --- a/extra/yassl/src/make.bat +++ b/extra/yassl/src/make.bat diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index 3cf6c14c4b3..d88df13c08e 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -109,19 +109,28 @@ uint Socket::get_ready() const } -uint Socket::send(const byte* buf, unsigned int sz, int flags) const +uint Socket::send(const byte* buf, unsigned int sz, unsigned int& written, + int flags) { const byte* pos = buf; const byte* end = pos + sz; + wouldBlock_ = false; + while (pos != end) { int sent = ::send(socket_, reinterpret_cast<const char *>(pos), static_cast<int>(end - pos), flags); - - if (sent == -1) - return 0; - + if (sent == -1) { + if (get_lastError() == SOCKET_EWOULDBLOCK || + get_lastError() == SOCKET_EAGAIN) { + wouldBlock_ = true; // would have blocked this time only + nonBlocking_ = true; // nonblocking, win32 only way to tell + return 0; + } + return static_cast<uint>(-1); + } pos += sent; + written += sent; } return sz; @@ -140,8 +149,8 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags) get_lastError() == SOCKET_EAGAIN) { wouldBlock_ = true; // would have blocked this time only nonBlocking_ = true; // socket nonblocking, win32 only way to tell - return 0; - } + return 0; + } } else if (recvd == 0) return static_cast<uint>(-1); diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 05c260e80ca..8401798534b 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -252,60 +252,73 @@ int SSL_connect(SSL* ssl) if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ)) ssl->SetError(no_error); + if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { + + ssl->SetError(no_error); + ssl->SendWriteBuffered(); + if (!ssl->GetError()) + ssl->useStates().UseConnect() = + ConnectState(ssl->getStates().GetConnect() + 1); + } + ClientState neededState; switch (ssl->getStates().GetConnect()) { case CONNECT_BEGIN : - sendClientHello(*ssl); + sendClientHello(*ssl); if (!ssl->GetError()) ssl->useStates().UseConnect() = CLIENT_HELLO_SENT; case CLIENT_HELLO_SENT : neededState = ssl->getSecurity().get_resuming() ? - serverFinishedComplete : serverHelloDoneComplete; - while (ssl->getStates().getClient() < neededState) { - if (ssl->GetError()) break; - processReply(*ssl); - } + serverFinishedComplete : serverHelloDoneComplete; + while (ssl->getStates().getClient() < neededState) { + if (ssl->GetError()) break; + processReply(*ssl); + // if resumption failed, reset needed state + if (neededState == serverFinishedComplete) + if (!ssl->getSecurity().get_resuming()) + neededState = serverHelloDoneComplete; + } if (!ssl->GetError()) ssl->useStates().UseConnect() = FIRST_REPLY_DONE; case FIRST_REPLY_DONE : - if(ssl->getCrypto().get_certManager().sendVerify()) - sendCertificate(*ssl); + if(ssl->getCrypto().get_certManager().sendVerify()) + sendCertificate(*ssl); - if (!ssl->getSecurity().get_resuming()) - sendClientKeyExchange(*ssl); + if (!ssl->getSecurity().get_resuming()) + sendClientKeyExchange(*ssl); - if(ssl->getCrypto().get_certManager().sendVerify()) - sendCertificateVerify(*ssl); + if(ssl->getCrypto().get_certManager().sendVerify()) + sendCertificateVerify(*ssl); - sendChangeCipher(*ssl); - sendFinished(*ssl, client_end); - ssl->flushBuffer(); + sendChangeCipher(*ssl); + sendFinished(*ssl, client_end); + ssl->flushBuffer(); if (!ssl->GetError()) ssl->useStates().UseConnect() = FINISHED_DONE; case FINISHED_DONE : - if (!ssl->getSecurity().get_resuming()) - while (ssl->getStates().getClient() < serverFinishedComplete) { - if (ssl->GetError()) break; - processReply(*ssl); - } + if (!ssl->getSecurity().get_resuming()) + while (ssl->getStates().getClient() < serverFinishedComplete) { + if (ssl->GetError()) break; + processReply(*ssl); + } if (!ssl->GetError()) ssl->useStates().UseConnect() = SECOND_REPLY_DONE; case SECOND_REPLY_DONE : - ssl->verifyState(serverFinishedComplete); - ssl->useLog().ShowTCP(ssl->getSocket().get_fd()); + ssl->verifyState(serverFinishedComplete); + ssl->useLog().ShowTCP(ssl->getSocket().get_fd()); if (ssl->GetError()) { GetErrors().Add(ssl->GetError()); - return SSL_FATAL_ERROR; + return SSL_FATAL_ERROR; } - return SSL_SUCCESS; + return SSL_SUCCESS; default : return SSL_FATAL_ERROR; // unkown state @@ -331,27 +344,36 @@ int SSL_accept(SSL* ssl) if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ)) ssl->SetError(no_error); + if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { + + ssl->SetError(no_error); + ssl->SendWriteBuffered(); + if (!ssl->GetError()) + ssl->useStates().UseAccept() = + AcceptState(ssl->getStates().GetAccept() + 1); + } + switch (ssl->getStates().GetAccept()) { case ACCEPT_BEGIN : - processReply(*ssl); + processReply(*ssl); if (!ssl->GetError()) ssl->useStates().UseAccept() = ACCEPT_FIRST_REPLY_DONE; case ACCEPT_FIRST_REPLY_DONE : - sendServerHello(*ssl); + sendServerHello(*ssl); - if (!ssl->getSecurity().get_resuming()) { - sendCertificate(*ssl); + if (!ssl->getSecurity().get_resuming()) { + sendCertificate(*ssl); - if (ssl->getSecurity().get_connection().send_server_key_) - sendServerKeyExchange(*ssl); + if (ssl->getSecurity().get_connection().send_server_key_) + sendServerKeyExchange(*ssl); - if(ssl->getCrypto().get_certManager().verifyPeer()) - sendCertificateRequest(*ssl); + if(ssl->getCrypto().get_certManager().verifyPeer()) + sendCertificateRequest(*ssl); - sendServerHelloDone(*ssl); - ssl->flushBuffer(); + sendServerHelloDone(*ssl); + ssl->flushBuffer(); } if (!ssl->GetError()) @@ -359,40 +381,40 @@ int SSL_accept(SSL* ssl) case SERVER_HELLO_DONE : if (!ssl->getSecurity().get_resuming()) { - while (ssl->getStates().getServer() < clientFinishedComplete) { - if (ssl->GetError()) break; - processReply(*ssl); + while (ssl->getStates().getServer() < clientFinishedComplete) { + if (ssl->GetError()) break; + processReply(*ssl); + } } - } if (!ssl->GetError()) ssl->useStates().UseAccept() = ACCEPT_SECOND_REPLY_DONE; case ACCEPT_SECOND_REPLY_DONE : - sendChangeCipher(*ssl); - sendFinished(*ssl, server_end); - ssl->flushBuffer(); + sendChangeCipher(*ssl); + sendFinished(*ssl, server_end); + ssl->flushBuffer(); if (!ssl->GetError()) ssl->useStates().UseAccept() = ACCEPT_FINISHED_DONE; case ACCEPT_FINISHED_DONE : - if (ssl->getSecurity().get_resuming()) { - while (ssl->getStates().getServer() < clientFinishedComplete) { - if (ssl->GetError()) break; - processReply(*ssl); - } - } + if (ssl->getSecurity().get_resuming()) { + while (ssl->getStates().getServer() < clientFinishedComplete) { + if (ssl->GetError()) break; + processReply(*ssl); + } + } if (!ssl->GetError()) ssl->useStates().UseAccept() = ACCEPT_THIRD_REPLY_DONE; case ACCEPT_THIRD_REPLY_DONE : - ssl->useLog().ShowTCP(ssl->getSocket().get_fd()); + ssl->useLog().ShowTCP(ssl->getSocket().get_fd()); if (ssl->GetError()) { GetErrors().Add(ssl->GetError()); - return SSL_FATAL_ERROR; + return SSL_FATAL_ERROR; } - return SSL_SUCCESS; + return SSL_SUCCESS; default: return SSL_FATAL_ERROR; // unknown state @@ -1097,7 +1119,6 @@ int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt, ivLeft -= store; } } - assert(keyOutput == (keyLen + ivLen)); return keyOutput; } diff --git a/extra/yassl/src/yassl.cpp b/extra/yassl/src/yassl.cpp index 815277ce6f3..99a1da5371b 100644 --- a/extra/yassl/src/yassl.cpp +++ b/extra/yassl/src/yassl.cpp @@ -69,13 +69,13 @@ void SetUpBase(Base& base, ConnectionEnd end, SOCKET_T s) if (base.ca_) if (SSL_CTX_load_verify_locations(base.ctx_, - base.ca_, 0) != SSL_SUCCESS) assert(0); + base.ca_, 0) != SSL_SUCCESS) throw(0); if (base.cert_) if (SSL_CTX_use_certificate_file(base.ctx_, - base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0); + base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0); if (base.key_) if (SSL_CTX_use_PrivateKey_file(base.ctx_, base.key_, - SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0); + SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0); if (end == server_end) SetDH(base); diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index 2ff30f436f5..e55c10c68c0 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -31,6 +31,11 @@ #pragma warning(disable: 4996) #endif +#ifdef _MSC_VER + // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy + #pragma warning(disable: 4996) +#endif + namespace yaSSL { @@ -59,8 +64,9 @@ void SetErrorString(unsigned long error, char* buffer) { using namespace TaoCrypt; const int max = MAX_ERROR_SZ; // shorthand + int localError = error; // errors from a few enums - switch ((int) error) { + switch (localError) { // yaSSL proper errors case range_error : @@ -121,7 +127,7 @@ void SetErrorString(unsigned long error, char* buffer) case certificate_error : strncpy(buffer, "unable to proccess cerificate", max); - break; + break; case privateKey_error : strncpy(buffer, "unable to proccess private key, bad format", max); @@ -130,7 +136,7 @@ void SetErrorString(unsigned long error, char* buffer) case badVersion_error : strncpy(buffer, "protocol version mismatch", max); break; - + case compress_error : strncpy(buffer, "compression error", max); break; @@ -148,6 +154,10 @@ void SetErrorString(unsigned long error, char* buffer) strncpy(buffer, "the read operation would block", max); break; + case SSL_ERROR_WANT_WRITE : + strncpy(buffer, "the write operation would block", max); + break; + case CERTFICATE_ERROR : strncpy(buffer, "Unable to verify certificate", max); break; diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 15d7ec5fb21..c0ef23a4e94 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2010, Oracle and/or its affiliates + Copyright (c) 2005, 2012, Oracle and/or its affiliates This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -117,7 +117,7 @@ void ClientDiffieHellmanPublic::build(SSL& ssl) if (*dhClient.get_agreedKey() == 0) ssl.set_preMaster(dhClient.get_agreedKey() + 1, keyLength - 1); else - ssl.set_preMaster(dhClient.get_agreedKey(), keyLength); + ssl.set_preMaster(dhClient.get_agreedKey(), keyLength); } @@ -135,8 +135,7 @@ void DH_Server::build(SSL& ssl) mySTL::auto_ptr<Auth> auth; const CertManager& cert = ssl.getCrypto().get_certManager(); - if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) - { + if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) { if (cert.get_keyType() != rsa_sa_algo) { ssl.SetError(privateKey_error); return; @@ -925,8 +924,6 @@ Data::Data(uint16 len, opaque* b) void Data::SetData(uint16 len, const opaque* buffer) { - assert(write_buffer_ == 0); - length_ = len; write_buffer_ = buffer; } @@ -992,6 +989,11 @@ void Data::Process(input_buffer& input, SSL& ssl) int dataSz = msgSz - ivExtra - digestSz - pad - padSz; opaque verify[SHA_LEN]; + if (dataSz < 0) { + ssl.SetError(bad_input); + return; + } + const byte* rawData = input.get_buffer() + input.get_current(); // read data @@ -1006,10 +1008,10 @@ void Data::Process(input_buffer& input, SSL& ssl) tmp.get_buffer(), tmp.get_size())); } else { - input_buffer* data; - ssl.addData(data = NEW_YS input_buffer(dataSz)); - input.read(data->get_buffer(), dataSz); - data->add_size(dataSz); + input_buffer* data; + ssl.addData(data = NEW_YS input_buffer(dataSz)); + input.read(data->get_buffer(), dataSz); + data->add_size(dataSz); } if (ssl.isTLS()) @@ -1085,19 +1087,37 @@ void Certificate::Process(input_buffer& input, SSL& ssl) uint32 list_sz; byte tmp[3]; + if (input.get_remaining() < sizeof(tmp)) { + ssl.SetError(YasslError(bad_input)); + return; + } tmp[0] = input[AUTO]; tmp[1] = input[AUTO]; tmp[2] = input[AUTO]; c24to32(tmp, list_sz); + + if (list_sz > (uint)MAX_RECORD_SIZE) { // sanity check + ssl.SetError(YasslError(bad_input)); + return; + } while (list_sz) { // cert size uint32 cert_sz; + + if (input.get_remaining() < sizeof(tmp)) { + ssl.SetError(YasslError(bad_input)); + return; + } tmp[0] = input[AUTO]; tmp[1] = input[AUTO]; tmp[2] = input[AUTO]; c24to32(tmp, cert_sz); + if (cert_sz > (uint)MAX_RECORD_SIZE || input.get_remaining() < cert_sz){ + ssl.SetError(YasslError(bad_input)); + return; + } x509* myCert; cm.AddPeerCert(myCert = NEW_YS x509(cert_sz)); input.read(myCert->use_buffer(), myCert->get_length()); @@ -1294,7 +1314,7 @@ void ServerHello::Process(input_buffer&, SSL& ssl) ssl.set_pending(cipher_suite_[1]); ssl.set_random(random_, server_end); if (id_len_) - ssl.set_sessionID(session_id_); + ssl.set_sessionID(session_id_); else ssl.useSecurity().use_connection().sessionID_Set_ = false; @@ -1422,7 +1442,7 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello) if (hello.id_len_) input.read(hello.session_id_, ID_LEN); // Suites - byte tmp[2]; + byte tmp[2]; uint16 len; tmp[0] = input[AUTO]; tmp[1] = input[AUTO]; @@ -1430,8 +1450,8 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello) hello.suite_len_ = min(len, static_cast<uint16>(MAX_SUITE_SZ)); input.read(hello.cipher_suites_, hello.suite_len_); - if (len > hello.suite_len_) // ignore extra suites - input.set_current(input.get_current() + len - hello.suite_len_); + if (len > hello.suite_len_) // ignore extra suites + input.set_current(input.get_current() + len - hello.suite_len_); // Compression hello.comp_len_ = input[AUTO]; @@ -1495,8 +1515,9 @@ void ClientHello::Process(input_buffer&, SSL& ssl) if (ssl.GetMultiProtocol()) { // SSLv23 support if (ssl.isTLS() && client_version_.minor_ < 1) { // downgrade to SSLv3 - ssl.useSecurity().use_connection().TurnOffTLS(); - ProtocolVersion pv = ssl.getSecurity().get_connection().version_; + ssl.useSecurity().use_connection().TurnOffTLS(); + + ProtocolVersion pv = ssl.getSecurity().get_connection().version_; bool removeDH = ssl.getSecurity().get_parms().removeDH_; bool removeRSA = false; bool removeDSA = false; @@ -1510,7 +1531,7 @@ void ClientHello::Process(input_buffer&, SSL& ssl) // reset w/ SSL suites ssl.useSecurity().use_parms().SetSuites(pv, removeDH, removeRSA, removeDSA); - } + } else if (ssl.isTLSv1_1() && client_version_.minor_ == 1) // downgrade to TLSv1, but use same suites ssl.useSecurity().use_connection().TurnOffTLS1_1(); @@ -1541,6 +1562,7 @@ void ClientHello::Process(input_buffer&, SSL& ssl) ssl.set_session(session); ssl.useSecurity().set_resuming(true); ssl.matchSuite(session->GetSuite(), SUITE_LEN); + if (ssl.GetError()) return; ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); ssl.set_masterSecret(session->GetSecret()); @@ -2037,7 +2059,7 @@ void Finished::Process(input_buffer& input, SSL& ssl) // verify hashes const Finished& verify = ssl.getHashes().get_verify(); uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ; - + input.read(hashes_.md5_, finishedSz); if (memcmp(&hashes_, &verify.hashes_, finishedSz)) { diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 3d553e37337..65e17b01544 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2011, Oracle and/or its affiliates + Copyright (c) 2005, 2012, Oracle and/or its affiliates This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -308,8 +308,9 @@ SSL::SSL(SSL_CTX* ctx) SetError(YasslError(err)); return; } - else if (serverSide && !(ctx->GetCiphers().setSuites_)) { + else if (serverSide && ctx->GetCiphers().setSuites_ == 0) { // remove RSA or DSA suites depending on cert key type + // but don't override user sets ProtocolVersion pv = secure_.get_connection().version_; bool removeDH = secure_.use_parms().removeDH_; @@ -1128,8 +1129,28 @@ void SSL::flushBuffer() void SSL::Send(const byte* buffer, uint sz) { - if (socket_.send(buffer, sz) != sz) - SetError(send_error); + unsigned int sent = 0; + + if (socket_.send(buffer, sz, sent) != sz) { + if (socket_.WouldBlock()) { + buffers_.SetOutput(NEW_YS output_buffer(sz - sent, buffer + sent, + sz - sent)); + SetError(YasslError(SSL_ERROR_WANT_WRITE)); + } + else + SetError(send_error); + } +} + + +void SSL::SendWriteBuffered() +{ + output_buffer* out = buffers_.TakeOutput(); + + if (out) { + mySTL::auto_ptr<output_buffer> tmp(out); + Send(out->get_buffer(), out->get_size()); + } } @@ -1291,7 +1312,6 @@ void SSL::matchSuite(const opaque* peer, uint length) if (secure_.use_parms().suites_[i] == peer[j]) { secure_.use_parms().suite_[0] = 0x00; secure_.use_parms().suite_[1] = peer[j]; - return; } @@ -1435,7 +1455,6 @@ void SSL::addBuffer(output_buffer* b) void SSL_SESSION::CopyX509(X509* x) { - assert(peerX509_ == 0); if (x == 0) return; X509_NAME* issuer = x->GetIssuer(); @@ -2232,7 +2251,7 @@ Hashes& sslHashes::use_certVerify() } -Buffers::Buffers() : rawInput_(0) +Buffers::Buffers() : prevSent(0), plainSz(0), rawInput_(0), output_(0) {} @@ -2243,12 +2262,18 @@ Buffers::~Buffers() STL::for_each(dataList_.begin(), dataList_.end(), del_ptr_zero()) ; ysDelete(rawInput_); + ysDelete(output_); +} + + +void Buffers::SetOutput(output_buffer* ob) +{ + output_ = ob; } void Buffers::SetRawInput(input_buffer* ib) { - assert(rawInput_ == 0); rawInput_ = ib; } @@ -2262,6 +2287,15 @@ input_buffer* Buffers::TakeRawInput() } +output_buffer* Buffers::TakeOutput() +{ + output_buffer* ret = output_; + output_ = 0; + + return ret; +} + + const Buffers::inputList& Buffers::getData() const { return dataList_; @@ -2536,14 +2570,12 @@ ASN1_STRING* StringHolder::GetString() // these versions should never get called int Compress(const byte* in, int sz, input_buffer& buffer) { - assert(0); return -1; } int DeCompress(input_buffer& in, int sz, input_buffer& out) { - assert(0); return -1; } |