public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (!payload.TryGetClaim(JwtClaimNames.Exp.EncodedUtf8Bytes, out var expires))
            {
                error = TokenValidationError.MissingClaim(JwtClaimNames.Exp.ToString());
                return(false);
            }

            if (!payload.TryGetClaim(JwtClaimNames.Jti.EncodedUtf8Bytes, out var jti))
            {
                error = TokenValidationError.MissingClaim(JwtClaimNames.Jti.ToString());
                return(false);
            }

            if (!_tokenReplayCache.TryAdd(jti.GetString(), expires.GetInt64()))
            {
                error = TokenValidationError.TokenReplayed();
                return(false);
            }

#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out error);
#else
            error = default;
#endif
            return(true);
        }
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload is null)
            {
                error = TokenValidationError.MalformedToken();
                return(false);
            }

            if (!payload.TryGetClaim(_claim, out var claim))
            {
                error = TokenValidationError.MissingClaim(_claim);
                return(false);
            }

            if (!claim.TryGetDouble(out var value) || _value != value)
            {
                error = TokenValidationError.InvalidClaim(_claim);
                return(false);
            }

#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out error);
#else
            error = default;
#endif
            return(true);
        }
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (header is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header);
            }

            if (header.Alg.IsEmpty)
            {
                error = TokenValidationError.MissingHeader(JwtHeaderParameterNames.Alg.ToString());
                return(false);
            }

            if (!header.Alg.ValueEquals(_algorithm))
            {
                error = TokenValidationError.InvalidHeader(JwtHeaderParameterNames.Alg.ToString());
                return(false);
            }

#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out error);
#else
            error = default;
#endif
            return(true);
        }
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
#if NET5_0_OR_GREATER
                Unsafe.SkipInit(out error);
#else
                error = default;
#endif
                return(true);
            }
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
                if (!payload.Iss.IsEmpty && payload.Iss.ValueEquals(_issuer))
                {
                    return(_policy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error));
                }

                error = SignatureValidationError.InvalidSignature();
                return(false);
            }
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
                if (!payload.Iss.IsEmpty)
                {
                    if (TryGetPolicy(payload.Iss, out var policy))
                    {
                        return(policy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error));
                    }
                }

                return(_defaultPolicy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error));
            }
Exemple #7
0
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
                if ((contentBytes.Length == 0 && signatureSegment.Length == 0) ||
                    (signatureSegment.IsEmpty && !header.Alg.IsEmpty && header.Alg.ValueEquals(SignatureAlgorithm.None.Utf8Name)))
                {
                    error = null;
                    return(true);
                }

                error = SignatureValidationError.InvalidSignature();
                return(false);
            }
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
                if ((contentBytes.Length == 0 && signatureSegment.Length == 0) ||
                    (signatureSegment.IsEmpty && !header.Alg.IsEmpty && header.Alg.ValueEquals(SignatureAlgorithm.None.Utf8Name)))
                {
#if NET5_0_OR_GREATER
                    Unsafe.SkipInit(out error);
#else
                    error = default;
#endif
                    return(true);
                }

                error = SignatureValidationError.InvalidSignature();
                return(false);
            }
Exemple #9
0
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload is null)
            {
                error = TokenValidationError.MalformedToken();
                return(false);
            }

            if (payload.ContainsClaim(_claim))
            {
                error = null;
                return(true);
            }

            error = TokenValidationError.MissingClaim(_claim);
            return(false);
        }
Exemple #10
0
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload is null)
            {
                error = TokenValidationError.MalformedToken();
                return(false);
            }

            if (payload.ContainsClaim(OAuth2Claims.AuthTime.EncodedUtf8Bytes))
            {
                error = null;
                return(true);
            }

            error = TokenValidationError.MissingClaim(OAuth2Claims.AuthTime.ToString());
            return(false);
        }
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload is null)
            {
                error = TokenValidationError.MalformedToken();
                return(false);
            }

            if (payload.ContainsClaim(_claim))
            {
#if NET5_0_OR_GREATER
                Unsafe.SkipInit(out error);
#else
                error = default;
#endif
                return(true);
            }

            error = TokenValidationError.MissingClaim(_claim);
            return(false);
        }
Exemple #12
0
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (header is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header);
            }

            if (header.Alg.IsEmpty)
            {
                error = TokenValidationError.MissingHeader(JwtHeaderParameterNames.Alg.ToString());
                return(false);
            }

            if (!header.Alg.ValueEquals(_algorithm))
            {
                error = TokenValidationError.InvalidHeader(JwtHeaderParameterNames.Alg.ToString());
                return(false);
            }

            error = null;
            return(true);
        }
Exemple #13
0
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload is null)
            {
                error = TokenValidationError.MalformedToken();
                return(false);
            }

            if (!payload.TryGetClaim(_claim, out var claim))
            {
                error = TokenValidationError.MissingClaim(_claim);
                return(false);
            }

            if (!claim.TryGetDouble(out var value) || _value != value)
            {
                error = TokenValidationError.InvalidClaim(_claim);
                return(false);
            }

            error = null;
            return(true);
        }
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload is null)
            {
                error = TokenValidationError.MalformedToken();
                return(false);
            }

            if (!payload.TryGetClaim(OAuth2Claims.Acr.EncodedUtf8Bytes, out var property))
            {
                error = TokenValidationError.MissingClaim(OAuth2Claims.Acr.ToString());
                return(false);
            }

            if (!property.ValueEquals(_requiredAcr))
            {
                error = TokenValidationError.InvalidClaim(OAuth2Claims.Acr.ToString());
                return(false);
            }

            error = null;
            return(true);
        }
Exemple #15
0
        public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (!payload.TryGetClaim(JwtClaimNames.Exp.EncodedUtf8Bytes, out var expires))
            {
                error = TokenValidationError.MissingClaim(JwtClaimNames.Exp.ToString());
                return(false);
            }

            if (!payload.TryGetClaim(JwtClaimNames.Jti.EncodedUtf8Bytes, out var jti))
            {
                error = TokenValidationError.MissingClaim(JwtClaimNames.Jti.ToString());
                return(false);
            }

            if (!_tokenReplayCache.TryAdd(jti.GetString(), expires.GetInt64()))
            {
                error = TokenValidationError.TokenReplayed();
                return(false);
            }

            error = null;
            return(true);
        }
Exemple #16
0
 public bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
 {
     return(SignatureValidationPolicy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error));
 }
Exemple #17
0
        /// <summary>Try to validate the token, according to the <paramref name="header"/> and the <paramref name="payload"/>.</summary>
        public bool TryValidateJwt(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            if (payload.Control != 0)
            {
                if (RequireAudience)
                {
                    if (payload.MissingAudience)
                    {
                        error = TokenValidationError.MissingClaim(JwtClaimNames.Aud.ToString());
                        goto Error;
                    }

                    if (payload.InvalidAudience)
                    {
                        error = TokenValidationError.InvalidClaim(JwtClaimNames.Aud.ToString());
                        goto Error;
                    }
                }

                if (RequireIssuer)
                {
                    if (payload.MissingIssuer)
                    {
                        error = TokenValidationError.MissingClaim(JwtClaimNames.Iss.ToString());
                        goto Error;
                    }

                    if (payload.InvalidIssuer)
                    {
                        error = TokenValidationError.InvalidClaim(JwtClaimNames.Iss.ToString());
                        goto Error;
                    }
                }

                if (RequireExpirationTime)
                {
                    if (payload.MissingExpirationTime)
                    {
                        error = TokenValidationError.MissingClaim(JwtClaimNames.Exp.ToString());
                        goto Error;
                    }

                    if (payload.Expired)
                    {
                        error = TokenValidationError.Expired();
                        goto Error;
                    }
                }

                if (payload.NotYetValid)
                {
                    error = TokenValidationError.NotYetValid();
                    goto Error;
                }
            }

            var validators = _validators;

            for (int i = 0; i < validators.Length; i++)
            {
                if (!validators[i].TryValidate(header, payload, out error))
                {
                    goto Error;
                }
            }

#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out error);
#else
            error = default;
#endif
            return(true);

Error:
            return(false);
        }
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
                if (signatureSegment.IsEmpty)
                {
                    if (contentBytes.IsEmpty)
                    {
                        // This is not a JWS
                        goto Success;
                    }
                    else
                    {
                        error = SignatureValidationError.MissingSignature();
                        goto Error;
                    }
                }

                byte[]? signatureToReturn = null;
                try
                {
                    int         signatureBytesLength = Base64Url.GetArraySizeRequiredToDecode(signatureSegment.Length);
                    Span <byte> signatureBytes       = signatureBytesLength > Constants.MaxStackallocBytes
                            ? (signatureToReturn = ArrayPool <byte> .Shared.Rent(signatureBytesLength))
                            : stackalloc byte[Constants.MaxStackallocBytes];

                    if (Base64Url.Decode(signatureSegment, signatureBytes, out _, out int bytesWritten) != OperationStatus.Done)
                    {
                        error = SignatureValidationError.MalformedSignature();
                        goto Error;
                    }

                    signatureBytes = signatureBytes.Slice(0, bytesWritten);
                    //Debug.Assert(signatureBytesLength == bytesWritten);
                    bool keysTried  = false;
                    var  keySet     = _keyProvider.GetKeys(header);
                    var  algElement = header.Alg;
                    if (keySet != null)
                    {
                        var algorithm = _algorithm;
                        for (int i = 0; i < keySet.Length; i++)
                        {
                            var key = keySet[i];
                            if (key.CanUseForSignature(algElement))
                            {
                                var alg = algorithm ?? key.SignatureAlgorithm;
                                if (!(alg is null))
                                {
                                    if (key.TryGetSignatureVerifier(alg, out var signatureVerifier))
                                    {
                                        if (signatureVerifier.Verify(contentBytes, signatureBytes.Slice(0, signatureBytesLength)))
                                        {
                                            goto Success;
                                        }
                                    }
                                }

                                keysTried = true;
                            }
                        }
                    }

                    error = keysTried
                        ? SignatureValidationError.InvalidSignature()
                        : SignatureValidationError.SignatureKeyNotFound();
                }
                catch (FormatException e)
                {
                    error = SignatureValidationError.MalformedSignature(e);
                }
                finally
                {
                    if (signatureToReturn != null)
                    {
                        ArrayPool <byte> .Shared.Return(signatureToReturn);
                    }
                }

                Error:
                return(false);

Success:
#if NET5_0_OR_GREATER
                Unsafe.SkipInit(out error);
#else
                error = default;
#endif
                return(true);
            }
 public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
 {
     error = SignatureValidationError.InvalidSignature();
     return(false);
 }
 /// <summary>Try to validate the token signature.</summary>
 public abstract bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error);
        internal static bool TryParsePayload(ReadOnlyMemory <byte> utf8Payload, byte[]?buffer, TokenValidationPolicy policy, [NotNullWhen(true)] out JwtPayloadDocument?payload, [NotNullWhen(false)] out TokenValidationError?error)
        {
            ReadOnlySpan <byte> utf8JsonSpan = utf8Payload.Span;
            var  database = new JsonMetadata(utf8Payload.Length);
            byte control  = policy.Control;
            int  issIdx   = -1;

            var reader = new Utf8JsonReader(utf8JsonSpan);

            if (reader.Read())
            {
                JsonTokenType tokenType = reader.TokenType;
                if (tokenType == JsonTokenType.StartObject)
                {
                    while (reader.Read())
                    {
                        tokenType = reader.TokenType;
                        int tokenStart = (int)reader.TokenStartIndex;

                        if (tokenType == JsonTokenType.EndObject)
                        {
                            break;
                        }
                        else if (tokenType != JsonTokenType.PropertyName)
                        {
                            error = TokenValidationError.MalformedToken();
                            goto Error;
                        }

                        Debug.Assert(tokenStart < int.MaxValue);
                        database.Append(JsonTokenType.PropertyName, tokenStart + 1, reader.ValueSpan.Length);
                        ReadOnlySpan <byte> memberName = reader.ValueSpan;
                        if (memberName.IndexOf((byte)'\\') != -1)
                        {
                            database.SetNeedUnescaping(database.Length - JsonRow.Size);
                        }

                        reader.Read();
                        tokenType  = reader.TokenType;
                        tokenStart = (int)reader.TokenStartIndex;

                        Debug.Assert(reader.TokenStartIndex <= int.MaxValue);
                        if (tokenType == JsonTokenType.String)
                        {
                            if (memberName.Length == 3)
                            {
                                switch ((JwtClaims)IntegerMarshal.ReadUInt24(memberName))
                                {
                                case JwtClaims.Aud:
                                    CheckStringAudience(ref reader, ref control, policy);
                                    break;

                                case JwtClaims.Iss:
                                    issIdx = database.Length;
                                    CheckIssuer(ref reader, ref control, policy);
                                    break;
                                }
                            }

                            Debug.Assert(tokenStart < int.MaxValue);
                            database.Append(JsonTokenType.String, tokenStart + 1, reader.ValueSpan.Length);
                        }
                        else if (tokenType == JsonTokenType.Number)
                        {
                            if (memberName.Length == 3)
                            {
                                switch ((JwtClaims)IntegerMarshal.ReadUInt24(memberName))
                                {
                                case JwtClaims.Exp:
                                    if (!TryCheckExpirationTime(ref reader, ref control, policy))
                                    {
                                        error = TokenValidationError.MalformedToken("The claim 'exp' must be an integral number.");
                                        goto Error;
                                    }
                                    break;

                                case JwtClaims.Nbf:
                                    if (!TryCheckNotBefore(ref reader, ref control, policy))
                                    {
                                        error = TokenValidationError.MalformedToken("The claim 'nbf' must be an integral number.");
                                        goto Error;
                                    }
                                    break;
                                }
                            }

                            database.Append(JsonTokenType.Number, tokenStart, reader.ValueSpan.Length);
                        }
                        else if (tokenType == JsonTokenType.StartObject)
                        {
                            int itemCount = Utf8JsonReaderHelper.SkipObject(ref reader);
                            int tokenEnd  = (int)reader.TokenStartIndex;
                            int index     = database.Length;
                            database.Append(JsonTokenType.StartObject, tokenStart, tokenEnd - tokenStart + 1);
                            database.SetNumberOfRows(index, itemCount);
                        }
                        else if (tokenType == JsonTokenType.StartArray)
                        {
                            int itemCount;
                            if (memberName.Length == 3 && (JwtClaims)IntegerMarshal.ReadUInt24(memberName) == JwtClaims.Aud)
                            {
                                itemCount = CheckArrayAudience(ref reader, ref control, policy);
                            }
                            else
                            {
                                itemCount = Utf8JsonReaderHelper.SkipArray(ref reader);
                            }

                            int index    = database.Length;
                            int tokenEnd = (int)reader.TokenStartIndex;
                            database.Append(JsonTokenType.StartArray, tokenStart, tokenEnd - tokenStart + 1);
                            database.SetNumberOfRows(index, itemCount);
                        }
                        else
                        {
                            Debug.Assert(tokenType >= JsonTokenType.True && tokenType <= JsonTokenType.Null);
                            database.Append(tokenType, tokenStart, reader.ValueSpan.Length);
                        }
                    }
                }
            }

            Debug.Assert(reader.BytesConsumed == utf8JsonSpan.Length);
            database.CompleteAllocations();

            payload = new JwtPayloadDocument(new JwtDocument(utf8Payload, database, buffer), control, issIdx);
#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out error);
#else
            error = default;
#endif
            return(true);

Error:
#if NET5_0_OR_GREATER
            Unsafe.SkipInit(out payload);
#else
            payload = default;
#endif
            return(false);
        }
Exemple #22
0
 private Jwt(JwtHeaderDocument header, JwtPayloadDocument payload, TokenValidationError error)
 {
     _header  = header;
     _payload = payload;
     _error   = error;
 }
Exemple #23
0
 internal Jwt(JwtHeaderDocument header, JwtPayloadDocument payload)
 {
     _header  = header;
     _payload = payload;
 }
Exemple #24
0
            public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error)
            {
                if (signatureSegment.IsEmpty)
                {
                    if (contentBytes.IsEmpty)
                    {
                        // This is not a JWS
                        goto Success;
                    }
                    else
                    {
                        error = SignatureValidationError.MissingSignature();
                        goto Error;
                    }
                }

                try
                {
                    int         signatureBytesLength = Base64Url.GetArraySizeRequiredToDecode(signatureSegment.Length);
                    Span <byte> signatureBytes       = stackalloc byte[signatureBytesLength];
                    if (Base64Url.Decode(signatureSegment, signatureBytes, out int byteConsumed, out int bytesWritten) != OperationStatus.Done)
                    {
                        error = SignatureValidationError.MalformedSignature();
                        goto Error;
                    }

                    Debug.Assert(bytesWritten == signatureBytes.Length);
                    bool keysTried = false;

                    var keySet     = _keyProvider.GetKeys(header);
                    var algElement = header.Alg;
                    if (keySet != null)
                    {
                        var algorithm = _algorithm;
                        for (int i = 0; i < keySet.Length; i++)
                        {
                            var key = keySet[i];
                            if (key.CanUseForSignature(algElement))
                            {
                                var alg = algorithm ?? key.SignatureAlgorithm;
                                if (!(alg is null))
                                {
                                    if (key.TryGetSignatureVerifier(alg, out var signatureVerifier))
                                    {
                                        if (signatureVerifier.Verify(contentBytes, signatureBytes))
                                        {
                                            goto Success;
                                        }
                                    }
                                }

                                keysTried = true;
                            }
                        }
                    }

                    error = keysTried
                        ? SignatureValidationError.InvalidSignature()
                        : SignatureValidationError.SignatureKeyNotFound();
                }
                catch (FormatException e)
                {
                    error = SignatureValidationError.MalformedSignature(e);
                }

Error:
                return(false);

Success:
                error = null;
                return(true);
            }