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

Stack parameters to improve reading of code. #3031

Merged
merged 1 commit into from
Dec 3, 2024
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
51 changes: 42 additions & 9 deletions src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,23 @@ internal AsymmetricAdapter(SecurityKey key, string algorithm, bool requirePrivat
{
}

internal AsymmetricAdapter(SecurityKey key, string algorithm, HashAlgorithm hashAlgorithm, HashAlgorithmName hashAlgorithmName, bool requirePrivateKey)
internal AsymmetricAdapter(
SecurityKey key,
string algorithm,
HashAlgorithm hashAlgorithm,
HashAlgorithmName hashAlgorithmName,
bool requirePrivateKey)
: this(key, algorithm, hashAlgorithm, requirePrivateKey)
{

HashAlgorithmName = hashAlgorithmName;
}

internal AsymmetricAdapter(SecurityKey key, string algorithm, HashAlgorithm hashAlgorithm, bool requirePrivateKey)
internal AsymmetricAdapter(
SecurityKey key,
string algorithm,
HashAlgorithm hashAlgorithm,
bool requirePrivateKey)
{
HashAlgorithm = hashAlgorithm;

Expand All @@ -79,15 +88,23 @@ internal AsymmetricAdapter(SecurityKey key, string algorithm, HashAlgorithm hash
else if (securityKey is ECDsaSecurityKey edcsaSecurityKeyFromJsonWebKey)
InitializeUsingEcdsaSecurityKey(edcsaSecurityKeyFromJsonWebKey);
else
throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10684, LogHelper.MarkAsNonPII(algorithm), key)));
throw LogHelper.LogExceptionMessage(
new NotSupportedException(
LogHelper.FormatInvariant(
LogMessages.IDX10684,
LogHelper.MarkAsNonPII(algorithm), key)));
}
}
else if (key is ECDsaSecurityKey ecdsaKey)
{
InitializeUsingEcdsaSecurityKey(ecdsaKey);
}
else
throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10684, LogHelper.MarkAsNonPII(algorithm), key)));
throw LogHelper.LogExceptionMessage(
new NotSupportedException(
LogHelper.FormatInvariant(
LogMessages.IDX10684,
LogHelper.MarkAsNonPII(algorithm), key)));
}

internal byte[] Decrypt(byte[] data)
Expand Down Expand Up @@ -233,7 +250,10 @@ private void InitializeUsingRsaSecurityKey(RsaSecurityKey rsaSecurityKey, string
}
}

private void InitializeUsingX509SecurityKey(X509SecurityKey x509SecurityKey, string algorithm, bool requirePrivateKey)
private void InitializeUsingX509SecurityKey(
X509SecurityKey x509SecurityKey,
string algorithm,
bool requirePrivateKey)
{
if (requirePrivateKey)
InitializeUsingRsa(x509SecurityKey.PrivateKey as RSA, algorithm);
Expand All @@ -249,7 +269,10 @@ internal byte[] Sign(byte[] bytes)
}

#if NET6_0_OR_GREATER
internal bool SignUsingSpan(ReadOnlySpan<byte> data, Span<byte> destination, out int bytesWritten)
internal bool SignUsingSpan(
ReadOnlySpan<byte> data,
Span<byte> destination,
out int bytesWritten)
{
return _signUsingSpanFunction(data, destination, out bytesWritten);
}
Expand All @@ -274,7 +297,10 @@ private static byte[] SignUsingOffsetNotFound(byte[] b, int c, int d)

#if NET6_0_OR_GREATER
#pragma warning disable CA1801 // Review unused parameters
private static bool SignUsingSpanNotFound(ReadOnlySpan<byte> data, Span<byte> destination, out int bytesWritten)
private static bool SignUsingSpanNotFound(
ReadOnlySpan<byte> data,
Span<byte> destination,
out int bytesWritten)
#pragma warning restore CA1801 // Review unused parameters
{
// we should never get here, its a bug if we do.
Expand All @@ -288,7 +314,10 @@ private byte[] SignECDsa(byte[] bytes)
}

#if NET6_0_OR_GREATER
internal bool SignUsingSpanECDsa(ReadOnlySpan<byte> data, Span<byte> destination, out int bytesWritten)
internal bool SignUsingSpanECDsa(
ReadOnlySpan<byte> data,
Span<byte> destination,
out int bytesWritten)
{
// ECDSA.TrySignData will return true and set bytesWritten = 64, if destination is null.
if (destination.Length == 0)
Expand Down Expand Up @@ -397,7 +426,11 @@ private bool VerifyUsingOffsetRsa(byte[] bytes, int offset, int count, byte[] si
#if NET6_0_OR_GREATER
return VerifyUsingSpan(isRSA: true, bytes.AsSpan(offset, count), signature);
#else
return RSA.VerifyHash(HashAlgorithm.ComputeHash(bytes, offset, count), signature, HashAlgorithmName, RSASignaturePadding);
return RSA.VerifyHash(
HashAlgorithm.ComputeHash(bytes, offset, count),
signature,
HashAlgorithmName,
RSASignaturePadding);
#endif
}

Expand Down
92 changes: 72 additions & 20 deletions src/Microsoft.IdentityModel.Tokens/AsymmetricSignatureProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class AsymmetricSignatureProvider : SignatureProvider
/// <summary>
/// Mapping from algorithm to minimum <see cref="AsymmetricSecurityKey"/>.KeySize when creating signatures.
/// </summary>
public static readonly Dictionary<string, int> DefaultMinimumAsymmetricKeySizeInBitsForSigningMap = new Dictionary<string, int>()
public static readonly Dictionary<string, int> DefaultMinimumAsymmetricKeySizeInBitsForSigningMap = new()
{
{ SecurityAlgorithms.EcdsaSha256, 256 },
{ SecurityAlgorithms.EcdsaSha384, 256 },
Expand All @@ -47,7 +47,7 @@ public class AsymmetricSignatureProvider : SignatureProvider
/// <summary>
/// Mapping from algorithm to minimum <see cref="AsymmetricSecurityKey"/>.KeySize when verifying signatures.
/// </summary>
public static readonly Dictionary<string, int> DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap = new Dictionary<string, int>()
public static readonly Dictionary<string, int> DefaultMinimumAsymmetricKeySizeInBitsForVerifyingMap = new()
{
{ SecurityAlgorithms.EcdsaSha256, 256 },
{ SecurityAlgorithms.EcdsaSha384, 256 },
Expand All @@ -69,13 +69,20 @@ public class AsymmetricSignatureProvider : SignatureProvider
{ SecurityAlgorithms.RsaSsaPssSha512Signature, 1040 }
};

internal AsymmetricSignatureProvider(SecurityKey key, string algorithm, CryptoProviderFactory cryptoProviderFactory)
internal AsymmetricSignatureProvider(
SecurityKey key,
string algorithm,
CryptoProviderFactory cryptoProviderFactory)
: this(key, algorithm)
{
_cryptoProviderFactory = cryptoProviderFactory;
}

internal AsymmetricSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures, CryptoProviderFactory cryptoProviderFactory)
internal AsymmetricSignatureProvider(
SecurityKey key,
string algorithm,
bool willCreateSignatures,
CryptoProviderFactory cryptoProviderFactory)
: this(key, algorithm, willCreateSignatures)
{
_cryptoProviderFactory = cryptoProviderFactory;
Expand Down Expand Up @@ -104,7 +111,10 @@ public AsymmetricSignatureProvider(SecurityKey key, string algorithm)
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="willCreateSignatures"/> is true and <see cref="SecurityKey.KeySize"/> is less than the required size for signing.</exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <see cref="SecurityKey.KeySize"/> is less than the required size for verifying signatures.</exception>
/// <exception cref="InvalidOperationException">Thrown if the runtime is unable to create a suitable cryptographic provider.</exception>
public AsymmetricSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
public AsymmetricSignatureProvider(
SecurityKey key,
string algorithm,
bool willCreateSignatures)
: base(key, algorithm)
{
_cryptoProviderFactory = key.CryptoProviderFactory;
Expand All @@ -116,13 +126,21 @@ public AsymmetricSignatureProvider(SecurityKey key, string algorithm, bool willC
JsonWebKeyConverter.TryConvertToSecurityKey(jsonWebKey, out SecurityKey _);

if (willCreateSignatures && FoundPrivateKey(key) == PrivateKeyStatus.DoesNotExist)
throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10638, key)));
throw LogHelper.LogExceptionMessage(
new InvalidOperationException(
LogHelper.FormatInvariant(LogMessages.IDX10638, key)));

if (!_cryptoProviderFactory.IsSupportedAlgorithm(algorithm, key))
throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10634, LogHelper.MarkAsNonPII((algorithm)), key)));
throw LogHelper.LogExceptionMessage(
new NotSupportedException(
LogHelper.FormatInvariant(
LogMessages.IDX10634,
LogHelper.MarkAsNonPII((algorithm)), key)));

WillCreateSignatures = willCreateSignatures;
_asymmetricAdapterObjectPool = new DisposableObjectPool<AsymmetricAdapter>(CreateAsymmetricAdapter, _cryptoProviderFactory.SignatureProviderObjectPoolCacheSize);
_asymmetricAdapterObjectPool = new DisposableObjectPool<AsymmetricAdapter>(
CreateAsymmetricAdapter,
_cryptoProviderFactory.SignatureProviderObjectPoolCacheSize);
}

/// <summary>
Expand Down Expand Up @@ -171,8 +189,13 @@ protected virtual HashAlgorithmName GetHashAlgorithmName(string algorithm)

private AsymmetricAdapter CreateAsymmetricAdapter()
{
var hashAlgoritmName = GetHashAlgorithmName(Algorithm);
return new AsymmetricAdapter(Key, Algorithm, _cryptoProviderFactory.CreateHashAlgorithm(hashAlgoritmName), hashAlgoritmName, WillCreateSignatures);
HashAlgorithmName hashAlgorithmName = GetHashAlgorithmName(Algorithm);
return new AsymmetricAdapter(
Key,
Algorithm,
_cryptoProviderFactory.CreateHashAlgorithm(hashAlgorithmName),
hashAlgorithmName,
WillCreateSignatures);
}

internal bool ValidKeySize()
Expand All @@ -188,7 +211,10 @@ internal bool ValidKeySize()

#if NET6_0_OR_GREATER
/// <inheritdoc/>
public override bool Sign(ReadOnlySpan<byte> input, Span<byte> signature, out int bytesWritten)
public override bool Sign(
ReadOnlySpan<byte> input,
Span<byte> signature,
out int bytesWritten)
{
if (input.Length == 0)
throw LogHelper.LogArgumentNullException(nameof(input));
Expand Down Expand Up @@ -219,12 +245,14 @@ public override bool Sign(ReadOnlySpan<byte> input, Span<byte> signature, out in
#endif

/// <summary>
/// Produces a signature over the 'input' using the <see cref="AsymmetricSecurityKey"/> and algorithm passed to <see cref="AsymmetricSignatureProvider( SecurityKey, string, bool )"/>.
/// Produces a signature over the 'input' using the <see cref="AsymmetricSecurityKey"/> and algorithm passed
/// to <see cref="AsymmetricSignatureProvider( SecurityKey, string, bool )"/>.
/// </summary>
/// <param name="input">The bytes to be signed.</param>
/// <returns>A signature over the input.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="input"/> is null or has length of 0.</exception>
/// <exception cref="ObjectDisposedException">Thrown If <see cref="AsymmetricSignatureProvider.Dispose(bool)"/> has been called.</exception>
/// <exception cref="ObjectDisposedException">Thrown if
/// <see cref="AsymmetricSignatureProvider.Dispose(bool)"/> has been called.</exception>
/// <remarks>Sign is thread safe.</remarks>
public override byte[] Sign(byte[] input)
{
Expand Down Expand Up @@ -317,23 +345,41 @@ public virtual void ValidateAsymmetricSecurityKeySize(SecurityKey key, string al
if (convertedSecurityKey is AsymmetricSecurityKey convertedAsymmetricKey)
keySize = convertedAsymmetricKey.KeySize;
else if (convertedSecurityKey is SymmetricSecurityKey)
throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10704, key)));
throw LogHelper.LogExceptionMessage(
new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10704, key)));
}
else
{
throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10704, key)));
throw LogHelper.LogExceptionMessage(
new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10704, key)));
}

if (willCreateSignatures)
{
if (MinimumAsymmetricKeySizeInBitsForSigningMap.ContainsKey(algorithm)
&& keySize < MinimumAsymmetricKeySizeInBitsForSigningMap[algorithm])
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10630, key, LogHelper.MarkAsNonPII(MinimumAsymmetricKeySizeInBitsForSigningMap[algorithm]), LogHelper.MarkAsNonPII(keySize))));
throw LogHelper.LogExceptionMessage(
new ArgumentOutOfRangeException(
nameof(key),
LogHelper.FormatInvariant(
LogMessages.IDX10630,
key,
LogHelper.MarkAsNonPII(
MinimumAsymmetricKeySizeInBitsForSigningMap[algorithm]),
LogHelper.MarkAsNonPII(keySize))));
}
else if (MinimumAsymmetricKeySizeInBitsForVerifyingMap.ContainsKey(algorithm)
&& keySize < MinimumAsymmetricKeySizeInBitsForVerifyingMap[algorithm])
{
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10631, key, LogHelper.MarkAsNonPII(MinimumAsymmetricKeySizeInBitsForVerifyingMap[algorithm]), LogHelper.MarkAsNonPII(keySize))));
throw LogHelper.LogExceptionMessage(
new ArgumentOutOfRangeException(
nameof(key),
LogHelper.FormatInvariant(
LogMessages.IDX10631,
key,
LogHelper.MarkAsNonPII(
MinimumAsymmetricKeySizeInBitsForVerifyingMap[algorithm]),
LogHelper.MarkAsNonPII(keySize))));
}
}

Expand Down Expand Up @@ -386,7 +432,13 @@ public override bool Verify(byte[] input, byte[] signature)
}

/// <inheritdoc/>
public override bool Verify(byte[] input, int inputOffset, int inputLength, byte[] signature, int signatureOffset, int signatureLength)
public override bool Verify(
byte[] input,
int inputOffset,
int inputLength,
byte[] signature,
int signatureOffset,
int signatureLength)
{
if (input == null || input.Length == 0)
throw LogHelper.LogArgumentNullException(nameof(input));
Expand Down Expand Up @@ -460,7 +512,7 @@ public override bool Verify(byte[] input, int inputOffset, int inputLength, byte
}
else
{
// AsymetricAdapter.Verify could do this.
// AsymmetricAdapter.Verify could do this.
// Having the logic here, handles EC and RSA. We can revisit when we start using spans in 3.1+.
byte[] signatureBytes = new byte[signatureLength];
Array.Copy(signature, 0, signatureBytes, 0, signatureLength);
Expand Down Expand Up @@ -490,7 +542,7 @@ protected override void Dispose(bool disposing)
_disposed = true;
if (disposing)
{
foreach (var item in _asymmetricAdapterObjectPool.Items)
foreach (DisposableObjectPool<AsymmetricAdapter>.Element item in _asymmetricAdapterObjectPool.Items)
item.Value?.Dispose();

CryptoProviderCache?.TryRemove(this);
Expand Down
Loading
Loading