TLSharp/TLSharp.Core/Auth/Step2_DHExchange.cs

167 lines
5.9 KiB
C#
Raw Normal View History

2015-09-28 04:01:17 +02:00
using System;
using System.Collections.Generic;
using System.IO;
using TLSharp.Core.MTProto;
using TLSharp.Core.MTProto.Crypto;
namespace TLSharp.Core.Auth
{
2016-04-18 12:50:57 +02:00
public class Step2_Response
{
public byte[] Nonce { get; set; }
public byte[] ServerNonce { get; set; }
public byte[] NewNonce { get; set; }
public byte[] EncryptedAnswer { get; set; }
2018-02-06 09:26:16 +01:00
public byte[] ToBytes()
{
const uint constructorNumber = 0xd0e8075c;
using (var memoryStream = new MemoryStream())
{
using (var binaryWriter = new BinaryWriter(memoryStream))
{
binaryWriter.Write(constructorNumber);
binaryWriter.Write(ServerNonce);
binaryWriter.Write(Nonce);
2018-02-07 16:20:36 +01:00
//binaryWriter.Write(EncryptedAnswer);
Serializers.Bytes.write(binaryWriter, EncryptedAnswer);
2018-02-06 09:26:16 +01:00
return memoryStream.ToArray();
}
}
}
2016-04-18 12:50:57 +02:00
}
public class Step2_DHExchange
{
public byte[] newNonce;
public Step2_DHExchange()
{
newNonce = new byte[32];
}
public byte[] ToBytes(byte[] nonce, byte[] serverNonce, List<byte[]> fingerprints, BigInteger pq)
{
new Random().NextBytes(newNonce);
var pqPair = Factorizator.Factorize(pq);
byte[] reqDhParamsBytes;
using (MemoryStream pqInnerData = new MemoryStream(255))
{
using (BinaryWriter pqInnerDataWriter = new BinaryWriter(pqInnerData))
{
pqInnerDataWriter.Write(0x83c95aec); // pq_inner_data
Serializers.Bytes.write(pqInnerDataWriter, pq.ToByteArrayUnsigned());
Serializers.Bytes.write(pqInnerDataWriter, pqPair.Min.ToByteArrayUnsigned());
Serializers.Bytes.write(pqInnerDataWriter, pqPair.Max.ToByteArrayUnsigned());
pqInnerDataWriter.Write(nonce);
pqInnerDataWriter.Write(serverNonce);
pqInnerDataWriter.Write(newNonce);
2018-02-24 21:46:54 +01:00
//TODO--change by main version code----
byte[] ciphertext = pqInnerData.ToArray();
byte[] targetFingerprint = fingerprints[0];
2016-04-18 12:50:57 +02:00
2018-02-24 21:46:54 +01:00
//byte[] ciphertext = null;
//byte[] targetFingerprint = null;
//foreach (byte[] fingerprint in fingerprints)
//{
// ciphertext = RSA.Encrypt(BitConverter.ToString(fingerprint).Replace("-", string.Empty),
// pqInnerData.GetBuffer(), 0, (int)pqInnerData.Position);
// if (ciphertext != null)
// {
// targetFingerprint = fingerprint;
// break;
// }
//}
//if (ciphertext == null)
//{
// throw new InvalidOperationException(
// String.Format("not found valid key for fingerprints: {0}", String.Join(", ", fingerprints)));
//}
2016-04-18 12:50:57 +02:00
using (MemoryStream reqDHParams = new MemoryStream(1024))
{
using (BinaryWriter reqDHParamsWriter = new BinaryWriter(reqDHParams))
{
reqDHParamsWriter.Write(0xd712e4be); // req_dh_params
reqDHParamsWriter.Write(nonce);
reqDHParamsWriter.Write(serverNonce);
Serializers.Bytes.write(reqDHParamsWriter, pqPair.Min.ToByteArrayUnsigned());
Serializers.Bytes.write(reqDHParamsWriter, pqPair.Max.ToByteArrayUnsigned());
reqDHParamsWriter.Write(targetFingerprint);
Serializers.Bytes.write(reqDHParamsWriter, ciphertext);
reqDhParamsBytes = reqDHParams.ToArray();
}
}
}
return reqDhParamsBytes;
}
}
public Step2_Response FromBytes(byte[] response)
{
byte[] encryptedAnswer;
using (MemoryStream responseStream = new MemoryStream(response, false))
{
using (BinaryReader responseReader = new BinaryReader(responseStream))
{
uint responseCode = responseReader.ReadUInt32();
if (responseCode == 0x79cb045d)
{
// server_DH_params_fail
throw new InvalidOperationException("server_DH_params_fail: TODO");
}
if (responseCode != 0xd0e8075c)
{
throw new InvalidOperationException($"invalid response code: {responseCode}");
}
byte[] nonceFromServer = responseReader.ReadBytes(16);
// TODO:!
/*
2015-09-28 04:01:17 +02:00
if (!nonceFromServer.SequenceEqual(nonce))
{
logger.debug("invalid nonce from server");
return null;
}
*/
2016-04-18 12:50:57 +02:00
byte[] serverNonceFromServer = responseReader.ReadBytes(16);
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
// TODO: !
/*
2015-09-28 04:01:17 +02:00
if (!serverNonceFromServer.SequenceEqual(serverNonce))
{
logger.error("invalid server nonce from server");
return null;
}
*/
2016-04-18 12:50:57 +02:00
encryptedAnswer = Serializers.Bytes.read(responseReader);
return new Step2_Response()
{
EncryptedAnswer = encryptedAnswer,
ServerNonce = serverNonceFromServer,
Nonce = nonceFromServer,
2018-02-14 09:45:14 +01:00
NewNonce = newNonce
2016-04-18 12:50:57 +02:00
};
}
}
}
}
2015-09-28 04:01:17 +02:00
}