private void ComputeSignatureValues(AKEKeys ake_keys, byte[] x_byte_array_data, UInt64 aes_counter, bool is_top_half_keys) { if (ake_keys == null) throw new ArgumentException("ComputeSignatureValues: AKE keys object should not be null"); if (is_top_half_keys == true && (ake_keys.GetAESKey1() == null || ake_keys.GetAESKey1().Length < 1)) throw new ArgumentException("ComputeSignatureValues: The AKE AES key 1 should not be null/empty"); if (is_top_half_keys == false && (ake_keys.GetAESKey2() == null || ake_keys.GetAESKey2().Length < 1)) throw new ArgumentException("ComputeSignatureValues: The AKE AES key 2 should not be null/empty"); if (x_byte_array_data == null || x_byte_array_data.Length < 1) throw new ArgumentException("ComputeSignatureValues: The x_byte_array_data cannot be null/empty"); if (aes_counter < 0) throw new ArgumentException("ComputeSignatureValues: The aes counter value cannot be less than zero"); byte[] _encrypted_signature_byte_array = null; if (is_top_half_keys == true) _encrypted_signature_byte_array = Utility.AESGetEncrypt(ake_keys.GetAESKey1(), x_byte_array_data, aes_counter); else _encrypted_signature_byte_array = Utility.AESGetEncrypt(ake_keys.GetAESKey2(), x_byte_array_data, aes_counter); try { Utility.EncodeOTRDataBE(_encrypted_signature_byte_array, ref _encoded_encrypted_signature_byte_array); } catch (Exception ex) { throw new InvalidDataException("ComputeSignatureValues:" + ex.ToString()); } if (is_top_half_keys == true && (ake_keys.GetMACKey2() == null || ake_keys.GetMACKey2().Length < 1)) throw new InvalidDataException("ComputeSignatureValues: The AKE MAC key 2 should not be null/empty"); if (is_top_half_keys == false && (ake_keys.GetMACKey4() == null || ake_keys.GetMACKey4().Length < 1)) throw new InvalidDataException("ComputeSignatureValues: The AKE MAC key 4 should not be null/empty"); if (is_top_half_keys == true) _hashed_encoded_encrypted_byte_array = Utility.SHA256GetKeyedHash(ake_keys.GetMACKey2(), _encoded_encrypted_signature_byte_array); else _hashed_encoded_encrypted_byte_array = Utility.SHA256GetKeyedHash(ake_keys.GetMACKey4(), _encoded_encrypted_signature_byte_array); _truncated_hash_signature = new byte[OTRConstants.MAC_SIGNATURE_LENGTH_BITS / 8]; Buffer.BlockCopy(_hashed_encoded_encrypted_byte_array, 0, _truncated_hash_signature, 0, _truncated_hash_signature.Length); }
private static bool IsEncryptedSignatureVerified(AKEKeys ake_keys, DHKeyPair key_pair, byte[] their_public_key_mpi_byte_array, byte[] encryted_byte_array, UInt64 counter, bool is_top_half_keys,ref UInt32 public_key_id, ref byte[] dsa_public_key_byte_array_encoded) { int _next_start_index = -1; bool _is_verified = false; byte[] _decrypted_x_data_array = null; byte[] _hashed_m_data_signature = null; byte[] _dh_kid_bytes = null; byte[] _temp_byte_array = null; byte[] _dsa_public_key_type = null; byte[] _dsa_public_key_param_p_mpi = null; byte[] _dsa_public_key_param_q_mpi = null; byte[] _dsa_public_key_param_g_mpi = null; byte[] _dsa_public_key_param_y_mpi = null; try { /*get encrypted signature bytes*/ _next_start_index = 0; _temp_byte_array = null; _next_start_index = Utility.DecodeDataFromBytesBE(encryted_byte_array, _next_start_index, ref _temp_byte_array); if (_temp_byte_array == null || _temp_byte_array.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The decoded Encrypted OTR Data type byte array cannot be null/empty"); if (is_top_half_keys == true) _decrypted_x_data_array = Utility.AESGetDecrypt(ake_keys.GetAESKey1(), _temp_byte_array, counter); else _decrypted_x_data_array = Utility.AESGetDecrypt(ake_keys.GetAESKey2(), _temp_byte_array, counter); if (_decrypted_x_data_array == null || _decrypted_x_data_array.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The decrypted byte array cannot be null/empty"); /*get public key parameter bytes*/ _next_start_index = 0; _temp_byte_array = null; //get public key type int _pub_key_start_index = _next_start_index; _next_start_index = Utility.DecodeShortFromBytes(_decrypted_x_data_array, _next_start_index, ref _dsa_public_key_type); if (_dsa_public_key_type == null || _dsa_public_key_type.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The decoded DSA public key type byte array cannot be null/empty"); if (BitConverter.ToUInt16(_dsa_public_key_type,0) != OTRConstants.DSA_PUB_KEY_TYPE) throw new InvalidDataException("IsEncryptedSignatureVerified: The DSA public key type is invalid"); //get MPI encoded DSA public key parameters _next_start_index = Utility.DecoupleMpiFromBytes(_decrypted_x_data_array, _next_start_index, ref _dsa_public_key_param_p_mpi); _next_start_index = Utility.DecoupleMpiFromBytes(_decrypted_x_data_array, _next_start_index, ref _dsa_public_key_param_q_mpi); _next_start_index = Utility.DecoupleMpiFromBytes(_decrypted_x_data_array, _next_start_index, ref _dsa_public_key_param_g_mpi); _next_start_index = Utility.DecoupleMpiFromBytes(_decrypted_x_data_array, _next_start_index, ref _dsa_public_key_param_y_mpi); int _pub_key_end_index = _next_start_index; //get the whole encoded DSA key dsa_public_key_byte_array_encoded = new byte[_pub_key_end_index - _pub_key_start_index]; Buffer.BlockCopy(_decrypted_x_data_array, _pub_key_start_index, dsa_public_key_byte_array_encoded, 0, dsa_public_key_byte_array_encoded.Length); DsaPublicKeyParameters _dsa_public_key_params = GetDSAPublicKeyParams(_dsa_public_key_param_p_mpi, _dsa_public_key_param_q_mpi, _dsa_public_key_param_g_mpi, _dsa_public_key_param_y_mpi); /*Get DH Key ID bytes*/ _next_start_index = Utility.DecodeIntFromBytes(_decrypted_x_data_array, _next_start_index, ref _dh_kid_bytes); if (_dh_kid_bytes == null || _dh_kid_bytes.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The decoded Key ID OTR Int type byte array cannot be null/empty"); public_key_id = BitConverter.ToUInt32(_dh_kid_bytes, 0); /*Get Signed M_b*/ _hashed_m_data_signature = new byte[_decrypted_x_data_array.Length - _next_start_index]; Buffer.BlockCopy(_decrypted_x_data_array, _next_start_index, _hashed_m_data_signature, 0, _hashed_m_data_signature.Length); if (_hashed_m_data_signature == null || _hashed_m_data_signature.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The extracted Signed byte array, M_b, cannot be null/empty"); /*Decode r and s */ _next_start_index = 0; byte[] _decoded_signature_r_byte_array = null; byte[] _decoded_signature_s_byte_array = null; _next_start_index = Utility.DecodeMacFromBytesBE(_hashed_m_data_signature, _next_start_index, ref _decoded_signature_r_byte_array); _next_start_index = Utility.DecodeMacFromBytesBE(_hashed_m_data_signature, _next_start_index, ref _decoded_signature_s_byte_array); if (_decoded_signature_r_byte_array == null || _decoded_signature_r_byte_array.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The decoded DSA signature parameter 'r' byte array cannot be null/empty"); if (_decoded_signature_s_byte_array == null || _decoded_signature_s_byte_array.Length < 1) throw new InvalidDataException("IsEncryptedSignatureVerified: The decoded DSA signature parameter 's' byte array cannot be null/empty"); /*Verify Signature*/ byte[] _hashed_m_data_byte_array = ComputeM(ake_keys, their_public_key_mpi_byte_array, key_pair.GetPublicKeyMpiBytes(), dsa_public_key_byte_array_encoded, _dh_kid_bytes, is_top_half_keys); _is_verified = DSASigner.VerifySignature(_dsa_public_key_params, _hashed_m_data_byte_array, _decoded_signature_r_byte_array, _decoded_signature_s_byte_array); } catch (Exception ex) { _is_verified = false; throw new InvalidDataException("IsEncryptedVerified:" + ex.ToString()); } return _is_verified; }