XnStatus PlayerNode::HandleRecord(Record &record, XnBool bHandlePayload) { XN_ASSERT(record.IsHeaderValid()); switch (record.GetType()) { case RECORD_NODE_ADDED: return HandleNodeAddedRecord(record); case RECORD_INT_PROPERTY: return HandleIntPropRecord(record); case RECORD_REAL_PROPERTY: return HandleRealPropRecord(record); case RECORD_STRING_PROPERTY: return HandleStringPropRecord(record); case RECORD_GENERAL_PROPERTY: return HandleGeneralPropRecord(record); case RECORD_NODE_REMOVED: return HandleNodeRemovedRecord(record); case RECORD_NODE_STATE_READY: return HandleNodeStateReadyRecord(record); case RECORD_NODE_DATA_BEGIN: return HandleNodeDataBeginRecord(record); case RECORD_NEW_DATA: return HandleNewDataRecord(record, bHandlePayload); case RECORD_END: return HandleEndRecord(record); // BC stuff case RECORD_NODE_ADDED_1_0_0_4: return HandleNodeAdded_1_0_0_4_Record(record); default: XN_ASSERT(FALSE); XN_LOG_ERROR_RETURN(XN_STATUS_CORRUPT_FILE, XN_MASK_OPEN_NI, "Unrecognized record type: %u", record.GetType()); } }
// Helper Funcitons void Socket::ClientHandshake() { std::cout << "Client Handshake" << std::endl; unsigned char previous = 0; bool bEncrypted = false; std::vector<unsigned char> handshakeData; bool bDone = false; while( !bDone ) { Record *record; if( !bEncrypted ) { record = new Record(); }else{ record = new Record( mClient ); } record->Read( *mSocket ); // Alert if( record->GetType() == Record::Alert ){ std::vector<unsigned char> data = record->GetData(); std::cerr << "Alert: " << std::hex << std::setw( 2 ) << std::setfill('0') << (int)data[0] << ", " << std::hex << std::setw( 2 ) << std::setfill('0') << (int)data[1] << std::endl; exit( EXIT_FAILURE ); } // Cipher if( record->GetType() == Record::Cipher ){ if( previous == Handshake::Type::ClientKey ){ bEncrypted = true; } previous = Record::Cipher; } // Handshake if( record->GetType() == Record::Handshake ){ std::vector<unsigned char> data = record->GetData(); if( previous == 0 ){ if( data[0] == Handshake::Type::ClientHello ){ Handshake::ClientHello hClientHello; hClientHello.Deserialize( std::vector<unsigned char>( data.begin() + 4, data.end() ) ); ClientRandom = hClientHello.Random(); handshakeData.insert( handshakeData.end(), data.begin(), data.end() ); Handshake::ServerHello hServerHello( 0x00, 0x35, 0x00 ); Record rServerHello( Record::Handshake, hServerHello.Serialize() ); rServerHello.Write( *mSocket ); ServerRandom = hServerHello.Random(); std::vector<unsigned char> dServerHello = hServerHello.Serialize(); handshakeData.insert( handshakeData.end(), dServerHello.begin(), dServerHello.end() ); Handshake::Certificate hCertificate( mCertificatePath ); Record rCertificate( Record::Handshake, hCertificate.Serialize() ); rCertificate.Write( *mSocket ); std::vector<unsigned char> dCertificate = hCertificate.Serialize(); handshakeData.insert( handshakeData.end(), dCertificate.begin(), dCertificate.end() ); std::vector<unsigned char> dServerDone; // Insert Size unsigned int size = htonl( dServerDone.size() ); unsigned char* cSize = (unsigned char*)&size; dServerDone.insert( dServerDone.begin(), cSize[3] ); dServerDone.insert( dServerDone.begin(), cSize[2] ); dServerDone.insert( dServerDone.begin(), cSize[1] ); // Insert Type dServerDone.insert( dServerDone.begin(), Handshake::Type::ServerDone ); Record rServerDone( Record::Handshake, dServerDone ); rServerDone.Write( *mSocket ); handshakeData.insert( handshakeData.end(), dServerDone.begin(), dServerDone.end() ); } previous = data[0]; } if( previous == Handshake::Type::ClientHello ){ if( data[0] == Handshake::Type::ClientKey ){ Handshake::ClientKeyExchange hClientKeyExchange( mKeyPath ); hClientKeyExchange.Deserialize( std::vector<unsigned char>( data.begin() + 4, data.end() ) ); handshakeData.insert( handshakeData.end(), data.begin(), data.end() ); DataArray secret = hClientKeyExchange.Secret(); MasterKey = PRF( 48, secret, "master secret", Concatonate( ClientRandom, ServerRandom ) ); KeyBlock = PRF( 136, MasterKey, "key expansion", Concatonate( ServerRandom, ClientRandom ) ); DataArray ClientMAC( KeyBlock.begin(), KeyBlock.begin() + 20 ); DataArray ServerMAC( KeyBlock.begin() + 20, KeyBlock.begin() + 40 ); DataArray ClientKey( KeyBlock.begin() + 40, KeyBlock.begin() + 72 ); DataArray ClientIV( KeyBlock.begin() + 104, KeyBlock.begin() + 120 ); mClient->Initialise( ClientMAC, ClientKey , ClientIV ); DataArray ServerKey( KeyBlock.begin() + 72, KeyBlock.begin() + 104 ); DataArray ServerIV( KeyBlock.begin() + 120, KeyBlock.begin() + 136 ); mServer->Initialise( ServerMAC, ServerKey , ServerIV ); } previous = data[0]; } if( previous == Record::Cipher ){ if( data[0] == Handshake::Type::Finished ){ Handshake::Finished hFinished; hFinished.Deserialize( std::vector<unsigned char>( data.begin() + 4, data.end() ) ); unsigned char md5hash[MD5_DIGEST_LENGTH]; unsigned char shahash[SHA_DIGEST_LENGTH]; MD5( &handshakeData[0], handshakeData.size(), md5hash ); SHA1( &handshakeData[0], handshakeData.size(), shahash ); std::vector<unsigned char> signiture; signiture.insert( signiture.end(), md5hash, md5hash + 16 ); signiture.insert( signiture.end(), shahash, shahash + 20 ); DataArray clientprf = PRF( 12, MasterKey, "client finished", signiture ); DataArray clientfin = std::vector<unsigned char>( data.begin() + 4, data.end() ); bool bDiff = false; for( unsigned int i = 0; i < clientfin.size(); i++ ){ if( clientfin[i] != clientprf[i] ) { bDiff = true; break; } } if( bDiff ) { std::cout << "Finished Different" << std::endl; std::cout << "Finish Should Be: " << std::dec << (int)clientprf.size() << std::endl; for( unsigned int i = 0 ; i < clientprf.size(); i++ ){ std::cout << std::hex << std::setw( 2 ) << std::setfill('0') << (int) clientprf[i] << " ";; if( (i + 1) % 16 == 0 ) std::cout << std::endl; } std::cout << std::endl; std::cout << "Finish Is: " << std::dec << (int)clientfin.size() << std::endl; for( unsigned int i = 0 ; i < clientfin.size(); i++ ){ std::cout << std::hex << std::setw( 2 ) << std::setfill('0') << (int) clientfin[i] << " ";; if( (i + 1) % 16 == 0 ) std::cout << std::endl; } std::cout << std::endl; } handshakeData.insert( handshakeData.end(), data.begin(), data.end() ); std::vector<unsigned char> dChangeCipher; dChangeCipher.push_back( 1 ); Record rChangeCipher( Record::Cipher, dChangeCipher ); rChangeCipher.Write( *mSocket ); MD5( &handshakeData[0], handshakeData.size(), md5hash ); SHA1( &handshakeData[0], handshakeData.size(), shahash ); std::vector<unsigned char> finSig; finSig.insert( finSig.end(), md5hash, md5hash + 16 ); finSig.insert( finSig.end(), shahash, shahash + 20 ); DataArray serverprf = PRF( 12, MasterKey, "server finished", finSig ); Record rServerFinished( Record::Handshake, Handshake::Finished( serverprf ).Serialize(), mServer ); rServerFinished.Write( *mSocket ); bDone = true; } previous = data[0]; } } } std::cout << "Finished " << this << " " << mSocket << std::endl; }