Skip to content

Commit 759ddff

Browse files
committed
SM2 user ID length checks
1 parent 74fdc1b commit 759ddff

2 files changed

Lines changed: 33 additions & 18 deletions

File tree

crypto/src/crypto/agreement/SM2KeyExchange.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23

34
using Org.BouncyCastle.Crypto.Digests;
45
using Org.BouncyCastle.Crypto.Parameters;
@@ -40,15 +41,15 @@ public virtual void Init(ICipherParameters privParam)
4041
{
4142
SM2KeyExchangePrivateParameters baseParam;
4243

43-
if (privParam is ParametersWithID)
44+
if (privParam is ParametersWithID withID)
4445
{
45-
baseParam = (SM2KeyExchangePrivateParameters)((ParametersWithID)privParam).Parameters;
46-
mUserID = ((ParametersWithID)privParam).GetID();
46+
baseParam = (SM2KeyExchangePrivateParameters)withID.Parameters;
47+
mUserID = CheckUserID(withID.GetID());
4748
}
4849
else
4950
{
5051
baseParam = (SM2KeyExchangePrivateParameters)privParam;
51-
mUserID = new byte[0];
52+
mUserID = Array.Empty<byte>();
5253
}
5354

5455
mInitiator = baseParam.IsInitiator;
@@ -65,15 +66,15 @@ public virtual byte[] CalculateKey(int kLen, ICipherParameters pubParam)
6566
SM2KeyExchangePublicParameters otherPub;
6667
byte[] otherUserID;
6768

68-
if (pubParam is ParametersWithID)
69+
if (pubParam is ParametersWithID withID)
6970
{
70-
otherPub = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).Parameters;
71-
otherUserID = ((ParametersWithID)pubParam).GetID();
71+
otherPub = (SM2KeyExchangePublicParameters)withID.Parameters;
72+
otherUserID = CheckUserID(withID.GetID());
7273
}
7374
else
7475
{
7576
otherPub = (SM2KeyExchangePublicParameters)pubParam;
76-
otherUserID = new byte[0];
77+
otherUserID = Array.Empty<byte>();
7778
}
7879

7980
byte[] za = GetZ(mDigest, mUserID, mStaticPubPoint);
@@ -99,15 +100,15 @@ public virtual byte[][] CalculateKeyWithConfirmation(int kLen, byte[] confirmati
99100
SM2KeyExchangePublicParameters otherPub;
100101
byte[] otherUserID;
101102

102-
if (pubParam is ParametersWithID)
103+
if (pubParam is ParametersWithID withID)
103104
{
104-
otherPub = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).Parameters;
105-
otherUserID = ((ParametersWithID)pubParam).GetID();
105+
otherPub = (SM2KeyExchangePublicParameters)withID.Parameters;
106+
otherUserID = CheckUserID(withID.GetID());
106107
}
107108
else
108109
{
109110
otherPub = (SM2KeyExchangePublicParameters)pubParam;
110-
otherUserID = new byte[0];
111+
otherUserID = Array.Empty<byte>();
111112
}
112113

113114
if (mInitiator && confirmationTag == null)
@@ -256,19 +257,29 @@ private byte[] GetZ(IDigest digest, byte[] userID, ECPoint pubPoint)
256257
return DigestUtilities.DoFinal(digest);
257258
}
258259

259-
private void AddUserID(IDigest digest, byte[] userID)
260+
private static void AddUserID(IDigest digest, byte[] userID)
260261
{
261262
uint len = (uint)(userID.Length * 8);
263+
Debug.Assert(len >> 16 == 0);
262264

263265
digest.Update((byte)(len >> 8));
264266
digest.Update((byte)len);
265267
digest.BlockUpdate(userID, 0, userID.Length);
266268
}
267269

268-
private void AddFieldElement(IDigest digest, ECFieldElement v)
270+
private static void AddFieldElement(IDigest digest, ECFieldElement v)
269271
{
270272
byte[] p = v.GetEncoded();
271273
digest.BlockUpdate(p, 0, p.Length);
272274
}
275+
276+
private static byte[] CheckUserID(byte[] userID)
277+
{
278+
// The length in bits must be expressible in two bytes
279+
if (userID.Length >= 8192)
280+
throw new ArgumentException("SM2 user ID must be less than 2^16 bits long");
281+
282+
return userID;
283+
}
273284
}
274285
}

crypto/src/crypto/signers/SM2Signer.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23

34
using Org.BouncyCastle.Crypto.Digests;
45
using Org.BouncyCastle.Crypto.Parameters;
@@ -65,8 +66,9 @@ public virtual void Init(bool forSigning, ICipherParameters parameters)
6566
baseParam = withID.Parameters;
6667
userID = withID.GetID();
6768

69+
// The length in bits must be expressible in two bytes
6870
if (userID.Length >= 8192)
69-
throw new ArgumentException("SM2 user ID must be less than 2^13 bits long");
71+
throw new ArgumentException("SM2 user ID must be less than 2^16 bits long");
7072
}
7173
else
7274
{
@@ -287,15 +289,17 @@ private byte[] GetZ(byte[] userID)
287289
return DigestUtilities.DoFinal(digest);
288290
}
289291

290-
private void AddUserID(IDigest digest, byte[] userID)
292+
private static void AddUserID(IDigest digest, byte[] userID)
291293
{
292-
int len = userID.Length * 8;
294+
uint len = (uint)(userID.Length * 8);
295+
Debug.Assert(len >> 16 == 0);
296+
293297
digest.Update((byte)(len >> 8));
294298
digest.Update((byte)len);
295299
digest.BlockUpdate(userID, 0, userID.Length);
296300
}
297301

298-
private void AddFieldElement(IDigest digest, ECFieldElement v)
302+
private static void AddFieldElement(IDigest digest, ECFieldElement v)
299303
{
300304
byte[] p = v.GetEncoded();
301305
digest.BlockUpdate(p, 0, p.Length);

0 commit comments

Comments
 (0)