Skip to content

Commit e3ec81c

Browse files
author
Jesper Glintborg
committed
Null termination is not a readable character, and encoded string should only be 40 characters long.
1 parent b69f707 commit e3ec81c

File tree

2 files changed

+39
-39
lines changed

2 files changed

+39
-39
lines changed

src/NetMQ.Tests/NetMQCertificateTest.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Xunit;
1+
using System;
2+
using Xunit;
23

34
namespace NetMQ.Tests
45
{
@@ -47,5 +48,18 @@ public void FromSecretKey()
4748
Assert.Equal(key.SecretKey, copy.SecretKey);
4849
Assert.Equal(key.PublicKey, copy.PublicKey);
4950
}
51+
52+
[Fact]
53+
public void InvalidKeyLength()
54+
{
55+
Assert.Throws<ArgumentException>(() => new NetMQCertificate("hkszCq4i}RDe:<!?NIDbGr0%Nl-CP9I^3h>TLT?", "hhRj/hiV-5CE(W!TLjLA%fGuxYmz9g}OZpJt2]cL"));
56+
Assert.Throws<ArgumentException>(() => new NetMQCertificate("hkszCq4i}RDe:<!?NIDbGr0%Nl-CP9I^3h>TLT?)", "hhRj/hiV-5CE(W!TLjLA%fGuxYmz9g}OZpJt2]c"));
57+
}
58+
59+
[Fact]
60+
public void InvalidKeyCharacter()
61+
{
62+
Assert.Throws<ArgumentException>(() => new NetMQCertificate(" kszCq4i}RDe:<!?NIDbGr0%Nl-CP9I^3h>TLT?)", "hhRj/hiV-5CE(W!TLjLA%fGuxYmz9g}OZpJt2]cL"));
63+
}
5064
}
5165
}

src/NetMQ/NetMQCertificate.cs

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,17 @@ public class NetMQCertificate
2828
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
2929
0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x4F, 0xFF, 0x50, 0xFF, 0xFF};
3030

31-
// --------------------------------------------------------------------------
32-
// Encode a binary frame as a string; destination string MUST be at least
33-
// size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns
34-
// dest. Size must be a multiple of 4.
35-
// Returns NULL for invalid input.
31+
/// <summary>
32+
/// Encodes Z85 string
33+
/// </summary>
34+
/// <param name="data">Data</param>
3635
private string Z85Encode(byte[] data)
3736
{
38-
if (data.Length % 4 != 0)
39-
{
40-
return null;
41-
}
42-
4337
byte byte_nbr = 0;
4438
UInt32 value = 0;
4539
string dest = null;
46-
while (byte_nbr<data.Length) {
40+
while (byte_nbr<data.Length)
41+
{
4742
// Accumulate value in base 256 (binary)
4843
value = value* 256 + data[byte_nbr++];
4944
if (byte_nbr % 4 == 0)
@@ -58,45 +53,41 @@ private string Z85Encode(byte[] data)
5853
value = 0;
5954
}
6055
}
61-
62-
dest += char.MinValue;
6356
return dest;
6457
}
6558

66-
67-
// --------------------------------------------------------------------------
68-
// Decode an encoded string into a binary frame; dest must be at least
69-
// strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string)
70-
// must be a multiple of 5.
71-
// Returns NULL for invalid input.
59+
/// <summary>
60+
/// Decodes Z85 string
61+
/// </summary>
62+
/// <param name="key">key in Z85 format</param>
63+
/// <exception cref="ArgumentException">If key in invalid</exception>
7264
byte[] Z85Decode(string key)
7365
{
7466
UInt32 byte_nbr = 0;
7567
UInt32 char_nbr = 0;
7668
UInt32 value = 0;
7769
var dest_ = new List<byte>();
78-
foreach (var cha in key.TakeWhile(c => c != char.MinValue))
70+
foreach (var cha in key)
7971
{
80-
8172
// Accumulate value in base 85
8273
if (UInt32.MaxValue / 85 < value)
8374
{
8475
// Invalid z85 encoding, represented value exceeds 0xffffffff
85-
return null;
76+
throw new ArgumentException("Invalid key bad encoding");
8677
}
8778
value *= 85;
8879
char_nbr++;
8980
var index = cha - 32;
9081
if (index >= Decoder.Length)
9182
{
9283
// Invalid z85 encoding, character outside range
93-
return null;
84+
throw new ArgumentException("Invalid key character");
9485
}
9586
UInt32 summand = Decoder[index];
9687
if (summand == 0xFF || summand > (UInt32.MaxValue - value))
9788
{
9889
// Invalid z85 encoding, invalid character or represented value exceeds 0xffffffff
99-
return null;
90+
throw new ArgumentException("Invalid key character");
10091
}
10192
value += summand;
10293
if (char_nbr % 5 == 0)
@@ -111,12 +102,7 @@ byte[] Z85Decode(string key)
111102
value = 0;
112103
}
113104
}
114-
if (char_nbr % 5 != 0)
115-
{
116-
return null;
117-
}
118105
return dest_.ToArray();
119-
120106
}
121107

122108
/// <summary>
@@ -152,14 +138,14 @@ public NetMQCertificate(byte[] secretKey, byte[] publicKey)
152138
/// </summary>
153139
/// <param name="secretKey">Secret key</param>
154140
/// <param name="publicKey">Public key</param>
155-
/// <exception cref="ArgumentException">If secretKey or publicKey are not 41-chars long</exception>
141+
/// <exception cref="ArgumentException">If secretKey or publicKey are not 40-chars long</exception>
156142
public NetMQCertificate(string secretKey, string publicKey)
157143
{
158-
if (secretKey.Length != 41)
159-
throw new ArgumentException("secretKey must be 41 char long");
144+
if (secretKey.Length != 40)
145+
throw new ArgumentException("secretKey must be 40 char long");
160146

161-
if (publicKey.Length != 41)
162-
throw new ArgumentException("publicKey must be 41 char long");
147+
if (publicKey.Length != 40)
148+
throw new ArgumentException("publicKey must be 40 char long");
163149

164150
SecretKey = Z85Decode(secretKey);
165151
PublicKey = Z85Decode(publicKey);
@@ -181,8 +167,8 @@ private NetMQCertificate(byte[] key, bool isSecret)
181167

182168
private NetMQCertificate(string keystr, bool isSecret)
183169
{
184-
if (keystr.Length != 41)
185-
throw new ArgumentException("key must be 41 bytes length");
170+
if (keystr.Length != 40)
171+
throw new ArgumentException("key must be 40 bytes length");
186172

187173
var key = Z85Decode(keystr);
188174
if (isSecret)
@@ -209,7 +195,7 @@ public NetMQCertificate FromSecretKey(byte[] secretKey)
209195
/// Create a certificate from secret key, public key is derived from the secret key
210196
/// </summary>
211197
/// <param name="secretKey">Secret Key</param>
212-
/// <exception cref="ArgumentException">If secret key is not 41-chars long</exception>
198+
/// <exception cref="ArgumentException">If secret key is not 40-chars long</exception>
213199
/// <returns>The newly created certificate</returns>
214200
public NetMQCertificate FromSecretKey(string secretKey)
215201
{
@@ -231,7 +217,7 @@ public static NetMQCertificate FromPublicKey(byte[] publicKey)
231217
/// Create a public key only certificate.
232218
/// </summary>
233219
/// <param name="publicKey">Public key</param>
234-
/// <exception cref="ArgumentException">If public key is not 41-chars long</exception>
220+
/// <exception cref="ArgumentException">If public key is not 40-chars long</exception>
235221
/// <returns>The newly created certificate</returns>
236222
public static NetMQCertificate FromPublicKey(string publicKey)
237223
{

0 commit comments

Comments
 (0)