Skip to content

Commit bdfd2cb

Browse files
[feature] Add protocol version check in session connection (#246)
1 parent 8da5fcb commit bdfd2cb

File tree

17 files changed

+982
-129
lines changed

17 files changed

+982
-129
lines changed

AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ Examples:
4242
- `[feature] Add user registration`
4343
- `[bugfix] Fix memory leak in sync module`
4444

45+
### PR Descriptions
46+
47+
- PR descriptions must be written in English.
48+
- Include a summary of the changes, main modifications, and implementation approach when relevant.
49+
4550
### Notes for Agents
4651
- Never propose changes directly on `master`.
4752
- Always create a branch using the proper prefix.

src/ByteSync.Client/Assets/Resources/Resources.Designer.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ByteSync.Client/Assets/Resources/Resources.fr.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,9 @@ Voulez-vous enregistrer ce nouveau Profil de Session avec ce nom ?</value>
15591559
<data name="JoinCloudSession_CanceledByUser" xml:space="preserve">
15601560
<value>Opération annulée par l'utilisateur.</value>
15611561
</data>
1562+
<data name="JoinCloudSession_IncompatibleProtocolVersion" xml:space="preserve">
1563+
<value>La version de votre application est incompatible avec cette session. Veuillez mettre à jour ByteSync pour rejoindre cette session.</value>
1564+
</data>
15621565
<data name="CreateCloudSession_CanceledByUser" xml:space="preserve">
15631566
<value>Opération annulée par l'utilisateur.</value>
15641567
</data>

src/ByteSync.Client/Assets/Resources/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,9 @@ Do you want to save this new Session Profile with this name?</value>
16011601
<data name="JoinCloudSession_CanceledByUser" xml:space="preserve">
16021602
<value>Operation canceled by the user.</value>
16031603
</data>
1604+
<data name="JoinCloudSession_IncompatibleProtocolVersion" xml:space="preserve">
1605+
<value>Your application version is incompatible with this session. Please update ByteSync to join this session.</value>
1606+
</data>
16041607
<data name="CreateCloudSession_CanceledByUser" xml:space="preserve">
16051608
<value>Operation canceled by the user.</value>
16061609
</data>

src/ByteSync.Client/Services/Communications/PublicKeysManager.cs

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Text;
44
using ByteSync.Business.Communications;
55
using ByteSync.Common.Business.EndPoints;
6-
using ByteSync.Common.Helpers;
6+
using ByteSync.Common.Business.Versions;
77
using ByteSync.Interfaces;
88
using ByteSync.Interfaces.Controls.Communications;
99
using ByteSync.Interfaces.Services.Communications;
@@ -16,56 +16,57 @@ public class PublicKeysManager : IPublicKeysManager
1616
private readonly IApplicationSettingsRepository _applicationSettingsRepository;
1717
private readonly IConnectionService _connectionService;
1818
private readonly ILogger<PublicKeysManager> _logger;
19-
19+
2020
public PublicKeysManager(IApplicationSettingsRepository applicationSettingsManager, IConnectionService connectionService,
2121
ILogger<PublicKeysManager> logger)
2222
{
2323
_applicationSettingsRepository = applicationSettingsManager;
2424
_connectionService = connectionService;
2525
_logger = logger;
2626
}
27-
27+
2828
public PublicKeyInfo GetMyPublicKeyInfo()
2929
{
3030
var applicationSettings = _applicationSettingsRepository.GetCurrentApplicationSettings();
31-
31+
3232
var myPublicKeyInfo = new PublicKeyInfo
3333
{
3434
ClientId = applicationSettings.ClientId,
3535
PublicKey = applicationSettings.DecodedRsaPublicKey!,
36+
ProtocolVersion = ProtocolVersion.CURRENT,
3637
};
37-
38+
3839
return myPublicKeyInfo;
3940
}
40-
41+
4142
public PublicKeyCheckData BuildJoinerPublicKeyCheckData(PublicKeyCheckData memberPublicKeyCheckData)
4243
{
4344
var joinerPublicKeyCheckData =
4445
BuildPublicKeyCheckData(memberPublicKeyCheckData.IssuerPublicKeyInfo, null, memberPublicKeyCheckData.Salt);
45-
46+
4647
return joinerPublicKeyCheckData;
4748
}
48-
49+
4950
public PublicKeyCheckData BuildMemberPublicKeyCheckData(PublicKeyInfo joinerPublicKeyInfo, bool isTrustedByMember)
5051
{
5152
var joinerPublicKeyCheckData =
5253
BuildPublicKeyCheckData(joinerPublicKeyInfo, isTrustedByMember, null);
53-
54+
5455
return joinerPublicKeyCheckData;
5556
}
56-
57+
5758
private PublicKeyCheckData BuildPublicKeyCheckData(PublicKeyInfo? otherPartyPublicKeyInfo, bool? checkResponse, string? salt)
5859
{
5960
var publicKeyCheckData = new PublicKeyCheckData();
6061

6162
publicKeyCheckData.IssuerPublicKeyInfo = GetMyPublicKeyInfo();
6263
publicKeyCheckData.IssuerClientInstanceId = _connectionService.ClientInstanceId!;
63-
64+
6465
publicKeyCheckData.OtherPartyPublicKeyInfo = otherPartyPublicKeyInfo;
6566

6667
var publicKeyFormatter = new PublicKeyFormatter();
6768
publicKeyCheckData.IssuerPublicKeyHash = publicKeyFormatter.Format(publicKeyCheckData);
68-
69+
6970
if (salt != null)
7071
{
7172
publicKeyCheckData.Salt = salt;
@@ -80,84 +81,86 @@ private PublicKeyCheckData BuildPublicKeyCheckData(PublicKeyInfo? otherPartyPubl
8081
// C'est supérieur à une recommandation "pseudo standard"
8182
publicKeyCheckData.Salt = RandomUtils.GetRandomLetters(12, null);
8283
}
83-
84+
8485
publicKeyCheckData.OtherPartyCheckResponse = checkResponse;
85-
86+
87+
publicKeyCheckData.ProtocolVersion = ProtocolVersion.CURRENT;
88+
8689
return publicKeyCheckData;
8790
}
88-
91+
8992
public bool IsTrusted(PublicKeyCheckData publicKeyCheckData)
9093
{
9194
return IsTrusted(publicKeyCheckData.IssuerPublicKeyInfo);
9295
}
93-
96+
9497
public bool IsTrusted(PublicKeyInfo publicKeyInfo)
9598
{
9699
var applicationSettings = _applicationSettingsRepository.GetCurrentApplicationSettings();
97100

98101
var trustedKey = applicationSettings.DecodedTrustedPublicKeys!
99102
.Where(tk => Equals(tk.ClientId, publicKeyInfo.ClientId))
100103
.MaxBy(tk => tk.ValidationDate);
101-
104+
102105
var result = false;
103106
if (trustedKey != null)
104107
{
105108
result = trustedKey.PublicKey.SequenceEqual(publicKeyInfo.PublicKey);
106109
}
107-
110+
108111
if (!result)
109112
{
110113
_logger.LogWarning("Public Key {@publicKeyInfo} is not trusted", publicKeyInfo);
111114
}
112-
115+
113116
return result;
114117
}
115-
118+
116119
public ReadOnlyCollection<TrustedPublicKey>? GetTrustedPublicKeys()
117120
{
118121
return _applicationSettingsRepository.GetCurrentApplicationSettings().DecodedTrustedPublicKeys;
119122
}
120-
123+
121124
public TrustedPublicKey BuildTrustedPublicKey(PublicKeyCheckData publicKeyCheckData)
122125
{
123126
var trustedPublicKey = new TrustedPublicKey();
124127
trustedPublicKey.ClientId = publicKeyCheckData.IssuerPublicKeyInfo.ClientId;
125128
trustedPublicKey.PublicKey = publicKeyCheckData.IssuerPublicKeyInfo.PublicKey;
126129
trustedPublicKey.ValidationDate = DateTimeOffset.Now;
127-
130+
128131
var publicKeyFormatter = new PublicKeyFormatter();
129132
trustedPublicKey.PublicKeyHash = publicKeyFormatter.Format(trustedPublicKey.PublicKey);
130-
133+
131134
var sha256PublicKeys = new List<string>();
132135
sha256PublicKeys.Add(CryptographyUtils.ComputeSHA256(publicKeyCheckData.IssuerPublicKeyInfo.PublicKey));
133136
sha256PublicKeys.Add(CryptographyUtils.ComputeSHA256(GetMyPublicKeyInfo().PublicKey));
134137
sha256PublicKeys.Sort();
135-
138+
136139
var precomputed = sha256PublicKeys[0] + "_" + sha256PublicKeys[1] + "_" + publicKeyCheckData.Salt;
137-
140+
138141
var md5 = CryptographyUtils.ComputeMD5FromText(precomputed);
139-
142+
140143
trustedPublicKey.SafetyKey = md5;
141-
144+
142145
return trustedPublicKey;
143146
}
144-
147+
145148
public void Trust(TrustedPublicKey trustedPublicKey)
146149
{
147-
_applicationSettingsRepository.UpdateCurrentApplicationSettings(settings =>
150+
_applicationSettingsRepository.UpdateCurrentApplicationSettings(settings =>
148151
settings.AddTrustedKey(trustedPublicKey));
149152

150153
_logger.LogInformation("Added Trusted Public Key {@publicKey}", trustedPublicKey);
151154
}
152-
155+
153156
public void Delete(TrustedPublicKey trustedPublicKey)
154157
{
155-
_applicationSettingsRepository.UpdateCurrentApplicationSettings(settings =>
158+
_applicationSettingsRepository.UpdateCurrentApplicationSettings(settings =>
156159
settings.RemoveTrustedKey(trustedPublicKey));
157160

158161
_logger.LogInformation("Removed Trusted Public Key {@publicKey}", trustedPublicKey);
159162
}
160-
163+
161164
public void InitializeRsaAndTrustedPublicKeys()
162165
{
163166
var updatedSettings = _applicationSettingsRepository.UpdateCurrentApplicationSettings(settings =>
@@ -169,31 +172,31 @@ public void InitializeRsaAndTrustedPublicKeys()
169172
_logger.LogInformation("Initialized Local RSA Keys and removed all Trusted Public Keys");
170173
_logger.LogInformation("ClientId is now {@clientId}", updatedSettings.ClientId);
171174
}
172-
175+
173176
public byte[] DecryptBytes(byte[] messageToDecrypt)
174177
{
175178
// On décrypte avec la clé privée
176179
var privateRsa = _applicationSettingsRepository.GetCurrentApplicationSettings()
177180
.PrivateRsa;
178181

179182
var decryptedBytes = privateRsa.Decrypt(messageToDecrypt, RSAEncryptionPadding.Pkcs1);
180-
183+
181184
return decryptedBytes;
182185
}
183-
186+
184187
public string DecryptString(byte[] messageToDecrypt)
185188
{
186189
// On décrypte avec la clé privée
187190
var privateRsa = _applicationSettingsRepository.GetCurrentApplicationSettings()
188191
.PrivateRsa;
189-
192+
190193
var decryptedBytes = privateRsa.Decrypt(messageToDecrypt, RSAEncryptionPadding.Pkcs1);
191-
194+
192195
var decryptedMessage = Encoding.UTF8.GetString(decryptedBytes);
193-
196+
194197
return decryptedMessage;
195198
}
196-
199+
197200
public byte[] EncryptString(PublicKeyInfo publicKeyInfo, string messageToEncrypt)
198201
{
199202
var bytes = Encoding.UTF8.GetBytes(messageToEncrypt);
@@ -203,10 +206,10 @@ public byte[] EncryptString(PublicKeyInfo publicKeyInfo, string messageToEncrypt
203206

204207
// On encrypte avec la clé de la tierce partie
205208
var result = rsa.Encrypt(bytes, RSAEncryptionPadding.Pkcs1);
206-
209+
207210
return result;
208211
}
209-
212+
210213
public byte[] SignData(string dataToEncrypt)
211214
{
212215
var bytes = Encoding.UTF8.GetBytes(dataToEncrypt);
@@ -218,7 +221,7 @@ public byte[] SignData(string dataToEncrypt)
218221

219222
// On encrypte avec la clé de la tierce partie
220223
var result = rsa.SignData(bytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
221-
224+
222225
return result;
223226
}
224227

@@ -232,21 +235,21 @@ public bool VerifyData(PublicKeyInfo publicKeyInfo, byte[] dataToVerify, string
232235

233236
var rsa = RSA.Create();
234237
rsa.ImportRSAPublicKey(publicKeyInfo.PublicKey, out _);
235-
238+
236239
// bool result = rsa.VerifyData(dataToVerify, signatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
237240
var result = rsa.VerifyData(signatureBytes, dataToVerify, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
238-
241+
239242
return result;
240243
}
241-
244+
242245
public byte[] EncryptBytes(PublicKeyInfo publicKeyInfo, byte[] messageToEncrypt)
243246
{
244247
var rsa = RSA.Create();
245248
rsa.ImportRSAPublicKey(publicKeyInfo.PublicKey, out _);
246249

247250
// On encrypte avec la clé de la tierce partie
248251
var result = rsa.Encrypt(messageToEncrypt, RSAEncryptionPadding.Pkcs1);
249-
252+
250253
return result;
251254
}
252255
}

0 commit comments

Comments
 (0)