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);
            }
Esempio n. 2
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);
            }