void MainWindow::msgCryptSetup(const MumbleProto::CryptSetup &msg) { ConnectionPtr c= g.sh->cConnection; if (! c) return; if (msg.has_key() && msg.has_client_nonce() && msg.has_server_nonce()) { const std::string &key = msg.key(); const std::string &client_nonce = msg.client_nonce(); const std::string &server_nonce = msg.server_nonce(); if (key.size() == AES_BLOCK_SIZE && client_nonce.size() == AES_BLOCK_SIZE && server_nonce.size() == AES_BLOCK_SIZE) c->csCrypt.setKey(reinterpret_cast<const unsigned char *>(key.data()), reinterpret_cast<const unsigned char *>(client_nonce.data()), reinterpret_cast<const unsigned char *>(server_nonce.data())); } else if (msg.has_server_nonce()) { const std::string &server_nonce = msg.server_nonce(); if (server_nonce.size() == AES_BLOCK_SIZE) { c->csCrypt.uiResync++; memcpy(c->csCrypt.decrypt_iv, server_nonce.data(), AES_BLOCK_SIZE); } } else { MumbleProto::CryptSetup mpcs; mpcs.set_client_nonce(std::string(reinterpret_cast<const char *>(c->csCrypt.encrypt_iv), AES_BLOCK_SIZE)); g.sh->sendMessage(mpcs); } }
void MumbleClient::setupEncryption(quint8 *message, quint64 size) { MumbleProto::CryptSetup crypt; crypt.ParseFromArray(message,size); _key = crypt.key(); _client_nonce = crypt.client_nonce(); _server_nonce = crypt.server_nonce(); #ifndef NO_CRYPT _crypt_state->setKey(reinterpret_cast<const unsigned char*>(_key.c_str()), reinterpret_cast<const unsigned char*>(_client_nonce.c_str()), reinterpret_cast<const unsigned char*>(_server_nonce.c_str())); #endif _encryption_set = true; qDebug() << "Encryption setup ok "; pingServer(); }
void mumlib::Transport::processMessageInternal(MessageType messageType, uint8_t *buffer, int length) { switch (messageType) { case MessageType::UDPTUNNEL: { logger.debug("Received %d B of encoded audio data via TCP.", length); processAudioPacket(buffer, length); } break; case MessageType::AUTHENTICATE: { logger.warn("Authenticate message received after authenticated."); } break; case MessageType::PING: { MumbleProto::Ping ping; ping.ParseFromArray(buffer, length); stringstream log; log << "Received ping."; if (ping.has_good()) { log << " good: " << ping.good(); } if (ping.has_late()) { log << " late: " << ping.late(); } if (ping.has_lost()) { log << " lost: " << ping.lost(); } if (ping.has_tcp_ping_avg()) { log << " TCP avg: " << ping.tcp_ping_avg() << " ms"; } if (ping.has_udp_ping_avg()) { log << " UDP avg: " << ping.udp_ping_avg() << " ms"; } logger.debug(log.str()); } break; case MessageType::REJECT: { MumbleProto::Reject reject; reject.ParseFromArray(buffer, length); stringstream errorMesg; errorMesg << "failed to authenticate"; if (reject.has_type()) { errorMesg << ": " << rejectMessages.at(reject.type()); } if (reject.has_reason()) { errorMesg << ", reason: " << reject.reason(); } throwTransportException(errorMesg.str()); } break; case MessageType::SERVERSYNC: { state = ConnectionState::CONNECTED; logger.debug("SERVERSYNC. Calling external ProcessControlMessageFunction."); processMessageFunction(messageType, buffer, length); } break; case MessageType::CRYPTSETUP: { if (not noUdp) { MumbleProto::CryptSetup cryptsetup; cryptsetup.ParseFromArray(buffer, length); if (cryptsetup.client_nonce().length() != AES_BLOCK_SIZE or cryptsetup.server_nonce().length() != AES_BLOCK_SIZE or cryptsetup.key().length() != AES_BLOCK_SIZE) { throwTransportException("one of cryptographic parameters has invalid length"); } cryptState.setKey( reinterpret_cast<const unsigned char *>(cryptsetup.key().c_str()), reinterpret_cast<const unsigned char *>(cryptsetup.client_nonce().c_str()), reinterpret_cast<const unsigned char *>(cryptsetup.server_nonce().c_str())); if (not cryptState.isValid()) { throwTransportException("crypt setup data not valid"); } logger.info("Set up cryptography for UDP transport. Sending UDP ping."); sendUdpPing(); } else { logger.info("Ignoring crypt setup message, because UDP is disabled."); } } break; default: { logger.debug("Calling external ProcessControlMessageFunction."); processMessageFunction(messageType, buffer, length); } break; } }