예제 #1
0
        internal SymmetricJwk(ref Utf8JsonReader reader)
        {
            byte[]? k = null;
            while (reader.Read() && reader.TokenType is JsonTokenType.PropertyName)
            {
                var      propertyName    = reader.ValueSpan;
                ref byte propertyNameRef = ref MemoryMarshal.GetReference(propertyName);
                reader.Read();
                switch (reader.TokenType)
                {
                case JsonTokenType.String:
                    switch (propertyName.Length)
                    {
                    case 1 when propertyNameRef == (byte)'k':
                        k = Base64Url.Decode(reader.ValueSpan);
                        break;

                    case 3:
                        PopulateThree(ref reader, ref propertyNameRef, this);
                        break;

                    case 8:
                        PopulateEight(ref reader, ref propertyNameRef, this);
                        break;

                    default:
                        break;
                    }
                    break;

                case JsonTokenType.StartObject:
                    PopulateObject(ref reader);
                    break;

                case JsonTokenType.StartArray:
                    PopulateArray(ref reader, ref propertyNameRef, propertyName.Length, this);
                    break;

                default:
                    break;
                }
            }
예제 #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;
                    }
                }

                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);
            }
예제 #3
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);
            }