Skip to content

Commit b94b25c

Browse files
committed
Sanity check length when deserializing
1 parent 337e0d3 commit b94b25c

File tree

2 files changed

+77
-31
lines changed

2 files changed

+77
-31
lines changed

libsignal-protocol-dotnet-tests/ecc/Curve25519Test.cs

+55-18
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,7 @@
1-
/**
2-
* Copyright (C) 2016 langboost
3-
*
4-
* This program is free software: you can redistribute it and/or modify
5-
* it under the terms of the GNU General Public License as published by
6-
* the Free Software Foundation, either version 3 of the License, or
7-
* (at your option) any later version.
8-
*
9-
* This program is distributed in the hope that it will be useful,
10-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-
* GNU General Public License for more details.
13-
*
14-
* You should have received a copy of the GNU General Public License
15-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
*/
17-
18-
using libsignal;
1+
using libsignal;
192
using libsignal.ecc;
203
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using System;
215

226
namespace libsignal_test
237
{
@@ -187,6 +171,59 @@ public void testSignature()
187171
}
188172
}
189173

174+
public void TestDecodeSize()
175+
{
176+
ECKeyPair keyPair = Curve.generateKeyPair();
177+
byte[] serializedPublic = keyPair.getPublicKey().serialize();
178+
179+
ECPublicKey justRight = Curve.decodePoint(serializedPublic, 0);
180+
181+
try
182+
{
183+
ECPublicKey tooSmall = Curve.decodePoint(serializedPublic, 1);
184+
Assert.Fail("Shouldn't decode");
185+
}
186+
catch (InvalidKeyException e)
187+
{
188+
// good
189+
}
190+
191+
try
192+
{
193+
ECPublicKey empty = Curve.decodePoint(new byte[0], 0);
194+
Assert.Fail("Shouldn't parse");
195+
}
196+
catch (InvalidKeyException e)
197+
{
198+
// good
199+
}
200+
201+
try
202+
{
203+
byte[] badKeyType = new byte[33];
204+
Array.Copy(serializedPublic, 0, badKeyType, 0, serializedPublic.Length);
205+
badKeyType[0] = 0x01;
206+
Curve.decodePoint(badKeyType, 0);
207+
Assert.Fail("Should be bad key type");
208+
}
209+
catch (InvalidKeyException e)
210+
{
211+
// good
212+
}
213+
214+
byte[] extraSpace = new byte[serializedPublic.Length + 1];
215+
Array.Copy(serializedPublic, 0, extraSpace, 0, serializedPublic.Length);
216+
ECPublicKey extra = Curve.decodePoint(extraSpace, 0);
217+
218+
byte[] offsetSpace = new byte[serializedPublic.Length + 1];
219+
Array.Copy(serializedPublic, 0, offsetSpace, 1, serializedPublic.Length);
220+
ECPublicKey offset = Curve.decodePoint(offsetSpace, 1);
221+
222+
CollectionAssert.AreEqual(serializedPublic, justRight.serialize());
223+
CollectionAssert.AreEqual(extra.serialize(), serializedPublic);
224+
CollectionAssert.AreEqual(offset.serialize(), serializedPublic);
225+
}
226+
190227
[TestMethod, TestCategory("libsignal.ecc")]
191228
public void testSignatureOverflow()
192229
{

libsignal-protocol-dotnet/ecc/Curve.cs

+22-13
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,28 @@ public static ECKeyPair generateKeyPair()
3434
new DjbECPrivateKey(keyPair.getPrivateKey()));
3535
}
3636

37-
public static ECPublicKey decodePoint(byte[] bytes, int offset)
38-
{
39-
int type = bytes[offset] & 0xFF;
40-
41-
switch (type)
42-
{
43-
case Curve.DJB_TYPE:
44-
byte[] keyBytes = new byte[32];
45-
System.Buffer.BlockCopy(bytes, offset + 1, keyBytes, 0, keyBytes.Length);
46-
return new DjbECPublicKey(keyBytes);
47-
default:
48-
throw new InvalidKeyException("Bad key type: " + type);
49-
}
37+
public static ECPublicKey decodePoint(byte[] bytes, int offset)
38+
{
39+
if (bytes.Length - offset < 1)
40+
{
41+
throw new InvalidKeyException("No key type identifier");
42+
}
43+
int type = bytes[offset] & 0xFF;
44+
45+
switch (type)
46+
{
47+
case Curve.DJB_TYPE:
48+
if (bytes.Length - offset < 33)
49+
{
50+
throw new InvalidKeyException("Bad key length: " + bytes.Length);
51+
}
52+
53+
byte[] keyBytes = new byte[32];
54+
System.Buffer.BlockCopy(bytes, offset + 1, keyBytes, 0, keyBytes.Length);
55+
return new DjbECPublicKey(keyBytes);
56+
default:
57+
throw new InvalidKeyException("Bad key type: " + type);
58+
}
5059
}
5160

5261
public static ECPrivateKey decodePrivatePoint(byte[] bytes)

0 commit comments

Comments
 (0)