Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Logging;

namespace Microsoft.IdentityModel.Tokens
Expand Down Expand Up @@ -32,6 +33,7 @@ private struct AuthenticatedKeys
private DecryptionDelegate DecryptFunction;
private EncryptionDelegate EncryptFunction;
private const string _className = "Microsoft.IdentityModel.Tokens.AuthenticatedEncryptionProvider";
internal const string _skipValidationOfAuthenticationTagLength = "Switch.Microsoft.IdentityModel.SkipAuthenticationTagLengthValidation";

/// <summary>
/// Initializes a new instance of the <see cref="AuthenticatedEncryptionProvider"/> class used for encryption and decryption.
Expand Down Expand Up @@ -165,6 +167,11 @@ private AuthenticatedEncryptionResult EncryptWithAesCbc(byte[] plaintext, byte[]
private byte[] DecryptWithAesCbc(byte[] ciphertext, byte[] authenticatedData, byte[] iv, byte[] authenticationTag)
{
// Verify authentication Tag
if (ShouldValidateAuthenticationTagLength()
&& SymmetricSignatureProvider.ExpectedSignatureSizeInBytes.TryGetValue(Algorithm, out int expectedTagLength)
&& expectedTagLength != authenticationTag.Length)
throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(LogHelper.FormatInvariant(LogMessages.IDX10625, Base64UrlEncoder.Encode(authenticationTag))));

byte[] al = Utility.ConvertToBigEndian(authenticatedData.Length * 8);
byte[] macBytes = new byte[authenticatedData.Length + iv.Length + ciphertext.Length + al.Length];
Array.Copy(authenticatedData, 0, macBytes, 0, authenticatedData.Length);
Expand All @@ -189,6 +196,11 @@ private byte[] DecryptWithAesCbc(byte[] ciphertext, byte[] authenticatedData, by
}
}

private static bool ShouldValidateAuthenticationTagLength()
{
return !(AppContext.TryGetSwitch(_skipValidationOfAuthenticationTagLength, out bool skipValidation) && skipValidation);
}

private AuthenticatedKeys CreateAuthenticatedKeys()
{
ValidateKeySize(Key, Algorithm);
Expand All @@ -201,7 +213,6 @@ internal SymmetricSignatureProvider CreateSymmetricSignatureProvider()
if (!IsSupportedAlgorithm(Key, Algorithm))
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10668, LogHelper.MarkAsNonPII(_className), LogHelper.MarkAsNonPII(Algorithm), Key)));

ValidateKeySize(Key, Algorithm);

SymmetricSignatureProvider symmetricSignatureProvider;

Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.IdentityModel.Tokens/LogMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ internal static class LogMessages
// public const string IDX10622 = "IDX10622:";
// public const string IDX10623 = "IDX10623:";
// public const string IDX10624 = "IDX10624:";
public const string IDX10625 = "IDX10625: Failed to verify the length of the authenticationTag '{0}'.";
// public const string IDX10627 = "IDX10627:";
public const string IDX10628 = "IDX10628: Cannot set the MinimumSymmetricKeySizeInBits to less than '{0}'.";
public const string IDX10630 = "IDX10630: The '{0}' for signing cannot be smaller than '{1}' bits. KeySize: '{2}'.";
Expand Down
Loading