int iaap_recv_dec_process (int chan, int flags, byte * buf, int len) {// Decrypt & Process 1 received encrypted message int bytes_written = BIO_write (hu_ssl_rm_bio, buf, len); // Write encrypted to SSL input BIO if (bytes_written <= 0) { loge ("BIO_write() bytes_written: %d", bytes_written); return (-1); } if (bytes_written != len) loge ("BIO_write() len: %d bytes_written: %d chan: %d", len, bytes_written, chan); else if (ena_log_verbo) logd ("BIO_write() len: %d bytes_written: %d chan: %d", len, bytes_written, chan); errno = 0; int ctr = 0; int max_tries = 1; // Higher never works int bytes_read = -1; while (bytes_read <= 0 && ctr ++ < max_tries) { bytes_read = SSL_read (hu_ssl_ssl, dec_buf, sizeof (dec_buf)); // Read decrypted to decrypted rx buf if (bytes_read <= 0) { loge ("ctr: %d SSL_read() bytes_read: %d errno: %d", ctr, bytes_read, errno); hu_ssl_ret_log (bytes_read); ms_sleep (1); } //logd ("ctr: %d SSL_read() bytes_read: %d errno: %d", ctr, bytes_read, errno); } if (bytes_read <= 0) { loge ("ctr: %d SSL_read() bytes_read: %d errno: %d", ctr, bytes_read, errno); hu_ssl_ret_log (bytes_read); return (-1); // Fatal so return error and de-initialize; Should we be able to recover, if USB data got corrupted ?? } if (ena_log_verbo) logd ("ctr: %d SSL_read() bytes_read: %d", ctr, bytes_read); int rmv = 0; #ifndef NDEBUG // if (chan != AA_CH_VID) // If not video... rmv = hu_aad_dmp ("DR: ", 2, dec_buf, bytes_read); // Dump decrypted AA #endif int prot_func_ret = iaap_msg_process (chan, flags, dec_buf, bytes_read); // Process decrypted AA protocol message return (0);//prot_func_ret); }
int HUServer::hu_aap_recv_process (int tmo) { // // Terminate unless started or starting (we need to process when starting) if (iaap_state != hu_STATE_STARTED && iaap_state != hu_STATE_STARTIN) { loge ("CHECK: iaap_state: %d (%s)", iaap_state, state_get (iaap_state)); return (-1); } int ret = 0; errno = 0; int min_size_hdr = 4; int have_len = 0; // Length remaining to process for all sub-packets plus 4/8 byte headers temp_assembly_buffer.clear(); bool has_last = false; bool has_first = false; int chan = -1; while (!has_last) { // While length remaining to process,... Process Rx packet: have_len = hu_aap_tra_recv (enc_buf, min_size_hdr, tmo); if (have_len == 0 && !has_first) { return 0; } if (have_len < min_size_hdr) { // If we don't have a full 6 byte header at least... loge ("Recv have_len: %d", have_len); return (-1); } if (ena_log_verbo) { logd ("Recv while (have_len > 0): %d", have_len); hex_dump ("LR: ", 16, enc_buf, have_len); } int cur_chan = (int) enc_buf [0]; // Channel if (cur_chan != chan && chan >= 0) { loge ("Interleaved channels"); return (-1); } chan = cur_chan; int flags = enc_buf [1]; // Flags int frame_len = be16toh(*((uint16_t*)&enc_buf[2])); logd("Frame flags %i len %i", flags, frame_len); if (frame_len > MAX_FRAME_PAYLOAD_SIZE) { loge ("Too big"); return (-1); } int header_size = 4; bool has_total_size_header = false; if ((flags & HU_FRAME_FIRST_FRAME) & !(flags & HU_FRAME_LAST_FRAME)) { //if first but not last, next 4 is total size has_total_size_header = true; header_size += 4; } int remaining_bytes_in_frame = (frame_len + header_size) - have_len; while(remaining_bytes_in_frame > 0) { logd("Getting more %i", remaining_bytes_in_frame); int got_bytes = hu_aap_tra_recv (&enc_buf[have_len], remaining_bytes_in_frame, tmo); // Get Rx packet from Transport if (got_bytes < 0) { // If we don't have a full 6 byte header at least... loge ("Recv got_bytes: %d", got_bytes); return (-1); } have_len += got_bytes; remaining_bytes_in_frame -= got_bytes; } if (!has_first && !(flags & HU_FRAME_FIRST_FRAME)) { loge ("No HU_FRAME_FIRST_FRAME"); return (-1); } has_first = true; has_last = (flags & HU_FRAME_LAST_FRAME) != 0; if (has_total_size_header) { uint32_t total_size = be32toh(*((uint32_t*)&enc_buf[4])); logd("First only, total len %u", total_size); temp_assembly_buffer.reserve(total_size); } else { temp_assembly_buffer.reserve(frame_len); } if (flags & HU_FRAME_ENCRYPTED) { size_t cur_vec = temp_assembly_buffer.size(); temp_assembly_buffer.resize(cur_vec + frame_len); //just incase int bytes_written = BIO_write (hu_ssl_rm_bio, &enc_buf[header_size], frame_len); // Write encrypted to SSL input BIO if (bytes_written <= 0) { loge ("BIO_write() bytes_written: %d", bytes_written); return (-1); } if (bytes_written != frame_len) loge ("BIO_write() len: %d bytes_written: %d chan: %d %s", frame_len, bytes_written, chan, chan_get (chan)); else if (ena_log_verbo) logd ("BIO_write() len: %d bytes_written: %d chan: %d %s", frame_len, bytes_written, chan, chan_get (chan)); int bytes_read = SSL_read (hu_ssl_ssl, &temp_assembly_buffer[cur_vec], frame_len); // Read decrypted to decrypted rx buf if (bytes_read <= 0 || bytes_read > frame_len) { loge ("SSL_read() bytes_read: %d errno: %d", bytes_read, errno); hu_ssl_ret_log (bytes_read); return (-1); // Fatal so return error and de-initialize; Should we be able to recover, if Transport data got corrupted ?? } if (ena_log_verbo) logd ("SSL_read() bytes_read: %d", bytes_read); temp_assembly_buffer.resize(cur_vec + bytes_read); } else { temp_assembly_buffer.insert(temp_assembly_buffer.end(), &enc_buf[header_size], &enc_buf[frame_len+header_size]); } } const int buf_len = temp_assembly_buffer.size(); if (buf_len >= 2) { uint16_t msg_type = be16toh(*reinterpret_cast<uint16_t*>(temp_assembly_buffer.data())); ret = iaap_msg_process (chan, msg_type, &temp_assembly_buffer[2], buf_len - 2); // Decrypt & Process 1 received encrypted message if (ret < 0 && iaap_state != hu_STATE_STOPPED) { // If error... loge ("Error iaap_msg_process() ret: %d ", ret); return (ret); } } return (ret); // Return value from the last iaap_recv_dec_process() call; should be 0 }