26 #include "runtime.hpp"
27 #include "handshake.hpp"
28 #include "yassl_int.hpp"
36 void buildClientHello(SSL& ssl, ClientHello& hello)
39 ssl.useSecurity().use_connection().chVersion_ = hello.client_version_;
41 ssl.getCrypto().get_random().Fill(hello.random_, RAN_LEN);
42 if (ssl.getSecurity().get_resuming()) {
43 hello.id_len_ = ID_LEN;
44 memcpy(hello.session_id_, ssl.getSecurity().get_resume().GetID(),
49 hello.suite_len_ = ssl.getSecurity().get_parms().suites_size_;
50 memcpy(hello.cipher_suites_, ssl.getSecurity().get_parms().suites_,
54 hello.set_length(
sizeof(ProtocolVersion) +
56 hello.id_len_ +
sizeof(hello.id_len_) +
57 hello.suite_len_ +
sizeof(hello.suite_len_) +
58 hello.comp_len_ +
sizeof(hello.comp_len_));
63 void buildServerHello(SSL& ssl, ServerHello& hello)
65 if (ssl.getSecurity().get_resuming()) {
66 memcpy(hello.random_,ssl.getSecurity().get_connection().server_random_,
68 memcpy(hello.session_id_, ssl.getSecurity().get_resume().GetID(),
72 ssl.getCrypto().get_random().Fill(hello.random_, RAN_LEN);
73 ssl.getCrypto().get_random().Fill(hello.session_id_, ID_LEN);
75 hello.id_len_ = ID_LEN;
76 ssl.set_sessionID(hello.session_id_);
78 hello.cipher_suite_[0] = ssl.getSecurity().get_parms().suite_[0];
79 hello.cipher_suite_[1] = ssl.getSecurity().get_parms().suite_[1];
80 hello.compression_method_ = hello.compression_method_;
82 hello.set_length(
sizeof(ProtocolVersion) + RAN_LEN + ID_LEN +
83 sizeof(hello.id_len_) + SUITE_LEN + SIZEOF_ENUM);
88 void hashHandShake(SSL& ssl,
const input_buffer& input, uint sz)
90 const opaque* buffer = input.get_buffer() + input.get_current() -
92 sz += HANDSHAKE_HEADER;
93 ssl.useHashes().use_MD5().update(buffer, sz);
94 ssl.useHashes().use_SHA().update(buffer, sz);
102 void buildOutput(output_buffer& buffer,
const RecordLayerHeader& rlHdr,
105 buffer.allocate(RECORD_HEADER + rlHdr.length_);
106 buffer << rlHdr << msg;
111 void buildOutput(output_buffer& buffer,
const RecordLayerHeader& rlHdr,
112 const HandShakeHeader& hsHdr,
const HandShakeBase& shake)
114 buffer.allocate(RECORD_HEADER + rlHdr.length_);
115 buffer << rlHdr << hsHdr << shake;
120 void buildHeader(SSL& ssl, RecordLayerHeader& rlHeader,
const Message& msg)
122 ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
123 rlHeader.type_ = msg.get_type();
124 rlHeader.version_.major_ = pv.major_;
125 rlHeader.version_.minor_ = pv.minor_;
126 rlHeader.length_ = msg.get_length();
131 void buildHeaders(SSL& ssl, HandShakeHeader& hsHeader,
132 RecordLayerHeader& rlHeader,
const HandShakeBase& shake)
134 int sz = shake.get_length();
136 hsHeader.set_type(shake.get_type());
137 hsHeader.set_length(sz);
139 ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
140 rlHeader.type_ = handshake;
141 rlHeader.version_.major_ = pv.major_;
142 rlHeader.version_.minor_ = pv.minor_;
143 rlHeader.length_ = sz + HANDSHAKE_HEADER;
148 void hashHandShake(SSL& ssl,
const output_buffer& output,
bool removeIV =
false)
150 uint sz = output.get_size() - RECORD_HEADER;
152 const opaque* buffer = output.get_buffer() + RECORD_HEADER;
155 uint blockSz = ssl.getCrypto().get_cipher().get_blockSize();
160 ssl.useHashes().use_MD5().update(buffer, sz);
161 ssl.useHashes().use_SHA().update(buffer, sz);
166 void buildMD5(SSL& ssl, Finished& fin,
const opaque* sender)
169 opaque md5_result[MD5_LEN];
170 opaque md5_inner[SIZEOF_SENDER + SECRET_LEN + PAD_MD5];
171 opaque md5_outer[SECRET_LEN + PAD_MD5 + MD5_LEN];
173 const opaque* master_secret =
174 ssl.getSecurity().get_connection().master_secret_;
177 memcpy(md5_inner, sender, SIZEOF_SENDER);
178 memcpy(&md5_inner[SIZEOF_SENDER], master_secret, SECRET_LEN);
179 memcpy(&md5_inner[SIZEOF_SENDER + SECRET_LEN], PAD1, PAD_MD5);
181 ssl.useHashes().use_MD5().get_digest(md5_result, md5_inner,
185 memcpy(md5_outer, master_secret, SECRET_LEN);
186 memcpy(&md5_outer[SECRET_LEN], PAD2, PAD_MD5);
187 memcpy(&md5_outer[SECRET_LEN + PAD_MD5], md5_result, MD5_LEN);
189 ssl.useHashes().use_MD5().get_digest(fin.set_md5(), md5_outer,
195 void buildSHA(SSL& ssl, Finished& fin,
const opaque* sender)
198 opaque sha_result[SHA_LEN];
199 opaque sha_inner[SIZEOF_SENDER + SECRET_LEN + PAD_SHA];
200 opaque sha_outer[SECRET_LEN + PAD_SHA + SHA_LEN];
202 const opaque* master_secret =
203 ssl.getSecurity().get_connection().master_secret_;
206 memcpy(sha_inner, sender, SIZEOF_SENDER);
207 memcpy(&sha_inner[SIZEOF_SENDER], master_secret, SECRET_LEN);
208 memcpy(&sha_inner[SIZEOF_SENDER + SECRET_LEN], PAD1, PAD_SHA);
210 ssl.useHashes().use_SHA().get_digest(sha_result, sha_inner,
214 memcpy(sha_outer, master_secret, SECRET_LEN);
215 memcpy(&sha_outer[SECRET_LEN], PAD2, PAD_SHA);
216 memcpy(&sha_outer[SECRET_LEN + PAD_SHA], sha_result, SHA_LEN);
218 ssl.useHashes().use_SHA().get_digest(fin.set_sha(), sha_outer,
224 static int sanity_check_message(SSL& ssl, uint msgSz)
228 if (ssl.getSecurity().get_parms().cipher_type_ ==
block) {
229 uint blockSz = ssl.getCrypto().get_cipher().get_blockSize();
233 minSz = ssl.getSecurity().get_parms().hash_size_ + 1;
241 minSz = ssl.getSecurity().get_parms().hash_size_;
252 void decrypt_message(SSL& ssl, input_buffer& input, uint sz)
254 input_buffer plain(sz);
255 opaque* cipher = input.get_buffer() + input.get_current();
257 if (sanity_check_message(ssl, sz) != 0) {
258 ssl.SetError(sanityCipher_error);
262 ssl.useCrypto().use_cipher().decrypt(plain.get_buffer(), cipher, sz);
263 memcpy(cipher, plain.get_buffer(), sz);
264 ssl.useSecurity().use_parms().encrypt_size_ = sz;
267 input.set_current(input.get_current() +
268 ssl.getCrypto().get_cipher().get_blockSize());
273 output_buffer& operator<<(output_buffer& output,
const input_buffer& input)
275 output.write(input.get_buffer(), input.get_size());
281 void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output)
283 uint digestSz = ssl.getCrypto().get_digest().get_digestSize();
284 uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ;
285 uint sz = RECORD_HEADER + HANDSHAKE_HEADER + finishedSz + digestSz;
287 uint blockSz = ssl.getCrypto().get_cipher().get_blockSize();
289 if (ssl.getSecurity().get_parms().cipher_type_ ==
block) {
293 pad = (sz - RECORD_HEADER) % blockSz;
298 RecordLayerHeader rlHeader;
299 HandShakeHeader hsHeader;
300 buildHeaders(ssl, hsHeader, rlHeader, fin);
301 rlHeader.length_ = sz - RECORD_HEADER;
304 if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_==
block){
305 iv.allocate(blockSz);
306 ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz);
307 iv.add_size(blockSz);
309 uint ivSz = iv.get_size();
311 output << rlHeader << iv << hsHeader << fin;
313 hashHandShake(ssl, output, ssl.isTLSv1_1() ?
true :
false);
314 opaque digest[SHA_LEN];
316 TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz,
317 output.get_size() - RECORD_HEADER - ivSz, handshake);
319 hmac(ssl, digest, output.get_buffer() + RECORD_HEADER,
320 output.get_size() - RECORD_HEADER, handshake);
321 output.write(digest, digestSz);
323 if (ssl.getSecurity().get_parms().cipher_type_ ==
block)
324 for (uint
i = 0;
i <= pad;
i++) output[AUTO] = pad;
326 input_buffer cipher(rlHeader.length_);
327 ssl.useCrypto().use_cipher().encrypt(cipher.get_buffer(),
328 output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER);
329 output.set_current(RECORD_HEADER);
330 output.write(cipher.get_buffer(), cipher.get_capacity());
335 void buildMessage(SSL& ssl, output_buffer& output,
const Message& msg)
337 uint digestSz = ssl.getCrypto().get_digest().get_digestSize();
338 uint sz = RECORD_HEADER + msg.get_length() + digestSz;
340 uint blockSz = ssl.getCrypto().get_cipher().get_blockSize();
342 if (ssl.getSecurity().get_parms().cipher_type_ ==
block) {
346 pad = (sz - RECORD_HEADER) % blockSz;
351 RecordLayerHeader rlHeader;
352 buildHeader(ssl, rlHeader, msg);
353 rlHeader.length_ = sz - RECORD_HEADER;
356 if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_==
block){
357 iv.allocate(blockSz);
358 ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz);
359 iv.add_size(blockSz);
362 uint ivSz = iv.get_size();
364 output << rlHeader << iv << msg;
366 opaque digest[SHA_LEN];
368 TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz,
369 output.get_size() - RECORD_HEADER - ivSz, msg.get_type());
371 hmac(ssl, digest, output.get_buffer() + RECORD_HEADER,
372 output.get_size() - RECORD_HEADER, msg.get_type());
373 output.write(digest, digestSz);
375 if (ssl.getSecurity().get_parms().cipher_type_ ==
block)
376 for (uint
i = 0;
i <= pad;
i++) output[AUTO] = pad;
378 input_buffer cipher(rlHeader.length_);
379 ssl.useCrypto().use_cipher().encrypt(cipher.get_buffer(),
380 output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER);
381 output.set_current(RECORD_HEADER);
382 output.write(cipher.get_buffer(), cipher.get_capacity());
387 void buildAlert(SSL& ssl, output_buffer& output,
const Alert& alert)
389 if (ssl.getSecurity().get_parms().pending_ ==
false)
390 buildMessage(ssl, output, alert);
392 RecordLayerHeader rlHeader;
393 buildHeader(ssl, rlHeader, alert);
394 buildOutput(output, rlHeader, alert);
400 void buildFinishedTLS(SSL& ssl, Finished& fin,
const opaque* sender)
402 opaque handshake_hash[FINISHED_SZ];
404 ssl.useHashes().use_MD5().get_digest(handshake_hash);
405 ssl.useHashes().use_SHA().get_digest(&handshake_hash[MD5_LEN]);
408 if ( strncmp((
const char*)sender, (
const char*)client, SIZEOF_SENDER) == 0)
413 PRF(fin.set_md5(), TLS_FINISHED_SZ,
414 ssl.getSecurity().get_connection().master_secret_, SECRET_LEN,
415 side, FINISHED_LABEL_SZ,
416 handshake_hash, FINISHED_SZ);
418 fin.set_length(TLS_FINISHED_SZ);
423 void p_hash(output_buffer& result,
const output_buffer& secret,
424 const output_buffer& seed, MACAlgorithm hash)
426 uint len = hash == md5 ? MD5_LEN : SHA_LEN;
427 uint times = result.get_capacity() / len;
428 uint lastLen = result.get_capacity() % len;
429 opaque previous[SHA_LEN];
430 opaque current[SHA_LEN];
433 if (lastLen) times += 1;
436 hmac.reset(NEW_YS HMAC_MD5(secret.get_buffer(), secret.get_size()));
438 hmac.reset(NEW_YS HMAC_SHA(secret.get_buffer(), secret.get_size()));
440 hmac->get_digest(previous, seed.get_buffer(), seed.get_size());
441 uint lastTime = times - 1;
443 for (uint
i = 0;
i < times;
i++) {
444 hmac->update(previous, len);
445 hmac->get_digest(current, seed.get_buffer(), seed.get_size());
447 if (lastLen && (
i == lastTime))
448 result.write(current, lastLen);
450 result.write(current, len);
452 hmac->get_digest(previous, previous, len);
459 void get_xor(byte *digest, uint digLen, output_buffer& md5,
462 for (uint
i = 0;
i < digLen;
i++)
463 digest[
i] = md5[AUTO] ^ sha[AUTO];
468 void buildMD5_CertVerify(SSL& ssl, byte* digest)
470 opaque md5_result[MD5_LEN];
471 opaque md5_inner[SECRET_LEN + PAD_MD5];
472 opaque md5_outer[SECRET_LEN + PAD_MD5 + MD5_LEN];
474 const opaque* master_secret =
475 ssl.getSecurity().get_connection().master_secret_;
478 memcpy(md5_inner, master_secret, SECRET_LEN);
479 memcpy(&md5_inner[SECRET_LEN], PAD1, PAD_MD5);
481 ssl.useHashes().use_MD5().get_digest(md5_result, md5_inner,
485 memcpy(md5_outer, master_secret, SECRET_LEN);
486 memcpy(&md5_outer[SECRET_LEN], PAD2, PAD_MD5);
487 memcpy(&md5_outer[SECRET_LEN + PAD_MD5], md5_result, MD5_LEN);
489 ssl.useHashes().use_MD5().get_digest(digest, md5_outer,
sizeof(md5_outer));
494 void buildSHA_CertVerify(SSL& ssl, byte* digest)
496 opaque sha_result[SHA_LEN];
497 opaque sha_inner[SECRET_LEN + PAD_SHA];
498 opaque sha_outer[SECRET_LEN + PAD_SHA + SHA_LEN];
500 const opaque* master_secret =
501 ssl.getSecurity().get_connection().master_secret_;
504 memcpy(sha_inner, master_secret, SECRET_LEN);
505 memcpy(&sha_inner[SECRET_LEN], PAD1, PAD_SHA);
507 ssl.useHashes().use_SHA().get_digest(sha_result, sha_inner,
511 memcpy(sha_outer, master_secret, SECRET_LEN);
512 memcpy(&sha_outer[SECRET_LEN], PAD2, PAD_SHA);
513 memcpy(&sha_outer[SECRET_LEN + PAD_SHA], sha_result, SHA_LEN);
515 ssl.useHashes().use_SHA().get_digest(digest, sha_outer,
sizeof(sha_outer));
523 void ProcessOldClientHello(input_buffer& input, SSL& ssl)
525 if (input.get_remaining() < 2) {
526 ssl.SetError(bad_input);
529 byte b0 = input[AUTO];
530 byte b1 = input[AUTO];
532 uint16 sz = ((b0 & 0x7f) << 8) | b1;
534 if (sz > input.get_remaining()) {
535 ssl.SetError(bad_input);
540 const opaque* buffer = input.get_buffer() + input.get_current();
541 ssl.useHashes().use_MD5().update(buffer, sz);
542 ssl.useHashes().use_SHA().update(buffer, sz);
547 ch.client_version_.major_ = input[AUTO];
548 ch.client_version_.minor_ = input[AUTO];
552 input.read(len,
sizeof(len));
553 ato16(len, ch.suite_len_);
555 input.read(len,
sizeof(len));
557 ato16(len, sessionLen);
558 ch.id_len_ = sessionLen;
560 input.read(len,
sizeof(len));
562 ato16(len, randomLen);
564 if (ch.suite_len_ > MAX_SUITE_SZ || sessionLen > ID_LEN ||
565 randomLen > RAN_LEN) {
566 ssl.SetError(bad_input);
571 for (uint16
i = 0;
i < ch.suite_len_;
i += 3) {
572 byte first = input[AUTO];
574 input.read(len, SUITE_LEN);
576 input.read(&ch.cipher_suites_[j], SUITE_LEN);
583 input.read(ch.session_id_, ch.id_len_);
585 if (randomLen < RAN_LEN)
586 memset(ch.random_, 0, RAN_LEN - randomLen);
587 input.read(&ch.random_[RAN_LEN - randomLen], randomLen);
590 ch.Process(input, ssl);
595 void buildFinished(SSL& ssl, Finished& fin,
const opaque* sender)
598 MD5 md5(ssl.getHashes().get_MD5());
599 SHA sha(ssl.getHashes().get_SHA());
602 buildFinishedTLS(ssl, fin, sender);
604 buildMD5(ssl, fin, sender);
605 buildSHA(ssl, fin, sender);
609 ssl.useHashes().use_MD5() = md5;
610 ssl.useHashes().use_SHA() = sha;
618 void hmac(SSL& ssl, byte* digest,
const byte* buffer, uint sz,
619 ContentType content,
bool verify)
621 Digest& mac = ssl.useCrypto().use_digest();
622 opaque inner[SHA_LEN + PAD_MD5 + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ];
623 opaque outer[SHA_LEN + PAD_MD5 + SHA_LEN];
624 opaque result[SHA_LEN];
625 uint digestSz = mac.get_digestSize();
626 uint padSz = mac.get_padSize();
627 uint innerSz = digestSz + padSz + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ;
628 uint outerSz = digestSz + padSz + digestSz;
631 const opaque* mac_secret = ssl.get_macSecret(verify);
632 opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
633 opaque length[LENGTH_SZ];
635 c32toa(ssl.get_SEQIncrement(verify), &seq[
sizeof(uint32)]);
638 memcpy(inner, mac_secret, digestSz);
639 memcpy(&inner[digestSz], PAD1, padSz);
640 memcpy(&inner[digestSz + padSz], seq, SEQ_SZ);
641 inner[digestSz + padSz + SEQ_SZ] = content;
642 memcpy(&inner[digestSz + padSz + SEQ_SZ + SIZEOF_ENUM], length, LENGTH_SZ);
644 mac.update(inner, innerSz);
645 mac.get_digest(result, buffer, sz);
648 memcpy(outer, mac_secret, digestSz);
649 memcpy(&outer[digestSz], PAD2, padSz);
650 memcpy(&outer[digestSz + padSz], result, digestSz);
652 mac.get_digest(digest, outer, outerSz);
657 void TLS_hmac(SSL& ssl, byte* digest,
const byte* buffer, uint sz,
658 ContentType content,
bool verify)
661 opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 };
662 opaque length[LENGTH_SZ];
663 opaque inner[SIZEOF_ENUM + VERSION_SZ + LENGTH_SZ];
666 c32toa(ssl.get_SEQIncrement(verify), &seq[
sizeof(uint32)]);
668 MACAlgorithm algo = ssl.getSecurity().get_parms().mac_algorithm_;
671 hmac.reset(NEW_YS HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN));
672 else if (algo == rmd)
673 hmac.reset(NEW_YS HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN));
675 hmac.reset(NEW_YS HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN));
677 hmac->update(seq, SEQ_SZ);
679 inner[SIZEOF_ENUM] = ssl.getSecurity().get_connection().version_.major_;
680 inner[SIZEOF_ENUM + SIZEOF_ENUM] =
681 ssl.getSecurity().get_connection().version_.minor_;
682 memcpy(&inner[SIZEOF_ENUM + VERSION_SZ], length, LENGTH_SZ);
683 hmac->update(inner,
sizeof(inner));
684 hmac->get_digest(digest, buffer, sz);
689 void PRF(byte* digest, uint digLen,
const byte* secret, uint secLen,
690 const byte* label, uint labLen,
const byte* seed, uint seedLen)
692 uint half = (secLen + 1) / 2;
694 output_buffer md5_half(half);
695 output_buffer sha_half(half);
696 output_buffer labelSeed(labLen + seedLen);
698 md5_half.write(secret, half);
699 sha_half.write(secret + half - secLen % 2, half);
700 labelSeed.write(label, labLen);
701 labelSeed.write(seed, seedLen);
703 output_buffer md5_result(digLen);
704 output_buffer sha_result(digLen);
706 p_hash(md5_result, md5_half, labelSeed, md5);
707 p_hash(sha_result, sha_half, labelSeed, sha);
709 md5_result.set_current(0);
710 sha_result.set_current(0);
711 get_xor(digest, digLen, md5_result, sha_result);
716 void build_certHashes(SSL& ssl, Hashes& hashes)
719 MD5 md5(ssl.getHashes().get_MD5());
720 SHA sha(ssl.getHashes().get_SHA());
723 ssl.useHashes().use_MD5().get_digest(hashes.md5_);
724 ssl.useHashes().use_SHA().get_digest(hashes.sha_);
727 buildMD5_CertVerify(ssl, hashes.md5_);
728 buildSHA_CertVerify(ssl, hashes.sha_);
732 ssl.useHashes().use_MD5() = md5;
733 ssl.useHashes().use_SHA() = sha;
739 int DoProcessReply(SSL& ssl)
741 uint ready = ssl.getSocket().get_ready();
746 input_buffer* buffered = ssl.useBuffers().TakeRawInput();
747 uint buffSz = buffered ? buffered->get_size() : 0;
748 input_buffer buffer(buffSz + ready);
750 buffer.assign(buffered->get_buffer(), buffSz);
756 uint read = ssl.useSocket().receive(buffer.get_buffer() + buffSz, ready);
757 if (read == static_cast<uint>(-1)) {
758 ssl.SetError(receive_error);
761 buffer.add_size(read);
763 const MessageFactory& mf = ssl.getFactory().getMessage();
766 if (ssl.getSecurity().get_parms().entity_ == server_end &&
767 ssl.getStates().getServer() == clientNull)
768 if (buffer.peek() != handshake) {
769 ProcessOldClientHello(buffer, ssl);
774 while(!buffer.eof()) {
776 RecordLayerHeader hdr;
777 bool needHdr =
false;
779 if (static_cast<uint>(RECORD_HEADER) > buffer.get_remaining())
783 ssl.verifyState(hdr);
787 if (needHdr || hdr.length_ > buffer.get_remaining()) {
789 uint
extra = needHdr ? 0 : RECORD_HEADER;
790 uint sz = buffer.get_remaining() + extra;
791 ssl.useBuffers().SetRawInput(NEW_YS input_buffer(sz,
792 buffer.get_buffer() + buffer.get_current() - extra, sz));
796 while (buffer.get_current() < hdr.length_ + RECORD_HEADER +
offset) {
798 if (ssl.getSecurity().get_parms().pending_ ==
false) {
800 if (buffer.get_remaining() < hdr.length_) {
801 ssl.SetError(bad_input);
804 decrypt_message(ssl, buffer, hdr.length_);
811 ssl.SetError(factory_error);
815 msg->Process(buffer, ssl);
819 offset += hdr.length_ + RECORD_HEADER;
826 void processReply(SSL& ssl)
828 if (ssl.GetError())
return;
830 if (DoProcessReply(ssl)) {
832 if (!ssl.getSocket().IsNonBlocking()) {
834 while (!ssl.GetError())
835 if (DoProcessReply(ssl) == 0)
break;
839 ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
845 void sendClientHello(SSL& ssl)
847 ssl.verifyState(serverNull);
848 if (ssl.GetError())
return;
850 ClientHello ch(ssl.getSecurity().get_connection().version_,
851 ssl.getSecurity().get_connection().compression_);
852 RecordLayerHeader rlHeader;
853 HandShakeHeader hsHeader;
856 buildClientHello(ssl, ch);
857 ssl.set_random(ch.get_random(), client_end);
858 buildHeaders(ssl, hsHeader, rlHeader, ch);
859 buildOutput(out, rlHeader, hsHeader, ch);
860 hashHandShake(ssl, out);
862 ssl.Send(out.get_buffer(), out.get_size());
867 void sendClientKeyExchange(SSL& ssl, BufferOutput buffer)
869 ssl.verifyState(serverHelloDoneComplete);
870 if (ssl.GetError())
return;
872 ClientKeyExchange ck(ssl);
874 ssl.makeMasterSecret();
876 RecordLayerHeader rlHeader;
877 HandShakeHeader hsHeader;
879 buildHeaders(ssl, hsHeader, rlHeader, ck);
880 buildOutput(*out.get(), rlHeader, hsHeader, ck);
881 hashHandShake(ssl, *out.get());
883 if (buffer == buffered)
884 ssl.addBuffer(out.release());
886 ssl.Send(out->get_buffer(), out->get_size());
891 void sendServerKeyExchange(SSL& ssl, BufferOutput buffer)
893 if (ssl.GetError())
return;
894 ServerKeyExchange sk(ssl);
896 if (ssl.GetError())
return;
898 RecordLayerHeader rlHeader;
899 HandShakeHeader hsHeader;
901 buildHeaders(ssl, hsHeader, rlHeader, sk);
902 buildOutput(*out.get(), rlHeader, hsHeader, sk);
903 hashHandShake(ssl, *out.get());
905 if (buffer == buffered)
906 ssl.addBuffer(out.release());
908 ssl.Send(out->get_buffer(), out->get_size());
913 void sendChangeCipher(SSL& ssl, BufferOutput buffer)
915 if (ssl.getSecurity().get_parms().entity_ == server_end) {
916 if (ssl.getSecurity().get_resuming())
917 ssl.verifyState(clientKeyExchangeComplete);
919 ssl.verifyState(clientFinishedComplete);
921 if (ssl.GetError())
return;
923 ChangeCipherSpec ccs;
924 RecordLayerHeader rlHeader;
925 buildHeader(ssl, rlHeader, ccs);
927 buildOutput(*out.get(), rlHeader, ccs);
929 if (buffer == buffered)
930 ssl.addBuffer(out.release());
932 ssl.Send(out->get_buffer(), out->get_size());
937 void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
939 if (ssl.GetError())
return;
942 buildFinished(ssl, fin, side == client_end ? client : server);
944 cipherFinished(ssl, fin, *out.get());
946 if (ssl.getSecurity().get_resuming()) {
947 if (side == server_end)
948 buildFinished(ssl, ssl.useHashes().use_verify(), client);
951 if (!ssl.getSecurity().GetContext()->GetSessionCacheOff())
952 GetSessions().add(ssl);
953 if (side == client_end)
954 buildFinished(ssl, ssl.useHashes().use_verify(), server);
956 ssl.useSecurity().use_connection().CleanMaster();
958 if (buffer == buffered)
959 ssl.addBuffer(out.release());
961 ssl.Send(out->get_buffer(), out->get_size());
966 int sendData(SSL& ssl,
const void* buffer,
int sz)
970 if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ))
971 ssl.SetError(no_error);
973 if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
974 ssl.SetError(no_error);
975 ssl.SendWriteBuffered();
976 if (!ssl.GetError()) {
978 sent = ssl.useBuffers().prevSent + ssl.useBuffers().plainSz;
982 ssl.verfiyHandShakeComplete();
983 if (ssl.GetError())
return -1;
986 int len = min(sz - sent, MAX_RECORD_SIZE);
992 if (sent == sz)
break;
994 if (ssl.CompressionOn()) {
995 if (Compress(static_cast<const opaque*>(buffer) + sent, len,
997 ssl.SetError(compress_error);
1000 data.SetData(tmp.get_size(), tmp.get_buffer());
1003 data.SetData(len, static_cast<const opaque*>(buffer) + sent);
1005 buildMessage(ssl, out, data);
1006 ssl.Send(out.get_buffer(), out.get_size());
1008 if (ssl.GetError()) {
1009 if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) {
1010 ssl.useBuffers().plainSz = len;
1011 ssl.useBuffers().prevSent = sent;
1017 ssl.useLog().ShowData(sent,
true);
1023 int sendAlert(SSL& ssl,
const Alert& alert)
1026 buildAlert(ssl, out, alert);
1027 ssl.Send(out.get_buffer(), out.get_size());
1029 return alert.get_length();
1034 int receiveData(SSL& ssl,
Data& data,
bool peek)
1036 if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ))
1037 ssl.SetError(no_error);
1039 ssl.verfiyHandShakeComplete();
1040 if (ssl.GetError())
return -1;
1050 ssl.useLog().ShowData(data.get_length());
1051 if (ssl.GetError())
return -1;
1053 if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) {
1054 ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
1055 return SSL_WOULD_BLOCK;
1057 return data.get_length();
1062 void sendServerHello(SSL& ssl, BufferOutput buffer)
1064 if (ssl.getSecurity().get_resuming())
1065 ssl.verifyState(clientKeyExchangeComplete);
1067 ssl.verifyState(clientHelloComplete);
1068 if (ssl.GetError())
return;
1070 ServerHello sh(ssl.getSecurity().get_connection().version_,
1071 ssl.getSecurity().get_connection().compression_);
1072 RecordLayerHeader rlHeader;
1073 HandShakeHeader hsHeader;
1076 buildServerHello(ssl, sh);
1077 ssl.set_random(sh.get_random(), server_end);
1078 buildHeaders(ssl, hsHeader, rlHeader, sh);
1079 buildOutput(*out.get(), rlHeader, hsHeader, sh);
1080 hashHandShake(ssl, *out.get());
1082 if (buffer == buffered)
1083 ssl.addBuffer(out.release());
1085 ssl.Send(out->get_buffer(), out->get_size());
1090 void sendServerHelloDone(SSL& ssl, BufferOutput buffer)
1092 if (ssl.GetError())
return;
1094 ServerHelloDone shd;
1095 RecordLayerHeader rlHeader;
1096 HandShakeHeader hsHeader;
1099 buildHeaders(ssl, hsHeader, rlHeader, shd);
1100 buildOutput(*out.get(), rlHeader, hsHeader, shd);
1101 hashHandShake(ssl, *out.get());
1103 if (buffer == buffered)
1104 ssl.addBuffer(out.release());
1106 ssl.Send(out->get_buffer(), out->get_size());
1111 void sendCertificate(SSL& ssl, BufferOutput buffer)
1113 if (ssl.GetError())
return;
1115 Certificate cert(ssl.getCrypto().get_certManager().get_cert());
1116 RecordLayerHeader rlHeader;
1117 HandShakeHeader hsHeader;
1120 buildHeaders(ssl, hsHeader, rlHeader, cert);
1121 buildOutput(*out.get(), rlHeader, hsHeader, cert);
1122 hashHandShake(ssl, *out.get());
1124 if (buffer == buffered)
1125 ssl.addBuffer(out.release());
1127 ssl.Send(out->get_buffer(), out->get_size());
1132 void sendCertificateRequest(SSL& ssl, BufferOutput buffer)
1134 if (ssl.GetError())
return;
1138 RecordLayerHeader rlHeader;
1139 HandShakeHeader hsHeader;
1142 buildHeaders(ssl, hsHeader, rlHeader, request);
1143 buildOutput(*out.get(), rlHeader, hsHeader, request);
1144 hashHandShake(ssl, *out.get());
1146 if (buffer == buffered)
1147 ssl.addBuffer(out.release());
1149 ssl.Send(out->get_buffer(), out->get_size());
1154 void sendCertificateVerify(SSL& ssl, BufferOutput buffer)
1156 if (ssl.GetError())
return;
1158 CertificateVerify verify;
1160 RecordLayerHeader rlHeader;
1161 HandShakeHeader hsHeader;
1164 buildHeaders(ssl, hsHeader, rlHeader, verify);
1165 buildOutput(*out.get(), rlHeader, hsHeader, verify);
1166 hashHandShake(ssl, *out.get());
1168 if (buffer == buffered)
1169 ssl.addBuffer(out.release());
1171 ssl.Send(out->get_buffer(), out->get_size());