📄 handshake.cpp
字号:
PRF(fin.set_md5(), TLS_FINISHED_SZ, ssl.getSecurity().get_connection().master_secret_, SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, FINISHED_SZ); fin.set_length(TLS_FINISHED_SZ); // shorter length for TLS}// compute p_hash for MD5 or SHA-1 for TLSv1 PRFvoid p_hash(output_buffer& result, const output_buffer& secret, const output_buffer& seed, MACAlgorithm hash){ uint len = hash == md5 ? MD5_LEN : SHA_LEN; uint times = result.get_capacity() / len; uint lastLen = result.get_capacity() % len; opaque previous[SHA_LEN]; // max size opaque current[SHA_LEN]; // max size mySTL::auto_ptr<Digest> hmac(ysDelete); if (lastLen) times += 1; if (hash == md5) hmac.reset(new (ys) HMAC_MD5(secret.get_buffer(), secret.get_size())); else hmac.reset(new (ys) HMAC_SHA(secret.get_buffer(), secret.get_size())); // A0 = seed hmac->get_digest(previous, seed.get_buffer(), seed.get_size());// A1 uint lastTime = times - 1; for (uint i = 0; i < times; i++) { hmac->update(previous, len); hmac->get_digest(current, seed.get_buffer(), seed.get_size()); if (lastLen && (i == lastTime)) result.write(current, lastLen); else { result.write(current, len); //memcpy(previous, current, len); hmac->get_digest(previous, previous, len); } }}// calculate XOR for TLSv1 PRFvoid get_xor(byte *digest, uint digLen, output_buffer& md5, output_buffer& sha){ for (uint i = 0; i < digLen; i++) digest[i] = md5[AUTO] ^ sha[AUTO];}// build MD5 part of certificate verifyvoid buildMD5_CertVerify(SSL& ssl, byte* digest){ opaque md5_result[MD5_LEN]; opaque md5_inner[SECRET_LEN + PAD_MD5]; opaque md5_outer[SECRET_LEN + PAD_MD5 + MD5_LEN]; const opaque* master_secret = ssl.getSecurity().get_connection().master_secret_; // make md5 inner memcpy(md5_inner, master_secret, SECRET_LEN); memcpy(&md5_inner[SECRET_LEN], PAD1, PAD_MD5); ssl.useHashes().use_MD5().get_digest(md5_result, md5_inner, sizeof(md5_inner)); // make md5 outer memcpy(md5_outer, master_secret, SECRET_LEN); memcpy(&md5_outer[SECRET_LEN], PAD2, PAD_MD5); memcpy(&md5_outer[SECRET_LEN + PAD_MD5], md5_result, MD5_LEN); ssl.useHashes().use_MD5().get_digest(digest, md5_outer, sizeof(md5_outer));}// build SHA part of certificate verifyvoid buildSHA_CertVerify(SSL& ssl, byte* digest){ opaque sha_result[SHA_LEN]; opaque sha_inner[SECRET_LEN + PAD_SHA]; opaque sha_outer[SECRET_LEN + PAD_SHA + SHA_LEN]; const opaque* master_secret = ssl.getSecurity().get_connection().master_secret_; // make sha inner memcpy(sha_inner, master_secret, SECRET_LEN); memcpy(&sha_inner[SECRET_LEN], PAD1, PAD_SHA); ssl.useHashes().use_SHA().get_digest(sha_result, sha_inner, sizeof(sha_inner)); // make sha outer memcpy(sha_outer, master_secret, SECRET_LEN); memcpy(&sha_outer[SECRET_LEN], PAD2, PAD_SHA); memcpy(&sha_outer[SECRET_LEN + PAD_SHA], sha_result, SHA_LEN); ssl.useHashes().use_SHA().get_digest(digest, sha_outer, sizeof(sha_outer));}} // namespace for locals// some clients still send sslv2 client hellovoid ProcessOldClientHello(input_buffer& input, SSL& ssl){ byte b0 = input[AUTO]; byte b1 = input[AUTO]; uint16 sz = ((b0 & 0x7f) << 8) | b1; // hashHandShake manually const opaque* buffer = input.get_buffer() + input.get_current(); ssl.useHashes().use_MD5().update(buffer, sz); ssl.useHashes().use_SHA().update(buffer, sz); b1 = input[AUTO]; // does this value mean client_hello? ClientHello ch; ch.client_version_.major_ = input[AUTO]; ch.client_version_.minor_ = input[AUTO]; byte len[2]; input.read(len, sizeof(len)); ato16(len, ch.suite_len_); input.read(len, sizeof(len)); uint16 sessionLen; ato16(len, sessionLen); ch.id_len_ = sessionLen; input.read(len, sizeof(len)); uint16 randomLen; ato16(len, randomLen); int j = 0; for (uint16 i = 0; i < ch.suite_len_; i += 3) { byte first = input[AUTO]; if (first) // sslv2 type input.read(len, SUITE_LEN); // skip else { input.read(&ch.cipher_suites_[j], SUITE_LEN); j += SUITE_LEN; } } ch.suite_len_ = j; if (ch.id_len_) input.read(ch.session_id_, ch.id_len_); if (randomLen < RAN_LEN) memset(ch.random_, 0, RAN_LEN - randomLen); input.read(&ch.random_[RAN_LEN - randomLen], randomLen); ch.Process(input, ssl);}// Build a finished message, see 7.6.9void buildFinished(SSL& ssl, Finished& fin, const opaque* sender) { // store current states, building requires get_digest which resets state MD5 md5(ssl.getHashes().get_MD5()); SHA sha(ssl.getHashes().get_SHA()); if (ssl.isTLS()) buildFinishedTLS(ssl, fin, sender); else { buildMD5(ssl, fin, sender); buildSHA(ssl, fin, sender); } // restore ssl.useHashes().use_MD5() = md5; ssl.useHashes().use_SHA() = sha;}/* compute SSLv3 HMAC into digest see * buffer is of sz size and includes HandShake Header but not a Record Header * verify means to check peers hmac*/void hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, ContentType content, bool verify){ Digest& mac = ssl.useCrypto().use_digest(); opaque inner[SHA_LEN + PAD_MD5 + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ]; opaque outer[SHA_LEN + PAD_MD5 + SHA_LEN]; opaque result[SHA_LEN]; // max possible sizes uint digestSz = mac.get_digestSize(); // actual sizes uint padSz = mac.get_padSize(); uint innerSz = digestSz + padSz + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ; uint outerSz = digestSz + padSz + digestSz; // data const opaque* mac_secret = ssl.get_macSecret(verify); opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; opaque length[LENGTH_SZ]; c16toa(sz, length); c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); // make inner memcpy(inner, mac_secret, digestSz); memcpy(&inner[digestSz], PAD1, padSz); memcpy(&inner[digestSz + padSz], seq, SEQ_SZ); inner[digestSz + padSz + SEQ_SZ] = content; memcpy(&inner[digestSz + padSz + SEQ_SZ + SIZEOF_ENUM], length, LENGTH_SZ); mac.update(inner, innerSz); mac.get_digest(result, buffer, sz); // append content buffer // make outer memcpy(outer, mac_secret, digestSz); memcpy(&outer[digestSz], PAD2, padSz); memcpy(&outer[digestSz + padSz], result, digestSz); mac.get_digest(digest, outer, outerSz);}// TLS type HAMCvoid TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, ContentType content, bool verify){ mySTL::auto_ptr<Digest> hmac(ysDelete); opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; opaque length[LENGTH_SZ]; opaque inner[SIZEOF_ENUM + VERSION_SZ + LENGTH_SZ]; // type + version + len c16toa(sz, length); c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); MACAlgorithm algo = ssl.getSecurity().get_parms().mac_algorithm_; if (algo == sha) hmac.reset(new (ys) HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN)); else if (algo == rmd) hmac.reset(new (ys) HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN)); else hmac.reset(new (ys) HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN)); hmac->update(seq, SEQ_SZ); // seq_num inner[0] = content; // type inner[SIZEOF_ENUM] = ssl.getSecurity().get_connection().version_.major_; inner[SIZEOF_ENUM + SIZEOF_ENUM] = ssl.getSecurity().get_connection().version_.minor_; // version memcpy(&inner[SIZEOF_ENUM + VERSION_SZ], length, LENGTH_SZ); // length hmac->update(inner, sizeof(inner)); hmac->get_digest(digest, buffer, sz); // content}// compute TLSv1 PRF (pseudo random function using HMAC)void PRF(byte* digest, uint digLen, const byte* secret, uint secLen, const byte* label, uint labLen, const byte* seed, uint seedLen){ uint half = secLen / 2 + secLen % 2; output_buffer md5_half(half); output_buffer sha_half(half); output_buffer labelSeed(labLen + seedLen); md5_half.write(secret, half); sha_half.write(secret + half - secLen % 2, half); labelSeed.write(label, labLen); labelSeed.write(seed, seedLen); output_buffer md5_result(digLen); output_buffer sha_result(digLen); p_hash(md5_result, md5_half, labelSeed, md5); p_hash(sha_result, sha_half, labelSeed, sha); md5_result.set_current(0); sha_result.set_current(0); get_xor(digest, digLen, md5_result, sha_result);}// build certificate hashesvoid build_certHashes(SSL& ssl, Hashes& hashes){ // store current states, building requires get_digest which resets state MD5 md5(ssl.getHashes().get_MD5()); SHA sha(ssl.getHashes().get_SHA()); if (ssl.isTLS()) { ssl.useHashes().use_MD5().get_digest(hashes.md5_); ssl.useHashes().use_SHA().get_digest(hashes.sha_); } else { buildMD5_CertVerify(ssl, hashes.md5_); buildSHA_CertVerify(ssl, hashes.sha_); } // restore ssl.useHashes().use_MD5() = md5; ssl.useHashes().use_SHA() = sha;}// do process input requestsmySTL::auto_ptr<input_buffer>DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered){ ssl.getSocket().wait(); // wait for input if blocking uint ready = ssl.getSocket().get_ready(); if (!ready) { // Nothing to receive after blocking wait => error ssl.SetError(receive_error); buffered.reset(0); return buffered; } // add buffered data if its there uint buffSz = buffered.get() ? buffered.get()->get_size() : 0; input_buffer buffer(buffSz + ready); if (buffSz) { buffer.assign(buffered.get()->get_buffer(), buffSz); buffered.reset(0); } // add new data uint read = ssl.getSocket().receive(buffer.get_buffer() + buffSz, ready); buffer.add_size(read); uint offset = 0; const MessageFactory& mf = ssl.getFactory().getMessage(); // old style sslv2 client hello? if (ssl.getSecurity().get_parms().entity_ == server_end && ssl.getStates().getServer() == clientNull)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -