Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CompressionAlgorithm"/> class.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="compressor"></param>
        public CompressionAlgorithm(sbyte id, string name, Compressor compressor)
        {
            if (name is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name);
            }

            if (compressor is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.compressor);
            }

            _id        = id;
            _utf8Name  = Utf8.GetBytes(name);
            Compressor = compressor;
        }
Example #2
0
        /// <inheritdoc/>
        public override string ToString()
        {
            using var bufferWriter = new PooledByteBufferWriter();
            using (var writer = new Utf8JsonWriter(bufferWriter, new JsonWriterOptions {
                Indented = true
            }))
            {
                writer.WriteStartObject();
                WriteTo(writer);
                writer.WriteEndObject();
            }

            var input = bufferWriter.WrittenSpan;

            return(Utf8.GetString(input));
        }
Example #3
0
 public static string TranscodeHelper(ReadOnlySpan <byte> utf8Unescaped)
 {
     try
     {
         return(Utf8.GetString(utf8Unescaped));
     }
     catch (DecoderFallbackException ex)
     {
         // We want to be consistent with the exception being thrown
         // so the user only has to catch a single exception.
         // Since we already throw InvalidOperationException for mismatch token type,
         // and while unescaping, using that exception for failure to decode invalid UTF-8 bytes as well.
         // Therefore, wrapping the DecoderFallbackException around an InvalidOperationException.
         //   throw ThrowHelper.GetInvalidOperationException_ReadInvalidUTF8(ex);
         throw new InvalidOperationException("Invalid UTF8", ex);
     }
 }
Example #4
0
 internal static int GetUtf8FromText(ReadOnlySpan <char> text, Span <byte> dest)
 {
     try
     {
         return(Utf8.GetBytes(text, dest));
     }
     catch (EncoderFallbackException ex)
     {
         // We want to be consistent with the exception being thrown
         // so the user only has to catch a single exception.
         // Since we already throw ArgumentException when validating other arguments,
         // using that exception for failure to encode invalid UTF-16 chars as well.
         // Therefore, wrapping the EncoderFallbackException around an ArgumentException.
         //throw  ThrowHelper.GetArgumentException_ReadInvalidUTF16(ex);
         throw new InvalidOperationException("Invalid UTF16", ex);
     }
 }
        /// <summary>Requires a least one audience contained in the <paramref name="audiences"/>.</summary>
        public TokenValidationPolicyBuilder RequireAudience(IEnumerable <string> audiences)
        {
            if (audiences == null)
            {
                throw new ArgumentNullException(nameof(audiences));
            }

            foreach (var audience in audiences)
            {
                if (audience != null)
                {
                    _audiences.Add(Utf8.GetBytes(audience));
                    _control |= TokenValidationPolicy.AudienceMask;
                }
            }

            return(this);
        }
Example #6
0
        /// <summary>Parses and validates a JWT encoded as a JWS or JWE in compact serialized format.</summary>
        /// <param name="token">The JWT encoded as JWE or JWS</param>
        /// <param name="policy">The validation policy.</param>
        /// <param name="jwt">The resulting <see cref="Jwt"/>.</param>
        public static bool TryParse(string token, TokenValidationPolicy policy, out Jwt jwt)
        {
            if (token is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.token);
            }

            if (policy is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.policy);
            }

            if (token.Length == 0)
            {
                jwt = new Jwt(TokenValidationError.MalformedToken());
                return(false);
            }

            int length = Utf8.GetMaxByteCount(token.Length);

            if (length > policy.MaximumTokenSizeInBytes)
            {
                jwt = new Jwt(TokenValidationError.MalformedToken());
                return(false);
            }

            byte[]? utf8ArrayToReturnToPool = null;
            var utf8Token = length <= Constants.MaxStackallocBytes
                  ? stackalloc byte[length]
                  : (utf8ArrayToReturnToPool = ArrayPool <byte> .Shared.Rent(length));

            try
            {
                int bytesWritten = Utf8.GetBytes(token, utf8Token);
                return(TryParse(utf8Token.Slice(0, bytesWritten), policy, out jwt));
            }
            finally
            {
                if (utf8ArrayToReturnToPool != null)
                {
                    ArrayPool <byte> .Shared.Return(utf8ArrayToReturnToPool);
                }
            }
        }
Example #7
0
        /// <summary>Decodes a span of UTF-8 base64-encoded text into a span of bytes.</summary>
        /// <returns>The number of the bytes written to <paramref name="data"/>.</returns>
        public static int Decode(ReadOnlySpan <char> base64, Span <byte> data)
        {
            byte[]? arrayToReturn = null;
            var buffer = base64.Length > Constants.MaxStackallocBytes
                ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(base64.Length))
                : stackalloc byte[Constants.MaxStackallocBytes];

            try
            {
                int length = Utf8.GetBytes(base64, buffer);
                return(Decode(buffer.Slice(0, length), data));
            }
            finally
            {
                if (arrayToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(arrayToReturn);
                }
            }
        }
Example #8
0
        /// <summary>
        /// Encodes a string of UTF-8 text.
        /// </summary>
        /// <returns>The base64-url encoded string.</returns>
        public static byte[] Encode(ReadOnlySpan <char> data)
        {
            byte[]? utf8ArrayToReturn = null;
            try
            {
                var utf8Data = data.Length > Constants.MaxStackallocBytes
                    ? (utf8ArrayToReturn = ArrayPool <byte> .Shared.Rent(data.Length)).AsSpan(0, data.Length)
                    : stackalloc byte[data.Length];

                Utf8.GetBytes(data, utf8Data);
                return(Encode(utf8Data));
            }
            finally
            {
                if (utf8ArrayToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(utf8ArrayToReturn);
                }
            }
        }
Example #9
0
        /// <summary>
        /// Decodes a span of UTF-8 base64url-encoded text into a span of bytes.
        /// </summary>
        /// <returns>The number of the bytes written to <paramref name="data"/>.</returns>
        public static int Decode(ReadOnlySpan <char> base64Url, Span <byte> data)
        {
            byte[]? arrayToReturn = null;
            var buffer = base64Url.Length > Constants.MaxStackallocBytes
                ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(base64Url.Length)).AsSpan(0, base64Url.Length)
                : stackalloc byte[base64Url.Length];

            try
            {
                Utf8.GetBytes(base64Url, buffer);
                return(Decode(buffer, data));
            }
            finally
            {
                if (arrayToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(arrayToReturn);
                }
            }
        }
Example #10
0
        /// <summary>Encodes a string of UTF-8 text.</summary>
        /// <returns>The base64-url encoded string.</returns>
        /// <remarks>This method allocate an array of bytes. Use <see cref="Encode(ReadOnlySpan{byte}, Span{byte})"/> when possible.</remarks>
        public static byte[] Encode(ReadOnlySpan <char> data)
        {
            byte[]? utf8ArrayToReturn = null;
            try
            {
                int length   = Utf8.GetMaxByteCount(data.Length);
                var utf8Data = length > Constants.MaxStackallocBytes
                    ? (utf8ArrayToReturn = ArrayPool <byte> .Shared.Rent(length))
                    : stackalloc byte[Constants.MaxStackallocBytes];

                int written = Utf8.GetBytes(data, utf8Data);
                return(Encode(utf8Data.Slice(0, written)));
            }
            finally
            {
                if (utf8ArrayToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(utf8ArrayToReturn);
                }
            }
        }
Example #11
0
        /// <inheritsdoc />
        public override void Encode(EncodingContext context, IBufferWriter <byte> output)
        {
            int payloadLength = Utf8.GetMaxByteCount(Payload.Length);

            byte[]? payloadToReturnToPool = null;
            Span <byte> encodedPayload = payloadLength > Constants.MaxStackallocBytes
                             ? (payloadToReturnToPool = ArrayPool <byte> .Shared.Rent(payloadLength))
                             : stackalloc byte[payloadLength];

            try
            {
                int bytesWritten = Utf8.GetBytes(Payload, encodedPayload);
                EncryptToken(context, encodedPayload.Slice(0, bytesWritten), output);
            }
            finally
            {
                if (payloadToReturnToPool != null)
                {
                    ArrayPool <byte> .Shared.Return(payloadToReturnToPool);
                }
            }
        }
Example #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="JwtHeader"/> class.
 /// </summary>
 /// <param name="json"></param>
 public static JwtHeader FromJson(string json)
 {
     return(JwtHeaderParser.ParseHeader(Utf8.GetBytes(json), TokenValidationPolicy.NoValidation));
 }
 /// <summary>Requires the specified claim.</summary>
 public TokenValidationPolicyBuilder RequireClaim(ReadOnlySpan <byte> requiredClaim)
 => RequireClaim(Utf8.GetString(requiredClaim));
Example #14
0
 /// <summary>
 /// Adds a claim.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="value"></param>
 /// <returns></returns>
 public void AddClaim(string name, JwtProperty value)
 => AddClaim(Utf8.GetBytes(name), value);
Example #15
0
 /// <summary>
 /// Gets or sets the <see cref="JwtProperty"/> at the specified key;
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public JwtProperty this[string key] => this[Utf8.GetBytes(key).AsSpan()];
Example #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Jwk"/> class.
 /// </summary>
 /// <param name="alg"></param>
 protected Jwk(string alg)
 {
     Alg = Utf8.GetBytes(alg);
 }
Example #17
0
 /// <summary>
 /// Writes a JWT in its compact serialization format and returns it a string.
 /// </summary>
 /// <param name="descriptor">The descriptor of the JWT.</param>
 /// <returns>The <see cref="string"/> retpresention of the JWT.</returns>
 public string WriteTokenString(JwtDescriptor descriptor)
 {
     using var bufferWriter = new PooledByteBufferWriter();
     WriteToken(descriptor, bufferWriter);
     return(Utf8.GetString(bufferWriter.WrittenSpan));
 }
 public MultiIssuersSignatureValidationPolicy(Dictionary <string, SignatureValidationPolicy> policies, SignatureValidationPolicy defaultPolicy)
 {
     _policies      = policies.ToDictionary(issuer => Utf8.GetBytes(issuer.Key), v => v.Value).ToArray();
     _defaultPolicy = defaultPolicy;
 }
Example #19
0
 static RsaJwk()
 {
     Utf8.AssertMagicNumber(qi, "qi");
     Utf8.AssertMagicNumber(dp, "dp");
     Utf8.AssertMagicNumber(dq, "dq");
 }
Example #20
0
        internal bool TryGetNamedPropertyValue(ReadOnlySpan <char> propertyName, out JwtElement value)
        {
            JsonRow row;

            int maxBytes = Utf8.GetMaxByteCount(propertyName.Length);
            int endIndex = _parsedData.Length;

            if (maxBytes < JsonConstants.StackallocThreshold)
            {
                Span <byte> utf8Name = stackalloc byte[JsonConstants.StackallocThreshold];
                int         len      = JsonReaderHelper.GetUtf8FromText(propertyName, utf8Name);
                utf8Name = utf8Name.Slice(0, len);

                return(TryGetNamedPropertyValue(
                           endIndex,
                           utf8Name,
                           out value));
            }

            // Unescaping the property name will make the string shorter (or the same)
            // So the first viable candidate is one whose length in bytes matches, or
            // exceeds, our length in chars.
            //
            // The maximal escaping seems to be 6 -> 1 ("\u0030" => "0"), but just transcode
            // and switch once one viable long property is found.
            int minBytes = propertyName.Length;

            for (int candidateIndex = 0; candidateIndex <= endIndex; candidateIndex += JsonRow.Size * 2)
            {
                row = _parsedData.Get(candidateIndex);
                Debug.Assert(row.TokenType == JsonTokenType.PropertyName);

                if (row.Length >= minBytes)
                {
                    byte[] tmpUtf8 = ArrayPool <byte> .Shared.Rent(maxBytes);

                    Span <byte> utf8Name = default;

                    try
                    {
                        int len = JsonReaderHelper.GetUtf8FromText(propertyName, tmpUtf8);
                        utf8Name = tmpUtf8.AsSpan(0, len);

                        return(TryGetNamedPropertyValue(
                                   candidateIndex,
                                   utf8Name,
                                   out value));
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(tmpUtf8);
                    }
                }
            }

            // None of the property names were within the range that the UTF-8 encoding would have been.
#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out value);
#else
            value = default;
#endif
            return(false);
        }
Example #21
0
 /// <summary>
 /// Adds a header parameter.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="value"></param>
 /// <returns></returns>
 public JwtDescriptorBuilder AddHeader(string name, JwtArray value)
 => AddHeader(Utf8.GetBytes(name), value);
Example #22
0
 /// <inheritdoc/>
 public override string ToString()
 => Utf8.GetString(_utf8Json.Span);
Example #23
0
#pragma warning disable CS8618
        static CompressionAlgorithm()
        {
            Utf8.AssertMagicNumber(DEF, "DEF");
        }
Example #24
0
        private static Exception CreateJwtDescriptorException_ClaimIsRequired(ReadOnlySpan <byte> claim)
        {
            var value = Utf8.GetString(claim);

            return(new JwtDescriptorException($"The claim '{value}' is required."));
        }
Example #25
0
 static ECJwk()
 {
     Utf8.AssertMagicNumber(crv, "crv");
 }
Example #26
0
        private static Exception CreateJwtDescriptorException_ClaimMustBeOfType(ReadOnlySpan <byte> utf8Name, JwtTokenType type)
        {
            var value = Utf8.GetString(utf8Name);

            return(new JwtDescriptorException($"The claim '{value}' must be of type {type}."));
        }
Example #27
0
 private static Exception CreateNotSupportedException_Jwk(ReadOnlySpan <byte> name) => new NotSupportedException($"JWK type '{Utf8.GetString(name)}' is not supported.");
 public SingleIssuerSignatureValidationPolicy(string issuer, SignatureValidationPolicy policy)
 {
     _issuer = Utf8.GetBytes(issuer);
     _policy = policy;
 }
Example #29
0
        private static Exception CreateJwtDescriptorException_HeaderIsRequired(ReadOnlySpan <byte> header)
        {
            var value = Utf8.GetString(header);

            return(new JwtDescriptorException($"The header parameter '{value}' is required."));
        }
Example #30
0
 /// <summary>
 /// Adds a claim.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="value"></param>
 /// <returns></returns>
 public JwtDescriptorBuilder AddClaim(string name, JwtObject value)
 => AddClaim(Utf8.GetBytes(name), value);