void RTMFP::Encode(RTMFPEngine& aesEncrypt,PacketWriter& packet) { // paddingBytesLength=(0xffffffff-plainRequestLength+5)&0x0F int paddingBytesLength = (0xFFFFFFFF-packet.size()+5)&0x0F; // Padd the plain request with paddingBytesLength of value 0xff at the end while (paddingBytesLength-->0) packet.write8(0xFF); WriteCRC(packet); // Encrypt the resulted request aesEncrypt.process(packet.data()+4,(UInt8*)packet.data()+4,packet.size()-4); }
void Handshake::createCookie(PacketWriter& writer,HelloAttempt& attempt,const string& tag,const string& queryUrl) { // New Cookie Cookie* pCookie = attempt.pCookie; if(!pCookie) { if(attempt.pTarget) pCookie = new Cookie(*this,invoker,tag,*attempt.pTarget); else pCookie = new Cookie(*this,invoker,tag,queryUrl); _cookies[pCookie->value()] = pCookie; attempt.pCookie = pCookie; } writer.write8(COOKIE_SIZE); writer.writeRaw(pCookie->value(),COOKIE_SIZE); }
void FlowWriter::flush(PacketWriter& writer,UInt64 stage,UInt8 flags,bool header,BinaryReader& reader,UInt16 size) { if(_stageAck==0 && header) flags |= MESSAGE_HEADER; if(size==0) flags |= MESSAGE_ABANDONMENT; if(_closed && _messages.size()==1) // On LAST message flags |= MESSAGE_END; // TRACE("FlowWriter %u stage %u",id,stage); writer.write8(flags); if(header) { writer.write7BitLongValue(id); writer.write7BitLongValue(stage); writer.write7BitLongValue(stage-_stageAck); // signature if(_stageAck==0) { writer.writeString8(signature); // No write this in the case where it's a new flow! if(flowId>0) { writer.write8(1+Util::Get7BitValueSize(flowId)); // following size writer.write8(0x0a); // Unknown! writer.write7BitLongValue(flowId); } writer.write8(0); // marker of end for this part } } if(size>0) { reader.readRaw(writer.begin()+writer.position(),size); writer.next(size); } }
// TODO make perhaps a FlowHandshake UInt8 Handshake::handshakeHandler(UInt8 id,PacketReader& request,PacketWriter& response) { switch(id){ case 0x30: { request.read8(); // passer un caractere (boite dans boite) UInt8 epdLen = request.read8()-1; UInt8 type = request.read8(); string epd; request.readRaw(epdLen,epd); string tag; request.readRaw(16,tag); response.writeString8(tag); // UDP hole punching if(type == 0x0f) return _gateway.p2pHandshake(tag,response,peer().address,(const UInt8*)epd.c_str()); if(type == 0x0a){ /// Handshake // RESPONSE 38 // New Cookie char cookie[65]; RandomInputStream ris; ris.read(cookie,64); cookie[64]='\0'; response.write8(64); response.writeRaw(cookie,64); _cookies[cookie] = new Cookie(epd); // instance id (certificat in the middle) response.writeRaw(_certificat,sizeof(_certificat)); return 0x70; } else { ERROR("Unkown handshake first way with '%02x' type",type); } break; } case 0x38: { _farId = request.read32(); string cookie; request.readRaw(request.read8(),cookie); map<string,Cookie*>::iterator itCookie = _cookies.find(cookie.c_str()); if(itCookie==_cookies.end()) { ERROR("Handshake cookie '%s' unknown",cookie.c_str()); return 0; } request.read8(); // why 0x81? // signature string farSignature; request.readString8(farSignature); // 81 02 1D 02 stable // farPubKeyPart UInt8 farPubKeyPart[128]; request.readRaw((char*)farPubKeyPart,sizeof(farPubKeyPart)); string farCertificat; request.readString8(farCertificat); // peerId = SHA256(farSignature+farPubKey) string temp(farSignature); temp.append((char*)farPubKeyPart,sizeof(farPubKeyPart)); EVP_Digest(temp.c_str(),temp.size(),(UInt8*)peer().id,NULL,EVP_sha256(),NULL); // Compute Diffie-Hellman secret UInt8 pubKey[128]; UInt8 sharedSecret[128]; RTMFP::EndDiffieHellman(RTMFP::BeginDiffieHellman(pubKey),farPubKeyPart,sharedSecret); // Compute Keys UInt8 requestKey[AES_KEY_SIZE]; UInt8 responseKey[AES_KEY_SIZE]; RTMFP::ComputeAsymetricKeys(sharedSecret,pubKey,_signature,farCertificat,requestKey,responseKey); // RESPONSE Util::UnpackUrl(itCookie->second->queryUrl,(string&)peer().path,(map<string,string>&)peer().parameters); response << _gateway.createSession(_farId,peer(),requestKey,responseKey); response.write8(0x81); response.writeString8(_signature); response.writeRaw((char*)pubKey,sizeof(pubKey)); response.write8(0x58); // remove cookie _cookies.erase(itCookie); // db_add_public(s); // TODO return 0x78; } default: ERROR("Unkown handshake packet id '%02x'",id); } return 0; }