Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify authentication tag length #2569

Merged
merged 11 commits into from
May 1, 2024
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";
kellyyangsong marked this conversation as resolved.
Show resolved Hide resolved

/// <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)
kellyyangsong marked this conversation as resolved.
Show resolved Hide resolved
&& 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);
kellyyangsong marked this conversation as resolved.
Show resolved Hide resolved

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}'.";
kellyyangsong marked this conversation as resolved.
Show resolved Hide resolved
// 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
Loading