Skip to content

Commit bea54d9

Browse files
committed
Improve EdDSA/XDH key validation
1 parent 2618a7e commit bea54d9

12 files changed

+122
-26
lines changed

crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public Ed25519PrivateKeyParameters(SecureRandom random)
2424
Ed25519.GeneratePrivateKey(random, data);
2525
}
2626

27+
public Ed25519PrivateKeyParameters(byte[] buf)
28+
: this(Validate(buf), 0)
29+
{
30+
}
31+
2732
public Ed25519PrivateKeyParameters(byte[] buf, int off)
2833
: base(true)
2934
{
@@ -106,5 +111,13 @@ public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff
106111
}
107112
}
108113
}
114+
115+
private static byte[] Validate(byte[] buf)
116+
{
117+
if (buf.Length != KeySize)
118+
throw new ArgumentException("must have length " + KeySize, "buf");
119+
120+
return buf;
121+
}
109122
}
110123
}

crypto/src/crypto/parameters/Ed25519PublicKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public sealed class Ed25519PublicKeyParameters
1414

1515
private readonly byte[] data = new byte[KeySize];
1616

17+
public Ed25519PublicKeyParameters(byte[] buf)
18+
: this(Validate(buf), 0)
19+
{
20+
}
21+
1722
public Ed25519PublicKeyParameters(byte[] buf, int off)
1823
: base(false)
1924
{
@@ -36,5 +41,13 @@ public byte[] GetEncoded()
3641
{
3742
return Arrays.Clone(data);
3843
}
44+
45+
private static byte[] Validate(byte[] buf)
46+
{
47+
if (buf.Length != KeySize)
48+
throw new ArgumentException("must have length " + KeySize, "buf");
49+
50+
return buf;
51+
}
3952
}
4053
}

crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public Ed448PrivateKeyParameters(SecureRandom random)
2424
Ed448.GeneratePrivateKey(random, data);
2525
}
2626

27+
public Ed448PrivateKeyParameters(byte[] buf)
28+
: this(Validate(buf), 0)
29+
{
30+
}
31+
2732
public Ed448PrivateKeyParameters(byte[] buf, int off)
2833
: base(true)
2934
{
@@ -98,5 +103,13 @@ public void Sign(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff,
98103
}
99104
}
100105
}
106+
107+
private static byte[] Validate(byte[] buf)
108+
{
109+
if (buf.Length != KeySize)
110+
throw new ArgumentException("must have length " + KeySize, "buf");
111+
112+
return buf;
113+
}
101114
}
102115
}

crypto/src/crypto/parameters/Ed448PublicKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public sealed class Ed448PublicKeyParameters
1414

1515
private readonly byte[] data = new byte[KeySize];
1616

17+
public Ed448PublicKeyParameters(byte[] buf)
18+
: this(Validate(buf), 0)
19+
{
20+
}
21+
1722
public Ed448PublicKeyParameters(byte[] buf, int off)
1823
: base(false)
1924
{
@@ -36,5 +41,13 @@ public byte[] GetEncoded()
3641
{
3742
return Arrays.Clone(data);
3843
}
44+
45+
private static byte[] Validate(byte[] buf)
46+
{
47+
if (buf.Length != KeySize)
48+
throw new ArgumentException("must have length " + KeySize, "buf");
49+
50+
return buf;
51+
}
3952
}
4053
}

crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public X25519PrivateKeyParameters(SecureRandom random)
2222
X25519.GeneratePrivateKey(random, data);
2323
}
2424

25+
public X25519PrivateKeyParameters(byte[] buf)
26+
: this(Validate(buf), 0)
27+
{
28+
}
29+
2530
public X25519PrivateKeyParameters(byte[] buf, int off)
2631
: base(true)
2732
{
@@ -59,5 +64,13 @@ public void GenerateSecret(X25519PublicKeyParameters publicKey, byte[] buf, int
5964
if (!X25519.CalculateAgreement(data, 0, encoded, 0, buf, off))
6065
throw new InvalidOperationException("X25519 agreement failed");
6166
}
67+
68+
private static byte[] Validate(byte[] buf)
69+
{
70+
if (buf.Length != KeySize)
71+
throw new ArgumentException("must have length " + KeySize, "buf");
72+
73+
return buf;
74+
}
6275
}
6376
}

crypto/src/crypto/parameters/X25519PublicKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public sealed class X25519PublicKeyParameters
1414

1515
private readonly byte[] data = new byte[KeySize];
1616

17+
public X25519PublicKeyParameters(byte[] buf)
18+
: this(Validate(buf), 0)
19+
{
20+
}
21+
1722
public X25519PublicKeyParameters(byte[] buf, int off)
1823
: base(false)
1924
{
@@ -36,5 +41,13 @@ public byte[] GetEncoded()
3641
{
3742
return Arrays.Clone(data);
3843
}
44+
45+
private static byte[] Validate(byte[] buf)
46+
{
47+
if (buf.Length != KeySize)
48+
throw new ArgumentException("must have length " + KeySize, "buf");
49+
50+
return buf;
51+
}
3952
}
4053
}

crypto/src/crypto/parameters/X448PrivateKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public X448PrivateKeyParameters(SecureRandom random)
2222
X448.GeneratePrivateKey(random, data);
2323
}
2424

25+
public X448PrivateKeyParameters(byte[] buf)
26+
: this(Validate(buf), 0)
27+
{
28+
}
29+
2530
public X448PrivateKeyParameters(byte[] buf, int off)
2631
: base(true)
2732
{
@@ -59,5 +64,13 @@ public void GenerateSecret(X448PublicKeyParameters publicKey, byte[] buf, int of
5964
if (!X448.CalculateAgreement(data, 0, encoded, 0, buf, off))
6065
throw new InvalidOperationException("X448 agreement failed");
6166
}
67+
68+
private static byte[] Validate(byte[] buf)
69+
{
70+
if (buf.Length != KeySize)
71+
throw new ArgumentException("must have length " + KeySize, "buf");
72+
73+
return buf;
74+
}
6275
}
6376
}

crypto/src/crypto/parameters/X448PublicKeyParameters.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public sealed class X448PublicKeyParameters
1414

1515
private readonly byte[] data = new byte[KeySize];
1616

17+
public X448PublicKeyParameters(byte[] buf)
18+
: this(Validate(buf), 0)
19+
{
20+
}
21+
1722
public X448PublicKeyParameters(byte[] buf, int off)
1823
: base(false)
1924
{
@@ -36,5 +41,13 @@ public byte[] GetEncoded()
3641
{
3742
return Arrays.Clone(data);
3843
}
44+
45+
private static byte[] Validate(byte[] buf)
46+
{
47+
if (buf.Length != KeySize)
48+
throw new ArgumentException("must have length " + KeySize, "buf");
49+
50+
return buf;
51+
}
3952
}
4053
}

crypto/src/security/PrivateKeyFactory.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -174,26 +174,26 @@ public static AsymmetricKeyParameter CreateKey(
174174
}
175175
else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
176176
{
177-
return new X25519PrivateKeyParameters(GetRawKey(keyInfo, X25519PrivateKeyParameters.KeySize), 0);
177+
return new X25519PrivateKeyParameters(GetRawKey(keyInfo));
178178
}
179179
else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
180180
{
181-
return new X448PrivateKeyParameters(GetRawKey(keyInfo, X448PrivateKeyParameters.KeySize), 0);
181+
return new X448PrivateKeyParameters(GetRawKey(keyInfo));
182182
}
183183
else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
184184
{
185-
return new Ed25519PrivateKeyParameters(GetRawKey(keyInfo, Ed25519PrivateKeyParameters.KeySize), 0);
185+
return new Ed25519PrivateKeyParameters(GetRawKey(keyInfo));
186186
}
187187
else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
188188
{
189-
return new Ed448PrivateKeyParameters(GetRawKey(keyInfo, Ed448PrivateKeyParameters.KeySize), 0);
189+
return new Ed448PrivateKeyParameters(GetRawKey(keyInfo));
190190
}
191191
else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)
192192
|| algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256))
193193
{
194194
Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters);
195-
ECGost3410Parameters ecSpec = null;
196-
BigInteger d = null;
195+
ECGost3410Parameters ecSpec;
196+
BigInteger d;
197197
Asn1Object p = keyInfo.PrivateKeyAlgorithm.Parameters.ToAsn1Object();
198198
if (p is Asn1Sequence && (Asn1Sequence.GetInstance(p).Count == 2 || Asn1Sequence.GetInstance(p).Count == 3))
199199
{
@@ -280,13 +280,9 @@ public static AsymmetricKeyParameter CreateKey(
280280
}
281281
}
282282

283-
private static byte[] GetRawKey(PrivateKeyInfo keyInfo, int expectedSize)
283+
private static byte[] GetRawKey(PrivateKeyInfo keyInfo)
284284
{
285-
byte[] result = Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
286-
if (expectedSize != result.Length)
287-
throw new SecurityUtilityException("private key encoding has incorrect length");
288-
289-
return result;
285+
return Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets();
290286
}
291287

292288
public static AsymmetricKeyParameter DecryptKey(

crypto/src/security/PublicKeyFactory.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -217,19 +217,19 @@ public static AsymmetricKeyParameter CreateKey(
217217
}
218218
else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
219219
{
220-
return new X25519PublicKeyParameters(GetRawKey(keyInfo, X25519PublicKeyParameters.KeySize), 0);
220+
return new X25519PublicKeyParameters(GetRawKey(keyInfo));
221221
}
222222
else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
223223
{
224-
return new X448PublicKeyParameters(GetRawKey(keyInfo, X448PublicKeyParameters.KeySize), 0);
224+
return new X448PublicKeyParameters(GetRawKey(keyInfo));
225225
}
226226
else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
227227
{
228-
return new Ed25519PublicKeyParameters(GetRawKey(keyInfo, Ed25519PublicKeyParameters.KeySize), 0);
228+
return new Ed25519PublicKeyParameters(GetRawKey(keyInfo));
229229
}
230230
else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
231231
{
232-
return new Ed448PublicKeyParameters(GetRawKey(keyInfo, Ed448PublicKeyParameters.KeySize), 0);
232+
return new Ed448PublicKeyParameters(GetRawKey(keyInfo));
233233
}
234234
else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256)
235235
|| algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
@@ -282,17 +282,13 @@ public static AsymmetricKeyParameter CreateKey(
282282
}
283283
}
284284

285-
private static byte[] GetRawKey(SubjectPublicKeyInfo keyInfo, int expectedSize)
285+
private static byte[] GetRawKey(SubjectPublicKeyInfo keyInfo)
286286
{
287287
/*
288288
* TODO[RFC 8422]
289289
* - Require keyInfo.Algorithm.Parameters == null?
290290
*/
291-
byte[] result = keyInfo.PublicKeyData.GetOctets();
292-
if (expectedSize != result.Length)
293-
throw new SecurityUtilityException("public key encoding has incorrect length");
294-
295-
return result;
291+
return keyInfo.PublicKeyData.GetOctets();
296292
}
297293

298294
private static bool IsPkcsDHParam(Asn1Sequence seq)

0 commit comments

Comments
 (0)