Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/commonTest.props
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkVersion)" />
<PackageReference Include="Moq" Version="$(MoqVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="xunit.runner.console" Version="$(XunitRunnerConsoleVersion)" />
Expand Down
6 changes: 6 additions & 0 deletions build/dependenciesTest.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
<DotNetCoreAppRuntimeVersion>2.1.30</DotNetCoreAppRuntimeVersion>
<MicrosoftAzureKeyVaultCryptographyVersion>3.0.5</MicrosoftAzureKeyVaultCryptographyVersion>
<MicrosoftNETTestSdkVersion>17.11.1</MicrosoftNETTestSdkVersion>
<!--
Locking the Moq version similar to https://github.com/Azure/azure-sdk-for-net/pull/38113/.
This version should not be changed without team discussion.
See https://github.com/Azure/azure-sdk-for-net/issues/38111.
-->
<MoqVersion>[4.16.1]</MoqVersion>
<NetStandardVersion>2.0.3</NetStandardVersion>
<NewtonsoftVersion>13.0.3</NewtonsoftVersion>
<OpenTelemetryVersion>1.6.0</OpenTelemetryVersion>
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ internal ValidationResult<string> DecryptToken(
ValidationError.GetCurrentStackFrame());
}

(IList<SecurityKey>? contentEncryptionKeys, ValidationError? validationError) result =
(IList<SecurityKey>? ContentEncryptionKeys, ValidationError? ValidationError) result =
GetContentEncryptionKeys(jwtToken, validationParameters, configuration, callContext);

if (result.validationError != null)
return result.validationError.AddCurrentStackFrame();
if (result.ValidationError != null)
return result.ValidationError.AddCurrentStackFrame();

if (result.contentEncryptionKeys == null || result.contentEncryptionKeys.Count == 0)
if (result.ContentEncryptionKeys == null || result.ContentEncryptionKeys.Count == 0)
{
return new ValidationError(
new MessageDetail(
Expand All @@ -68,15 +68,12 @@ internal ValidationResult<string> DecryptToken(
ValidationError.GetCurrentStackFrame());
}

var decryptionParameters = CreateJwtTokenDecryptionParameters(jwtToken, result.ContentEncryptionKeys);

return JwtTokenUtilities.DecryptJwtToken(
jwtToken,
validationParameters,
new JwtTokenDecryptionParameters
{
DecompressionFunction = JwtTokenUtilities.DecompressToken,
Keys = result.contentEncryptionKeys,
MaximumDeflateSize = MaximumTokenSizeInBytes
},
decryptionParameters,
callContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,28 @@ private string DecryptToken(JsonWebToken jwtToken, TokenValidationParameters val
throw LogHelper.LogExceptionMessage(new SecurityTokenException(LogHelper.FormatInvariant(TokenLogMessages.IDX10612)));

var keys = GetContentEncryptionKeys(jwtToken, validationParameters, configuration);
return JwtTokenUtilities.DecryptJwtToken(
jwtToken,
validationParameters,
new JwtTokenDecryptionParameters
{
DecompressionFunction = JwtTokenUtilities.DecompressToken,
Keys = keys,
MaximumDeflateSize = MaximumTokenSizeInBytes
});

var decryptionParameters = CreateJwtTokenDecryptionParameters(jwtToken, keys);

return JwtTokenUtilities.DecryptJwtToken(jwtToken, validationParameters, decryptionParameters);
}

private JwtTokenDecryptionParameters CreateJwtTokenDecryptionParameters(JsonWebToken jwtToken, IEnumerable<SecurityKey> keys)
{
return new JwtTokenDecryptionParameters
{
Alg = jwtToken.Alg,
AuthenticationTagBytes = jwtToken.AuthenticationTagBytes,
CipherTextBytes = jwtToken.CipherTextBytes,
DecompressionFunction = JwtTokenUtilities.DecompressToken,
Enc = jwtToken.Enc,
EncodedToken = jwtToken.EncodedToken,
HeaderAsciiBytes = jwtToken.HeaderAsciiBytes,
InitializationVectorBytes = jwtToken.InitializationVectorBytes,
MaximumDeflateSize = MaximumTokenSizeInBytes,
Keys = keys,
Zip = jwtToken.Zip,
};
}

private static SecurityKey ResolveTokenDecryptionKeyFromConfig(JsonWebToken jwtToken, BaseConfiguration configuration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using TokenLogMessages = Microsoft.IdentityModel.Tokens.LogMessages;

namespace Microsoft.IdentityModel.JsonWebTokens
{
Expand Down Expand Up @@ -120,7 +119,7 @@ internal static ValidationResult<string> DecryptJwtToken(
#pragma warning restore CA1031 // Do not catch general exception types
{
return new ValidationError(
new MessageDetail(TokenLogMessages.IDX10679, zipAlgorithm),
new MessageDetail(GetIDX10679LogMessage(zipAlgorithm)),
ValidationFailureType.TokenDecryptionFailed,
typeof(SecurityTokenDecompressionFailedException),
ValidationError.GetCurrentStackFrame(),
Expand Down
78 changes: 25 additions & 53 deletions src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,12 @@ internal static string DecompressToken(byte[] tokenBytes, string algorithm, int

var decompressedBytes = compressionProvider.Decompress(tokenBytes);

return decompressedBytes != null ? Encoding.UTF8.GetString(decompressedBytes) : throw LogHelper.LogExceptionMessage(new SecurityTokenDecompressionFailedException(LogHelper.FormatInvariant(TokenLogMessages.IDX10679, LogHelper.MarkAsNonPII(algorithm))));
return decompressedBytes != null ? Encoding.UTF8.GetString(decompressedBytes) : throw LogHelper.LogExceptionMessage(new SecurityTokenDecompressionFailedException(GetIDX10679LogMessage(algorithm)));
}

private static string GetIDX10679LogMessage(string algorithm)
{
return LogHelper.FormatInvariant(TokenLogMessages.IDX10679, LogHelper.MarkAsNonPII(algorithm));
}

/// <summary>
Expand Down Expand Up @@ -275,61 +280,28 @@ internal static string DecryptJwtToken(

try
{
// The JsonWebTokenHandler will set the JsonWebToken and those values will be used.
// The JwtSecurityTokenHandler will calculate values and set the values on DecryptionParameters.

// JsonWebToken from JsonWebTokenHandler
if (securityToken is JsonWebToken jsonWebToken)
if (!cryptoProviderFactory.IsSupportedAlgorithm(decryptionParameters.Enc, key))
{
if (!cryptoProviderFactory.IsSupportedAlgorithm(jsonWebToken.Enc, key))
{
if (LogHelper.IsEnabled(EventLogLevel.Warning))
LogHelper.LogWarning(TokenLogMessages.IDX10611, LogHelper.MarkAsNonPII(decryptionParameters.Enc), LogHelper.MarkAsNonPII(key.KeyId));

algorithmNotSupportedByCryptoProvider = true;
continue;
}
if (LogHelper.IsEnabled(EventLogLevel.Warning))
LogHelper.LogWarning(TokenLogMessages.IDX10611, LogHelper.MarkAsNonPII(decryptionParameters.Enc), LogHelper.MarkAsNonPII(key.KeyId));

Validators.ValidateAlgorithm(jsonWebToken.Enc, key, securityToken, validationParameters);
decryptedTokenBytes = DecryptToken(
cryptoProviderFactory,
key,
jsonWebToken.Enc,
jsonWebToken.CipherTextBytes,
jsonWebToken.HeaderAsciiBytes,
jsonWebToken.InitializationVectorBytes,
jsonWebToken.AuthenticationTagBytes);

zipAlgorithm = jsonWebToken.Zip;
decryptionSucceeded = true;
break;
algorithmNotSupportedByCryptoProvider = true;
continue;
}
// JwtSecurityToken from JwtSecurityTokenHandler
else
{
if (!cryptoProviderFactory.IsSupportedAlgorithm(decryptionParameters.Enc, key))
{
if (LogHelper.IsEnabled(EventLogLevel.Warning))
LogHelper.LogWarning(TokenLogMessages.IDX10611, LogHelper.MarkAsNonPII(decryptionParameters.Enc), LogHelper.MarkAsNonPII(key.KeyId));

algorithmNotSupportedByCryptoProvider = true;
continue;
}

Validators.ValidateAlgorithm(decryptionParameters.Enc, key, securityToken, validationParameters);
decryptedTokenBytes = DecryptToken(
cryptoProviderFactory,
key,
decryptionParameters.Enc,
decryptionParameters.CipherTextBytes,
decryptionParameters.HeaderAsciiBytes,
decryptionParameters.InitializationVectorBytes,
decryptionParameters.AuthenticationTagBytes);

zipAlgorithm = decryptionParameters.Zip;
decryptionSucceeded = true;
break;
}
Validators.ValidateAlgorithm(decryptionParameters.Enc, key, securityToken, validationParameters);
decryptedTokenBytes = DecryptToken(
cryptoProviderFactory,
key,
decryptionParameters.Enc,
decryptionParameters.CipherTextBytes,
decryptionParameters.HeaderAsciiBytes,
decryptionParameters.InitializationVectorBytes,
decryptionParameters.AuthenticationTagBytes);

zipAlgorithm = decryptionParameters.Zip;
decryptionSucceeded = true;
break;
}
catch (Exception ex)
{
Expand Down Expand Up @@ -361,7 +333,7 @@ internal static string DecryptJwtToken(
}
catch (Exception ex)
{
throw LogHelper.LogExceptionMessage(new SecurityTokenDecompressionFailedException(LogHelper.FormatInvariant(TokenLogMessages.IDX10679, zipAlgorithm), ex));
throw LogHelper.LogExceptionMessage(new SecurityTokenDecompressionFailedException(GetIDX10679LogMessage(zipAlgorithm), ex));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

<ItemGroup>
<AdditionalFiles Include="InternalAPI.Shipped.txt" />
<AdditionalFiles Include="InternalAPI.Unshipped.txt" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
Expand Down
11 changes: 9 additions & 2 deletions src/System.IdentityModel.Tokens.Jwt/JwtSecurityTokenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,7 +1762,14 @@ protected string DecryptToken(JwtSecurityToken jwtToken, TokenValidationParamete

var keys = GetContentEncryptionKeys(jwtToken, validationParameters);

return JwtTokenUtilities.DecryptJwtToken(jwtToken, validationParameters, new JwtTokenDecryptionParameters
var decryptionParameters = CreateJwtTokenDecryptionParameters(jwtToken, keys);

return JwtTokenUtilities.DecryptJwtToken(jwtToken, validationParameters, decryptionParameters);
}

private JwtTokenDecryptionParameters CreateJwtTokenDecryptionParameters(JwtSecurityToken jwtToken, IEnumerable<SecurityKey> keys)
{
return new JwtTokenDecryptionParameters
{
Alg = jwtToken.Header.Alg,
AuthenticationTagBytes = Base64UrlEncoder.DecodeBytes(jwtToken.RawAuthenticationTag),
Expand All @@ -1775,7 +1782,7 @@ protected string DecryptToken(JwtSecurityToken jwtToken, TokenValidationParamete
MaximumDeflateSize = MaximumTokenSizeInBytes,
Keys = keys,
Zip = jwtToken.Header.Zip,
});
};
}

internal IEnumerable<SecurityKey> GetContentEncryptionKeys(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)..\..\build\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Moq" Version="4.16.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.IdentityModel.Abstractions\Microsoft.IdentityModel.Abstractions.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.TestUtils;
Expand Down Expand Up @@ -2797,6 +2798,7 @@ public static TheoryData<CreateTokenTheoryData> RoundTripJWEDirectTestCases
EncryptingCredentials = Default.SymmetricEncryptingCredentials,
ExpectedException = ExpectedException.SecurityTokenDecryptionFailedException("IDX10603:")
},
GetTokenTheoryDataWithKeyId(),
new CreateTokenTheoryData()
{
TestId = "EncryptionAlgorithmNotSupported",
Expand All @@ -2812,6 +2814,38 @@ public static TheoryData<CreateTokenTheoryData> RoundTripJWEDirectTestCases
ExpectedException = ExpectedException.SecurityTokenDecryptionFailedException("IDX10619:")
},
};

static CreateTokenTheoryData GetTokenTheoryDataWithKeyId()
{
var validationParameters = new TokenValidationParameters
{
IssuerSigningKey = Default.SymmetricSigningKey256,
TokenDecryptionKey = NotDefault.SymmetricSigningKey256,
};

var keysAttempted = new StringBuilder().AppendLine(validationParameters.TokenDecryptionKey.KeyId);
var incompleteExceptionMessage = new MessageDetail(
Tokens.LogMessages.IDX10603,
LogHelper.MarkAsNonPII(keysAttempted.ToString()),
string.Empty, // Using empty since actual exception contains file paths, which are machine specific.
string.Empty) // Using empty since EncodedToken is not available and the message is getting used partially below.
.Message;
// Get partial messages as the actual exception message contains file paths.
var partialExceptionMessage = incompleteExceptionMessage.Substring(
0,
incompleteExceptionMessage.IndexOf(validationParameters.TokenDecryptionKey.KeyId) + validationParameters.TokenDecryptionKey.KeyId.Length);

return new CreateTokenTheoryData()
{
TestId = "EncryptionKey-Not-Found-Returns-KeyId-In-Error-Message",
IsValid = false,
ValidationParameters = validationParameters,
Payload = Default.PayloadString,
SigningCredentials = Default.SymmetricSigningCredentials,
EncryptingCredentials = Default.SymmetricEncryptingCredentials,
ExpectedException = ExpectedException.SecurityTokenDecryptionFailedException(partialExceptionMessage)
};
}
}
}

Expand Down
Loading
Loading