TLSharp/TLSharp.Core/Auth/Step2_DHExchange.cs

136 lines
4.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; }
}
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;
2017-04-13 08:38:01 +02:00
using (var pqInnerData = new MemoryStream(255))
2016-04-18 12:50:57 +02:00
{
2017-04-13 08:38:01 +02:00
using (var pqInnerDataWriter = new BinaryWriter(pqInnerData))
2016-04-18 12:50:57 +02:00
{
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);
byte[] ciphertext = null;
byte[] targetFingerprint = null;
2017-04-13 08:38:01 +02:00
foreach (var fingerprint in fingerprints)
2016-04-18 12:50:57 +02:00
{
ciphertext = RSA.Encrypt(BitConverter.ToString(fingerprint).Replace("-", string.Empty),
2017-04-13 08:38:01 +02:00
pqInnerData.GetBuffer(), 0, (int) pqInnerData.Position);
2016-04-18 12:50:57 +02:00
if (ciphertext != null)
{
targetFingerprint = fingerprint;
break;
}
}
if (ciphertext == null)
throw new InvalidOperationException(
2017-04-13 08:38:01 +02:00
string.Format("not found valid key for fingerprints: {0}",
string.Join(", ", fingerprints)));
2016-04-18 12:50:57 +02:00
2017-04-13 08:38:01 +02:00
using (var reqDHParams = new MemoryStream(1024))
2016-04-18 12:50:57 +02:00
{
2017-04-13 08:38:01 +02:00
using (var reqDHParamsWriter = new BinaryWriter(reqDHParams))
2016-04-18 12:50:57 +02:00
{
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;
2017-04-13 08:38:01 +02:00
using (var responseStream = new MemoryStream(response, false))
2016-04-18 12:50:57 +02:00
{
2017-04-13 08:38:01 +02:00
using (var responseReader = new BinaryReader(responseStream))
2016-04-18 12:50:57 +02:00
{
2017-04-13 08:38:01 +02:00
var responseCode = responseReader.ReadUInt32();
2016-04-18 12:50:57 +02:00
if (responseCode == 0x79cb045d)
throw new InvalidOperationException("server_DH_params_fail: TODO");
if (responseCode != 0xd0e8075c)
throw new InvalidOperationException($"invalid response code: {responseCode}");
2017-04-13 08:38:01 +02:00
var nonceFromServer = responseReader.ReadBytes(16);
2016-04-18 12:50:57 +02:00
// TODO:!
/*
2015-09-28 04:01:17 +02:00
if (!nonceFromServer.SequenceEqual(nonce))
{
logger.debug("invalid nonce from server");
return null;
}
*/
2017-04-13 08:38:01 +02:00
var 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);
2017-04-13 08:38:01 +02:00
return new Step2_Response
2016-04-18 12:50:57 +02:00
{
EncryptedAnswer = encryptedAnswer,
ServerNonce = serverNonceFromServer,
Nonce = nonceFromServer,
NewNonce = newNonce
};
}
}
}
}
2017-04-13 08:38:01 +02:00
}