예제 #1
0
 /// <summary>Initializes a new instance of the <see cref="EncodingContext"/> class.</summary>
 public EncodingContext(IBufferWriter <byte> bufferWriter, EncodingContext other)
 {
     BufferWriter           = bufferWriter;
     HeaderCache            = other.HeaderCache;
     TokenLifetimeInSeconds = other.TokenLifetimeInSeconds;
     GenerateIssuedTime     = other.GenerateIssuedTime;
 }
예제 #2
0
        /// <summary>Encrypt the token.</summary>
        protected void EncryptToken(ReadOnlySpan <byte> payload, EncodingContext context)
        {
            var output = context.BufferWriter;
            EncryptionAlgorithm enc = _enc;
            var key = _encryptionKey;

            if (key is null)
            {
                ThrowHelper.ThrowKeyNotFoundException();
                return;
            }

            KeyManagementAlgorithm alg = _alg;

            if (key.TryGetKeyWrapper(enc, alg, out var keyWrapper))
            {
                var header = Header;
                byte[]? wrappedKeyToReturnToPool      = null;
                byte[]? buffer64HeaderToReturnToPool  = null;
                byte[]? arrayCiphertextToReturnToPool = null;
                int         keyWrapSize = keyWrapper.GetKeyWrapSize();
                Span <byte> wrappedKey  = keyWrapSize <= Constants.MaxStackallocBytes ?
                                          stackalloc byte[keyWrapSize] :
                                          new Span <byte>(wrappedKeyToReturnToPool = ArrayPool <byte> .Shared.Rent(keyWrapSize), 0, keyWrapSize);
                var cek = keyWrapper.WrapKey(null, header, wrappedKey);

                try
                {
                    using var bufferWriter = new PooledByteBufferWriter();
                    var writer = new Utf8JsonWriter(bufferWriter, JsonSerializationBehavior.NoJsonValidation);
                    int base64EncodedHeaderLength  = 0;
                    ReadOnlySpan <byte> headerJson = default;
                    var headerCache = context.HeaderCache;
                    if (headerCache.TryGetHeader(header, alg, enc, _kid, _typ, _cty, out byte[]? cachedHeader))
예제 #3
0
        /// <inheritsdoc />
        public override void Encode(EncodingContext context)
        {
            if (Payload != null)
            {
                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(encodedPayload.Slice(0, bytesWritten), context);
                }
                finally
                {
                    if (payloadToReturnToPool != null)
                    {
                        ArrayPool <byte> .Shared.Return(payloadToReturnToPool);
                    }
                }
            }
            else
            {
                ThrowHelper.ThrowInvalidOperationException_UndefinedPayload();
            }
        }
        /// <inheritdoc/>
        public override void Encode(EncodingContext context)
        {
            using var bufferWriter = new PooledByteBufferWriter();
            var ctx = new EncodingContext(bufferWriter, context);

            if (Payload is null)
            {
                ThrowHelper.ThrowInvalidOperationException_UndefinedPayload();
            }

            using var writer = new Utf8JsonWriter(ctx.BufferWriter);
            Payload.WriteTo(writer);
            EncryptToken(bufferWriter.WrittenSpan, context);
        }
예제 #5
0
        /// <summary>
        /// Writes a JWT in its compact serialization format.
        /// </summary>
        /// <param name="descriptor">The descriptor of the JWT.</param>
        /// <param name="output">The <see cref="IBufferWriter{T}"/> used for writing the output.</param>
        /// <returns>The array of <see cref="byte"/> representation of the JWT.</returns>
        public void WriteToken(JwtDescriptor descriptor, IBufferWriter <byte> output)
        {
            if (descriptor is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.descriptor);
            }

            if (!IgnoreTokenValidation)
            {
                descriptor.Validate();
            }

            var encodingContext = new EncodingContext(EnableHeaderCaching ? _headerCache : null, TokenLifetimeInSeconds, GenerateIssuedTime);

            descriptor.Encode(encodingContext, output);
        }
예제 #6
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);
                }
            }
        }
예제 #7
0
 /// <inheritdoc />
 public override void Encode(EncodingContext context)
 {
     EncryptToken(Payload, context);
 }
예제 #8
0
 /// <inheritsdoc />
 public override void Encode(EncodingContext context, IBufferWriter <byte> output)
 {
     using var bufferWriter = new PooledByteBufferWriter();
     Payload?.Encode(context, bufferWriter);
     EncryptToken(context, bufferWriter.WrittenSpan, output);
 }
예제 #9
0
 /// <inheritdoc />
 public override void Encode(EncodingContext context, IBufferWriter <byte> output)
 {
     EncryptToken(context, Payload, output);
 }