/// <inheritdoc/>
            public bool TryGetHeader(JwtHeader header, KeyManagementAlgorithm alg, EncryptionAlgorithm enc, JsonEncodedText kid, string?typ, string?cty, [NotNullWhen(true)] out byte[]?base64UrlHeader)
            {
                if (ReferenceEquals(_firstHeader.Header, header))
                {
                    base64UrlHeader = _firstHeader.BinaryHeader;
                    goto Found;
                }

                if (IsEligibleHeaderForJwe(header.Count, kid, typ, cty))
                {
                    int algorithmId = enc.ComputeKey(alg);
                    var node        = _head;
                    while (node != null)
                    {
                        if (algorithmId == node.AlgorithmId)
                        {
                            if (node.TryGetEntry(kid, out var entry))
                            {
                                if (cty != entry.Cty)
                                {
                                    goto NotFound;
                                }

                                if (typ != entry.Typ)
                                {
                                    goto NotFound;
                                }

                                base64UrlHeader = entry.Data;
                                if (node != _head)
                                {
                                    MoveToHead(node);
                                }

                                goto Found;
                            }
                        }

                        node = node.Next;
                    }
                }

NotFound:
#if NET5_0_OR_GREATER
                Unsafe.SkipInit(out base64UrlHeader);
#else
                base64UrlHeader = default;
#endif
                return(false);

Found:
                return(true);
            }
Exemple #2
0
            /// <inheritdoc/>
            public void AddHeader(JwtHeader header, KeyManagementAlgorithm alg, EncryptionAlgorithm enc, JsonEncodedText kid, string?typ, string?cty, ReadOnlySpan <byte> base6UrlHeader)
            {
                _firstHeader = new WrappedHeader(header, base6UrlHeader.ToArray());
                if (IsEligibleHeaderForJwe(header.Count, kid, typ, cty))
                {
                    int  algorithmId = enc.ComputeKey(alg);
                    bool lockTaken   = false;
                    try
                    {
                        _spinLock.Enter(ref lockTaken);
                        if (_count >= MaxSize)
                        {
                            _head  = null;
                            _tail  = null;
                            _count = 0;
                        }

                        var node = _head;
                        while (node != null)
                        {
                            if (algorithmId == node.AlgorithmId)
                            {
                                break;
                            }

                            node = node.Next;
                        }

                        var key = alg.Id;
                        if (node is null)
                        {
                            _count++;
                            node = new Bucket(algorithmId, kid, new CacheEntry(base6UrlHeader.ToArray(), typ, cty))
                            {
                                Next = _head
                            };
                        }
                        else
                        {
                            if (!node.Entries.ContainsKey(kid !))
                            {
                                _count++;
                                node.Entries[kid] = new CacheEntry(base6UrlHeader.ToArray(), typ, cty);
                            }
                        }

                        if (!ReferenceEquals(_head, node))
                        {
                            if (_head != null)
                            {
                                _head.Previous = node;
                            }

                            _head = node;
                        }

                        if (_tail is null)
                        {
                            _tail = node;
                        }
                    }
                    finally
                    {
                        if (lockTaken)
                        {
                            _spinLock.Exit();
                        }
                    }
                }
            }