private void ProcessSignatureMessage(OTRMessage otr_message) { DebugPrint("Received Signature Message"); _otr_event_args = new OTREventArgs(); if (_authentication_state != OTR_AUTH_STATE.AUTH_STATE_AWAITING_SIG) { OTRError("ProcessSignatureMessage: OTR Engine is not in the AUTH_STATE_AWAITING_SIG state", "ProcessSignatureMessage: OTR Engine is not in the AUTH_STATE_AWAITING_SIG state", null); return; } if (otr_message.GetEncodedEncryptedSignature() == null || otr_message.GetEncodedEncryptedSignature().Length < 1) { OTRError("ProcessSignatureMessage: The encoded encrypted signature byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } if (otr_message.GetMacDSignature() == null || otr_message.GetMacDSignature().Length < 1) { OTRError("ProcessSignatureMessage: The MAC'd signature byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } _otr_event_args.SetOTREvent(OTR_EVENT.ERROR); byte[] dsa_public_key_byte_array_encoded = null; bool _is_sig_verified = SignatureManager.IsSignatureVerified(_ake_keys, _otr_session_object.GetMyRecentDHKeyPair(), _otr_session_object.GetBuddyRecentPublicKeyMpi(), otr_message.GetEncodedEncryptedSignature(), otr_message.GetMacDSignature(), false, ref _temp_int_32_val, ref dsa_public_key_byte_array_encoded); if (_otr_session_object.IsComputeBuddyFingerPrint(dsa_public_key_byte_array_encoded) == false) { OTRError("ProcessSignatureMessage:" + _my_buddy_unique_id + "'s DSA public key fingerprint computation failed", "ProcessSignatureMessage:" + _my_buddy_unique_id + "'s DSA public key fingerprint computation failed", null); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_NONE; return; } if (_is_sig_verified != true) { OTRError("ProcessSignatureMessage:" + _my_buddy_unique_id + "'s signature verification failed", "ProcessSignatureMessage:" + _my_buddy_unique_id + "'s signature verification failed", null); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_NONE; return; } /* Inform client of OTR readiness */ _otr_session_object.SetFirstBuddyPublicKeyID(_temp_int_32_val); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_NONE; _message_state = OTR_MESSAGE_STATE.MSG_STATE_ENCRYPTED; _otr_event_args.SetOTREvent(OTR_EVENT.READY); _otr_event_args.SetMessage(_my_buddy_unique_id + "'s signature verification successful"); DoOTREvent(_otr_event_args); }
private void ProcessDataMessage(OTRMessage otr_message) { DebugPrint("Received Data Message"); if (_message_state != OTR_MESSAGE_STATE.MSG_STATE_ENCRYPTED) { OTRError("ProcessDataMessage: OTR Engine is not in the MSG_STATE_ENCRYPTED state", "ProcessDataMessage: OTR Engine is not in the MSG_STATE_ENCRYPTED state", null); return; } /*Compute new keys */ DataExchangeKeys _data_exchange_keys = _otr_session_object.GetDataExchangeKeys(otr_message.GetRecipientKeyId(), _otr_message.GetSenderKeyId(), _otr_message.GetNextDHPublicKeyMpi(), _re_key_my_dh_keys); string _error_string = null; if (_data_exchange_keys == null) { if (otr_message.GetFlags() != OTRConstants.IGNORE_UNREADABLE) _error_string = "You transmitted an unreadable encrypted message"; OTRError("ProcessDataMessage: Data exchange keys are null", "ProcessDataMessage: Data exchange keys are null", _error_string); return; } /* Compute hash with MAC receiving key */ _temp_buffer = Utility.SHA1GetKeyedHash(_data_exchange_keys.GetMACKeyRecv(), otr_message.GetBytesToAuthenticate()); /* Compare hashed MAC */ if (Utility.IsArrayEqual(_temp_buffer, otr_message.GetAuthenticationMAC()) == false) { if (otr_message.GetFlags() != OTRConstants.IGNORE_UNREADABLE) _error_string = "You transmitted an unreadable encrypted message"; OTRError("Message MAC authentication failed", "Message MAC authentication failed", _error_string); return; } /* Decrypt message data */ try { _temp_buffer = Utility.AESGetDecrypt(_data_exchange_keys.GetAESKeyRecv(), otr_message.GetEncryptedData(), otr_message.GetCounterTopHalf()); _extra_symmetric_key_temp = _data_exchange_keys.GetAESKeyExtra(); } catch (Exception ex) { if (otr_message.GetFlags() != OTRConstants.IGNORE_UNREADABLE) _error_string = "You transmitted an unreadable encrypted message"; else _error_string = string.Empty; OTRError("ProcessDataMessage:Unable to decrypte message", "ProcessDataMessage:" + ex.ToString(), _error_string); _otr_fragment_object = null; return; } /* Process plain text */ if (_otr_fragment_object != null) { _otr_fragment_object.ClearCombinedString(); _otr_fragment_object = null; } ProcessPlaintext(_temp_buffer,_otr_message.GetOldMacKeys()); }
private void ProcessRevealSigMessage(OTRMessage otr_message) { DebugPrint("Received Reveal Signature Message"); _otr_event_args = new OTREventArgs(); if (_authentication_state != OTR_AUTH_STATE.AUTH_STATE_AWAITING_REVEAL_SIG) { OTRError("ProcessRevealSigMessage: OTR Engine is not in the AUTH_STATE_AWAITING_REVEAL_SIG state", "ProcessRevealSigMessage: OTR Engine is not in the AUTH_STATE_AWAITING_REVEAL_SIG state", null); return; } if (otr_message.GetRevealedKey() == null || otr_message.GetRevealedKey().Length < 1) { OTRError("ProcessRevealSigMessage: The AES revealed key byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } if (otr_message.GetEncodedEncryptedSignature() == null || otr_message.GetEncodedEncryptedSignature().Length < 1) { OTRError("ProcessRevealSigMessage: The encoded encrypted signature byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } if (otr_message.GetMacDSignature() == null || otr_message.GetMacDSignature().Length < 1) { OTRError("ProcessRevealSigMessage: The MAC'd signature byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } _otr_event_args.SetOTREvent(OTR_EVENT.ERROR); if (_dh_commit_message == null || _dh_commit_message.GetEncryptedGxMpi() == null || _dh_commit_message.GetEncryptedGxMpi().Length < 1) { OTRError("ProcessRevealSigMessage: The MPI encoded encrypted public key (g^x mpi) should not be null/empty", "ProcessRevealSigMessage: The MPI encoded encrypted public key (g^x mpi) should not be null/empty", "OTR Failed. Unexpected error"); return; } if (_otr_session_object.IsSetMyBuddyFirstPublicKey(otr_message.GetRevealedKey(), _dh_commit_message.GetEncryptedGxMpi(), _dh_commit_message.GetHashedGxMpi()) == false) { OTRError("ProcessRevealSigMessage: The MPI encoded decrypted public key (g^x mpi) should not be null/empty", "ProcessRevealSigMessage: The MPI encoded decrypted public key (g^x mpi) should not be null/empty", "OTR Failed. Unexpected error"); return; } _ake_keys = _ake_keys_manager.ComputeKeys(_otr_session_object.GetMyRecentDHKeyPair(), _otr_session_object.GetBuddyRecentPublicKey()); byte[] dsa_public_key_byte_array_encoded = null; bool _is_sig_verified = SignatureManager.IsSignatureVerified(_ake_keys, _otr_session_object.GetMyRecentDHKeyPair(), _otr_session_object.GetBuddyRecentPublicKeyMpi(), otr_message.GetEncodedEncryptedSignature(), otr_message.GetMacDSignature(), true, ref _temp_int_32_val, ref dsa_public_key_byte_array_encoded); if (_otr_session_object.IsComputeBuddyFingerPrint(dsa_public_key_byte_array_encoded) == false) { OTRError("ProcessRevealSigMessage:" + _my_buddy_unique_id + "'s DSA public key fingerprint computation failed", "ProcessRevealSigMessage:" + _my_buddy_unique_id + "'s DSA public key fingerprint computation failed", null); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_NONE; return; } if (_is_sig_verified != true) { OTRError("ProcessRevealSigMessage:" + _my_buddy_unique_id + "'s signature verification failed", "ProcessRevealSigMessage:" + _my_buddy_unique_id + "'s signature verification failed", "OTR Failed. Unexpected error"); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_NONE; return; } _signature_manager.ComputeSignature(_ake_keys, _otr_session_object.GetMyRecentDHKeyPair().GetPublicKeyMpiBytes(), _otr_session_object.GetMyRecentDHKeyPair().GetKeyIDBytes(), _otr_session_object.GetBuddyRecentPublicKeyMpi(), _otr_session_object.GetCounter(), false); //Send signature message byte[] _dh_signature_byte_array = _message_manager.FormatSignature(_signature_manager.GetSignatureDataBytes()); DebugPrint("Sending Signature Message"); SendOTRMessage(_dh_signature_byte_array); /* Inform client of OTR readiness */ _otr_session_object.SetFirstBuddyPublicKeyID(_temp_int_32_val); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_NONE; _message_state = OTR_MESSAGE_STATE.MSG_STATE_ENCRYPTED; _otr_event_args.SetOTREvent(OTR_EVENT.READY); _otr_event_args.SetMessage(_my_buddy_unique_id + "'s signature verification successful"); DoOTREvent(_otr_event_args); }
private void ProcessOTRMessage(string otr_message_string) { byte[] _message_byte_array = null; try { RemoveHeaderFooter(otr_message_string, ref _message_byte_array); if (_message_byte_array == null || _message_byte_array.Length < 1) { OTRError("The OTR data byte array cannot be null/empty", null, null); return; } OTR_VERSION _otr_version = MessageManager.GetMessageOTRVersion(_message_byte_array); if (_current_otr_version == OTR_VERSION.INVALID) { if (_otr_version == OTR_VERSION.INVALID) { OTRError("ProcessMessage: Received OTR version not supported.", "ProcessMessage: Received OTR version not supported.", null); return; } else SetOTRVersion(_otr_version); } else if (_current_otr_version != _otr_version) { OTRError("ProcessMessage: Received OTR version is invalid.", "ProcessMessage: Received OTR version is invalid.", null); return; } if (_message_byte_array == null || _message_byte_array.Length < 1) return; _otr_message = _message_manager.ExtractMessage(_message_byte_array); if (_otr_message == null) { OTRError("Received OTR message not properly formatted", null, "Message not properly formatted."); return; } switch (_otr_message.GetMessageType()) { case OTR_MESSAGE_TYPE.DH_COMMIT: ProcessDHCommitMessage(_otr_message); break; case OTR_MESSAGE_TYPE.DH_KEY: ProcessDHKeyMessage(_otr_message); break; case OTR_MESSAGE_TYPE.REVEAL_SIGNATURE: ProcessRevealSigMessage(_otr_message); break; case OTR_MESSAGE_TYPE.SIGNATURE: ProcessSignatureMessage(_otr_message); break; case OTR_MESSAGE_TYPE.DATA: ProcessDataMessage(_otr_message); break; default: OTRError("ProcessMessage: Invalid Message type.", "ProcessMessage: Invalid Message type.", "Message not properly formatted."); break; } } catch (Exception ex) { OTRError("ProcessOTRMesaage: Received OTR message not properly formatted", "ProcessOTRMesaage:" + ex.ToString(), "Message not properly formatted."); return; } }
private void ProcessDHKeyMessage(OTRMessage otr_message) { DebugPrint("Received DH Key Message"); _otr_event_args = new OTREventArgs(); if (_authentication_state != OTR_AUTH_STATE.AUTH_STATE_AWAITING_DH_KEY) { OTRError("ProcessDHKeyMessage: OTR Engine is not in the AUTH_STATE_AWAITING_DH_KEY state", "ProcessDHKeyMessage: OTR Engine is not in the AUTH_STATE_AWAITING_DH_KEY state", null); return; } if (otr_message.GetGxMpi() == null || otr_message.GetGxMpi().Length < 1) { OTRError("ProcessDHKeyMessage: The received MPI encoded public key byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } if (_otr_session_object.IsSetBuddyFirstPublicKey(otr_message.GetGxMpi()) == false) { OTRError("ProcessDHKeyMessage:" + _my_buddy_unique_id + "'s DH public key is invalid", "ProcessDHKeyMessage:" + _my_buddy_unique_id + "'s DH public key is invalid", "OTR Failed. Unexpected error"); return; } _ake_keys = _ake_keys_manager.ComputeKeys(_otr_session_object.GetMyRecentDHKeyPair(), _otr_session_object.GetBuddyRecentPublicKey()); _signature_manager.ComputeSignature(_ake_keys, _otr_session_object.GetMyRecentDHKeyPair().GetPublicKeyMpiBytes(), _otr_session_object.GetMyRecentDHKeyPair().GetKeyIDBytes(), otr_message.GetGxMpi(), _otr_session_object.GetCounter(), true); if (_aes_key == null || _aes_key.Length < 1) { OTRError("ProcessDHKeyMessage: The AES key byte array cannot be null/empty", null, "OTR Failed. Unexpected error"); return; } Utility.EncodeOTRDataBE(_aes_key, ref _temp_buffer); _temp_buffer_2 = new byte[_temp_buffer.Length + _signature_manager.GetSignatureDataLength()]; Buffer.BlockCopy(_temp_buffer, 0, _temp_buffer_2, 0, _temp_buffer.Length); Buffer.BlockCopy(_signature_manager.GetSignatureDataBytes(), 0, _temp_buffer_2, _temp_buffer.Length, _signature_manager.GetSignatureDataLength()); byte[] _dh_reveal_byte_array = _message_manager.FormatRevealSig(_temp_buffer_2); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_AWAITING_SIG; DebugPrint("Sending Reveal Signature Message"); SendOTRMessage(_dh_reveal_byte_array); }
private void ProcessDHCommitMessage(OTRMessage otr_message) { DebugPrint("Received DH Commit Message"); if (_authentication_state != OTR_AUTH_STATE.AUTH_STATE_NONE) { OTRError("ProcessDHCommitMessage: OTR Engine is not in the AUTH_STATE_NONE state", "ProcessDHCommitMessage: OTR Engine is not in the AUTH_STATE_NONE state", null); return; } _dh_commit_message = otr_message; byte[] _dh_key_message = _message_manager.FormatDHKey(_otr_session_object.GetMyRecentDHKeyPair().GetPublicKeyMpiBytes()); _authentication_state = OTR_AUTH_STATE.AUTH_STATE_AWAITING_REVEAL_SIG; DebugPrint("Sending DH Key Message"); SendOTRMessage(_dh_key_message); }
public OTRMessage ExtractMessage(byte[] in_message_byte_array) { int _next_index = 0; _otr_message = null; _temp_buffer = null; _message_type = OTR_MESSAGE_TYPE.INVALID; //get protocol version _next_index = Utility.DecodeShortFromBytes(in_message_byte_array, _next_index, ref _temp_buffer_2); OTR_VERSION _otr_version = Utility.GetOTRVersion(_temp_buffer_2); if (_otr_version == OTR_VERSION.INVALID) throw new ArgumentException("ExtractMessage:OTR version is invalid"); _otr_message = new OTRMessage(); _otr_message.SetProtocolVersion(_otr_version); // get message type _temp_buffer_2 = _temp_buffer = null; _next_index = Utility.DecodeByteFromBytes(in_message_byte_array, _next_index, ref _temp_buffer_2); _message_type = GetMessageType(_temp_buffer_2[0]); if (_message_type == OTR_MESSAGE_TYPE.INVALID) throw new ArgumentException("ExtractMessage:OTR message type is invalid"); _otr_message.SetMessageType(_message_type); //get instance tags if (_otr_version != OTR_VERSION.VERSION_2) { _temp_buffer_2 = _temp_buffer = null; _next_index = Utility.DecodeIntFromBytes(in_message_byte_array, _next_index, ref _temp_buffer_2); _otr_message.SetSenderInstanceTag(_temp_buffer_2); if (_otr_message.GetSenderInstanceTag() < 4) throw new ArgumentException("ExtractMessage:The Sender's instance tag cannot be less than 4"); if (_buddy_instance_tag == 0) _buddy_instance_tag = _otr_message.GetSenderInstanceTag(); if (_buddy_instance_tag != 0 && _otr_message.GetSenderInstanceTag() != _buddy_instance_tag) throw new ArgumentException("ExtractMessage:The Sender's instance tag is invalid"); _temp_buffer_2 = _temp_buffer = null; _next_index = Utility.DecodeIntFromBytes(in_message_byte_array, _next_index, ref _temp_buffer_2); _otr_message.SetReceiverInstanceTag(_temp_buffer_2); } if (_message_type == OTR_MESSAGE_TYPE.DATA) return ExtractData(in_message_byte_array, _next_index); else if (_message_type == OTR_MESSAGE_TYPE.DH_COMMIT) return ExtractDHCommit(in_message_byte_array, _next_index); else if (_message_type == OTR_MESSAGE_TYPE.DH_KEY) return ExtractDHKey(in_message_byte_array, _next_index); else if (_message_type == OTR_MESSAGE_TYPE.REVEAL_SIGNATURE) return ExtractRevealSig(in_message_byte_array, _next_index); else if (_message_type == OTR_MESSAGE_TYPE.SIGNATURE) return ExtractSignature(in_message_byte_array, _next_index); return null; }