Skip to content

Commit

Permalink
Merge pull request #242 from dvsekhvalnov/issue_237-more-checks
Browse files Browse the repository at this point in the history
minor fixes and security guards
  • Loading branch information
dvsekhvalnov committed Apr 1, 2024
2 parents 58f4143 + df888c6 commit bd566a6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 14 deletions.
13 changes: 13 additions & 0 deletions UnitTests/TestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4725,6 +4725,19 @@ public void DecodeObject()
Assert.Equal("[email protected]", test.sub);
}

[Fact]
public void DecodeMalformedToken()
{
// 1 parts
Assert.Throws<JoseException>(() => Jose.JWT.Decode("eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0", testSuiteUtils.PubKey()));

// 2 parts
Assert.Throws<JoseException>(() => Jose.JWT.Decode("eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9", testSuiteUtils.PubKey()));

// 4 parts
Assert.Throws<JoseException>(() => Jose.JWT.Decode("eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJ1SDVxVThlN2JVZXhGYWh3IiwidGFnIjoiamdxc2czdHoyUGo0QmhEWU1xTnBrdyJ9.peAzKiVO3_w2tAlSzRZdqqQpnUSpgPDHi_xgTd6VzP4.o8bhvYO_UTkrsxQmm__nIg.MSmgetpjXHWMs0TyuGgmWd-msfbQ7oVWC4WuCJcfAsbhLU9kLDLrd0naL5f_UkWBaM04bfcc31K4FRN20IiUxcHzLnMR-lY-HkvRFWYdur-kLWw1UXjIlPOb0nqCuyd2FRpxMdSfFnYr5Us9T45cF7DdK8p4iA7KqPToMHWBsvAcET_ycMIoERqJrBuiJzh-j7UtDzH6KtUfgD4tzZAm3iM6HWT2lq25Pqsu4qf19LYXxZaMIiFwFKboeexkJ5E0hc7P-wIeknzFJaZhkb5P4g", aes128Key));
}

private static ECDiffieHellman Ecdh256Private(CngKeyUsages usage = CngKeyUsages.Signing)
{
byte[] x = { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
Expand Down
24 changes: 24 additions & 0 deletions UnitTestsNet40/TestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3031,6 +3031,30 @@ public void DecodeObject()
Assert.That(test.sub, Is.EqualTo("[email protected]"));
}

[Test]
[ExpectedException(typeof(JoseException))]

public void DecodeMalformedTokenOnePart()
{
Jose.JWT.Decode("eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0", PubKey());
}

[Test]
[ExpectedException(typeof(JoseException))]

public void DecodeMalformedTokenTwoPart()
{
Jose.JWT.Decode("eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9", PubKey());
}

[Test]
[ExpectedException(typeof(JoseException))]

public void DecodeMalformedTokenFourPart()
{
Jose.JWT.Decode("eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJ1SDVxVThlN2JVZXhGYWh3IiwidGFnIjoiamdxc2czdHoyUGo0QmhEWU1xTnBrdyJ9.peAzKiVO3_w2tAlSzRZdqqQpnUSpgPDHi_xgTd6VzP4.o8bhvYO_UTkrsxQmm__nIg.MSmgetpjXHWMs0TyuGgmWd-msfbQ7oVWC4WuCJcfAsbhLU9kLDLrd0naL5f_UkWBaM04bfcc31K4FRN20IiUxcHzLnMR-lY-HkvRFWYdur-kLWw1UXjIlPOb0nqCuyd2FRpxMdSfFnYr5Us9T45cF7DdK8p4iA7KqPToMHWBsvAcET_ycMIoERqJrBuiJzh-j7UtDzH6KtUfgD4tzZAm3iM6HWT2lq25Pqsu4qf19LYXxZaMIiFwFKboeexkJ5E0hc7P-wIeknzFJaZhkb5P4g", PubKey());
}

#region test utils

private RSACryptoServiceProvider PrivKey()
Expand Down
13 changes: 13 additions & 0 deletions UnitTestsNet46/TestSuite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5188,6 +5188,19 @@ public void DecodeObject()
Assert.Equal("[email protected]", test.sub);
}

[Fact]
public void DecodeMalformedToken()
{
// 1 parts
Assert.Throws<JoseException>(() => Jose.JWT.Decode("eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0", PubKey()));

// 2 parts
Assert.Throws<JoseException>(() => Jose.JWT.Decode("eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9", PubKey()));

// 4 parts
Assert.Throws<JoseException>(() => Jose.JWT.Decode("eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJ1SDVxVThlN2JVZXhGYWh3IiwidGFnIjoiamdxc2czdHoyUGo0QmhEWU1xTnBrdyJ9.peAzKiVO3_w2tAlSzRZdqqQpnUSpgPDHi_xgTd6VzP4.o8bhvYO_UTkrsxQmm__nIg.MSmgetpjXHWMs0TyuGgmWd-msfbQ7oVWC4WuCJcfAsbhLU9kLDLrd0naL5f_UkWBaM04bfcc31K4FRN20IiUxcHzLnMR-lY-HkvRFWYdur-kLWw1UXjIlPOb0nqCuyd2FRpxMdSfFnYr5Us9T45cF7DdK8p4iA7KqPToMHWBsvAcET_ycMIoERqJrBuiJzh-j7UtDzH6KtUfgD4tzZAm3iM6HWT2lq25Pqsu4qf19LYXxZaMIiFwFKboeexkJ5E0hc7P-wIeknzFJaZhkb5P4g", aes128Key));
}

#region Test Utils

private static RSACryptoServiceProvider PrivKey()
Expand Down
24 changes: 12 additions & 12 deletions jose-jwt/JWT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ public static string Decode(string token, object key, JweAlgorithm alg, JweEncry
/// <exception cref="InvalidAlgorithmException">if JWT signature, encryption or compression algorithm is not supported</exception>
public static byte[] DecodeBytes(string token, object key, JweAlgorithm alg, JweEncryption enc, JwtSettings settings = null)
{
return DecodeBytes(token, key, null, alg, enc, settings);
return DecodeBytes(Compact.Iterate(token), key, null, alg, enc, settings);
}

/// <summary>
Expand Down Expand Up @@ -367,7 +367,7 @@ public static string Decode(string token, object key, JwsAlgorithm alg, JwtSetti
/// <exception cref="InvalidAlgorithmException">if JWT signature, encryption or compression algorithm is not supported</exception>
public static byte[] DecodeBytes(string token, object key, JwsAlgorithm alg, JwtSettings settings = null, byte[] payload = null)
{
return DecodeBytes(token, key, alg, null, null, settings, payload);
return DecodeBytes(Compact.Iterate(token), key, alg, null, null, settings, payload);
}

/// <summary>
Expand Down Expand Up @@ -401,7 +401,7 @@ public static string Decode(string token, object key = null, JwtSettings setting
/// <exception cref="InvalidAlgorithmException">if JWT signature, encryption or compression algorithm is not supported</exception>
public static byte[] DecodeBytes(string token, object key = null, JwtSettings settings = null, byte[] payload = null)
{
return DecodeBytes(token, key, null, null, null, settings, payload);
return DecodeBytes(Compact.Iterate(token), key, null, null, null, settings, payload);
}

/// <summary>
Expand Down Expand Up @@ -474,7 +474,7 @@ public static byte[] VerifyBytes(string token, object key, JwsAlgorithm? alg = n
throw new JoseException("Unexpected number of parts in signed token: " + parts.Count);
}

return DecodeBytes(token, key, alg, null, null, settings, payload);
return DecodeBytes(parts, key, alg, null, null, settings, payload);
}

public static string Decrypt(string token, object key, JweAlgorithm? alg = null, JweEncryption? enc = null, JwtSettings settings = null)
Expand All @@ -491,15 +491,13 @@ public static byte[] DecryptBytes(string token, object key, JweAlgorithm? alg =
throw new JoseException("Unexpected number of parts in encrypted token: " + parts.Count);
}

return DecodeBytes(token, key, null, alg, enc, settings);
return DecodeBytes(parts, key, null, alg, enc, settings);
}


private static byte[] DecodeBytes(string token, object key = null, JwsAlgorithm? expectedJwsAlg = null, JweAlgorithm? expectedJweAlg = null, JweEncryption? expectedJweEnc = null, JwtSettings settings = null, byte[] payload = null)
private static byte[] DecodeBytes(Compact.Iterator parts, object key = null, JwsAlgorithm? expectedJwsAlg = null, JweAlgorithm? expectedJweAlg = null, JweEncryption? expectedJweEnc = null, JwtSettings settings = null, byte[] payload = null)
{
Ensure.IsNotEmpty(token, "Incoming token expected to be in compact serialization form, not empty, whitespace or null.");

var parts = Compact.Iterate(token);
Ensure.IsNotEmpty(parts.Token, "Incoming token expected to be in compact serialization form, not empty, whitespace or null.");

if (parts.Count == 5) //encrypted JWT
{
Expand All @@ -508,9 +506,9 @@ private static byte[] DecodeBytes(string token, object key = null, JwsAlgorithm?
throw new InvalidAlgorithmException("Encrypted tokens can't assert signing algorithm type.");
}

return JWE.Decrypt(token, key, expectedJweAlg, expectedJweEnc, settings).PlaintextBytes;
return JWE.Decrypt(parts.Token, key, expectedJweAlg, expectedJweEnc, settings).PlaintextBytes;
}
else
else if (parts.Count == 3) // signed JWT
{
if (expectedJweAlg != null || expectedJweEnc !=null)
{
Expand Down Expand Up @@ -559,13 +557,15 @@ private static byte[] DecodeBytes(string token, object key = null, JwsAlgorithm?

return effectivePayload;
}

throw new JoseException("Expected compact serialized token with 3 or 5 parts, but got: " + parts.Count);
}

private static string Decode(string token, object key = null, JwsAlgorithm? jwsAlg = null, JweAlgorithm? jweAlg = null, JweEncryption? jweEnc = null, JwtSettings settings = null, string payload = null)
{
var detached = payload != null ? Encoding.UTF8.GetBytes(payload) : null;

var payloadBytes = DecodeBytes(token, key, jwsAlg, jweAlg, jweEnc, settings, detached);
var payloadBytes = DecodeBytes(Compact.Iterate(token), key, jwsAlg, jweAlg, jweEnc, settings, detached);

return Encoding.UTF8.GetString(payloadBytes);
}
Expand Down
11 changes: 9 additions & 2 deletions jose-jwt/util/Compact.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,18 @@ public static Iterator Iterate(string token)
if (token == null)
throw new ArgumentNullException(nameof(token));

return new Iterator(token.Split('.'));
return new Iterator(token, token.Split('.'));
}

public class Iterator
{
private string token;
private string[] parts;
private int current;

public Iterator(string[] parts)
public Iterator(string token, string[] parts)
{
this.token = token;
this.parts = parts;
this.current = 0;
}
Expand All @@ -91,6 +93,11 @@ public byte[] Next(bool decode = true)

return null;
}

public string Token
{
get { return token; }
}
}
}
}

0 comments on commit bd566a6

Please sign in to comment.