Resolve Concelier/Excititor merge conflicts
This commit is contained in:
		
							
								
								
									
										66
									
								
								src/StellaOps.Auth.Security/Dpop/DpopNonceUtilities.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/StellaOps.Auth.Security/Dpop/DpopNonceUtilities.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace StellaOps.Auth.Security.Dpop;
 | 
			
		||||
 | 
			
		||||
internal static class DpopNonceUtilities
 | 
			
		||||
{
 | 
			
		||||
    private static readonly char[] Base64Padding = { '=' };
 | 
			
		||||
 | 
			
		||||
    internal static string GenerateNonce()
 | 
			
		||||
    {
 | 
			
		||||
        Span<byte> buffer = stackalloc byte[32];
 | 
			
		||||
        RandomNumberGenerator.Fill(buffer);
 | 
			
		||||
 | 
			
		||||
        return Convert.ToBase64String(buffer)
 | 
			
		||||
            .TrimEnd(Base64Padding)
 | 
			
		||||
            .Replace('+', '-')
 | 
			
		||||
            .Replace('/', '_');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static byte[] ComputeNonceHash(string nonce)
 | 
			
		||||
    {
 | 
			
		||||
        ArgumentException.ThrowIfNullOrWhiteSpace(nonce);
 | 
			
		||||
        var bytes = Encoding.UTF8.GetBytes(nonce);
 | 
			
		||||
        return SHA256.HashData(bytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static string EncodeHash(ReadOnlySpan<byte> hash)
 | 
			
		||||
        => Convert.ToHexString(hash);
 | 
			
		||||
 | 
			
		||||
    internal static string ComputeStorageKey(string audience, string clientId, string keyThumbprint)
 | 
			
		||||
    {
 | 
			
		||||
        ArgumentException.ThrowIfNullOrWhiteSpace(audience);
 | 
			
		||||
        ArgumentException.ThrowIfNullOrWhiteSpace(clientId);
 | 
			
		||||
        ArgumentException.ThrowIfNullOrWhiteSpace(keyThumbprint);
 | 
			
		||||
 | 
			
		||||
        return string.Create(
 | 
			
		||||
            "dpop-nonce:".Length + audience.Length + clientId.Length + keyThumbprint.Length + 2,
 | 
			
		||||
            (audience.Trim(), clientId.Trim(), keyThumbprint.Trim()),
 | 
			
		||||
            static (span, parts) =>
 | 
			
		||||
            {
 | 
			
		||||
                var index = 0;
 | 
			
		||||
                const string Prefix = "dpop-nonce:";
 | 
			
		||||
                Prefix.CopyTo(span);
 | 
			
		||||
                index += Prefix.Length;
 | 
			
		||||
 | 
			
		||||
                index = Append(span, index, parts.Item1);
 | 
			
		||||
                span[index++] = ':';
 | 
			
		||||
                index = Append(span, index, parts.Item2);
 | 
			
		||||
                span[index++] = ':';
 | 
			
		||||
                _ = Append(span, index, parts.Item3);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        static int Append(Span<char> span, int index, string value)
 | 
			
		||||
        {
 | 
			
		||||
            if (value.Length == 0)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentException("Value must not be empty after trimming.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            value.AsSpan().CopyTo(span[index..]);
 | 
			
		||||
            return index + value.Length;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user