// send finished void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) { if (ssl.GetError()) return; Finished fin; buildFinished(ssl, fin, side == client_end ? client : server); mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); cipherFinished(ssl, fin, *out.get()); // hashes handshake if (ssl.getSecurity().get_resuming()) { if (side == server_end) buildFinished(ssl, ssl.useHashes().use_verify(), client); // client } else { if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) GetSessions().add(ssl); // store session if (side == client_end) buildFinished(ssl, ssl.useHashes().use_verify(), server); // server } ssl.useSecurity().use_connection().CleanMaster(); if (buffer == buffered) ssl.addBuffer(out.release()); else ssl.Send(out->get_buffer(), out->get_size()); }
// send server hello void sendServerHello(SSL& ssl, BufferOutput buffer) { if (ssl.getSecurity().get_resuming()) ssl.verifyState(clientKeyExchangeComplete); else ssl.verifyState(clientHelloComplete); if (ssl.GetError()) return; ServerHello sh(ssl.getSecurity().get_connection().version_, ssl.getSecurity().get_connection().compression_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); buildServerHello(ssl, sh); ssl.set_random(sh.get_random(), server_end); buildHeaders(ssl, hsHeader, rlHeader, sh); buildOutput(*out.get(), rlHeader, hsHeader, sh); hashHandShake(ssl, *out.get()); if (buffer == buffered) ssl.addBuffer(out.release()); else ssl.Send(out->get_buffer(), out->get_size()); }
// send alert int sendAlert(SSL& ssl, const Alert& alert) { output_buffer out; buildAlert(ssl, out, alert); ssl.Send(out.get_buffer(), out.get_size()); return alert.get_length(); }
// 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; for (;;) { int len = min(sz - sent, MAX_RECORD_SIZE); output_buffer out; input_buffer tmp; Data data; if (sent == sz) break; if (ssl.CompressionOn()) { if (Compress(static_cast<const opaque*>(buffer) + sent, len, tmp) == -1) { ssl.SetError(compress_error); return -1; } data.SetData(tmp.get_size(), tmp.get_buffer()); } else data.SetData(len, static_cast<const opaque*>(buffer) + sent); buildMessage(ssl, out, data); ssl.Send(out.get_buffer(), out.get_size()); if (ssl.GetError()) { if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { ssl.useBuffers().plainSz = len; ssl.useBuffers().prevSent = sent; } return -1; } sent += len; } ssl.useLog().ShowData(sent, true); return sent; }
// send certificate void sendCertificate(SSL& ssl, BufferOutput buffer) { if (ssl.GetError()) return; Certificate cert(ssl.getCrypto().get_certManager().get_cert()); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); buildHeaders(ssl, hsHeader, rlHeader, cert); buildOutput(*out.get(), rlHeader, hsHeader, cert); hashHandShake(ssl, *out.get()); if (buffer == buffered) ssl.addBuffer(out.release()); else ssl.Send(out->get_buffer(), out->get_size()); }
// send server hello done void sendServerHelloDone(SSL& ssl, BufferOutput buffer) { if (ssl.GetError()) return; ServerHelloDone shd; RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); buildHeaders(ssl, hsHeader, rlHeader, shd); buildOutput(*out.get(), rlHeader, hsHeader, shd); hashHandShake(ssl, *out.get()); if (buffer == buffered) ssl.addBuffer(out.release()); else ssl.Send(out->get_buffer(), out->get_size()); }
// send client_hello, no buffering void sendClientHello(SSL& ssl) { ssl.verifyState(serverNull); if (ssl.GetError()) return; ClientHello ch(ssl.getSecurity().get_connection().version_, ssl.getSecurity().get_connection().compression_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; output_buffer out; buildClientHello(ssl, ch); ssl.set_random(ch.get_random(), client_end); buildHeaders(ssl, hsHeader, rlHeader, ch); buildOutput(out, rlHeader, hsHeader, ch); hashHandShake(ssl, out); ssl.Send(out.get_buffer(), out.get_size()); }
// send change cipher void sendChangeCipher(SSL& ssl, BufferOutput buffer) { if (ssl.getSecurity().get_parms().entity_ == server_end) if (ssl.getSecurity().get_resuming()) ssl.verifyState(clientKeyExchangeComplete); else ssl.verifyState(clientFinishedComplete); if (ssl.GetError()) return; ChangeCipherSpec ccs; RecordLayerHeader rlHeader; buildHeader(ssl, rlHeader, ccs); mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); buildOutput(*out.get(), rlHeader, ccs); if (buffer == buffered) ssl.addBuffer(out.release()); else ssl.Send(out->get_buffer(), out->get_size()); }
// send client key exchange void sendClientKeyExchange(SSL& ssl, BufferOutput buffer) { ssl.verifyState(serverHelloDoneComplete); if (ssl.GetError()) return; ClientKeyExchange ck(ssl); ck.build(ssl); ssl.makeMasterSecret(); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); buildHeaders(ssl, hsHeader, rlHeader, ck); buildOutput(*out.get(), rlHeader, hsHeader, ck); hashHandShake(ssl, *out.get()); if (buffer == buffered) ssl.addBuffer(out.release()); else ssl.Send(out->get_buffer(), out->get_size()); }