EncryptData() private méthode

private EncryptData ( byte buffer, int offset, int count, byte &outBuffer, int &outSize ) : SecurityStatusPal
buffer byte
offset int
count int
outBuffer byte
outSize int
Résultat SecurityStatusPal
Exemple #1
0
        private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest)
        {
            if (asyncRequest != null)
            {
                asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncWriteCallback);
            }

            // We loop to this method from the callback.
            // If the last chunk was just completed from async callback (count < 0), we complete user request.
            if (count >= 0)
            {
                byte[] outBuffer = null;
                if (_PinnableOutputBufferInUse == null)
                {
                    if (_PinnableOutputBuffer == null)
                    {
                        _PinnableOutputBuffer = s_PinnableWriteBufferCache.AllocateBuffer();
                    }

                    _PinnableOutputBufferInUse = buffer;
                    outBuffer = _PinnableOutputBuffer;
                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Trying Pinnable", this.GetHashCode(), count, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer));
                    }
                }
                else
                {
                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.StartWriting BufferInUse", this.GetHashCode(), count);
                    }
                }

                do
                {
                    // Request a write IO slot.
                    if (_SslState.CheckEnqueueWrite(asyncRequest))
                    {
                        // Operation is async and has been queued, return.
                        return;
                    }

                    int chunkBytes = Math.Min(count, _SslState.MaxDataSize);
                    int encryptedBytes;
                    Interop.SecurityStatus errorCode = _SslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes);
                    if (errorCode != Interop.SecurityStatus.OK)
                    {
                        ProtocolToken message = new ProtocolToken(null, errorCode);
                        throw new IOException(SR.net_io_encrypt, message.GetException());
                    }

                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Got Encrypted Buffer",
                                                                         this.GetHashCode(), encryptedBytes, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer));
                    }

                    if (asyncRequest != null)
                    {
                        // Prepare for the next request.
                        asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback);
                        IAsyncResult ar = _SslState.InnerStreamAPM.BeginWrite(outBuffer, 0, encryptedBytes, s_writeCallback, asyncRequest);
                        if (!ar.CompletedSynchronously)
                        {
                            return;
                        }

                        _SslState.InnerStreamAPM.EndWrite(ar);
                    }
                    else
                    {
                        _SslState.InnerStream.Write(outBuffer, 0, encryptedBytes);
                    }

                    offset += chunkBytes;
                    count  -= chunkBytes;

                    // Release write IO slot.
                    _SslState.FinishWrite();
                } while (count != 0);
            }

            if (asyncRequest != null)
            {
                asyncRequest.CompleteUser();
            }

            if (buffer == _PinnableOutputBufferInUse)
            {
                _PinnableOutputBufferInUse = null;
                if (PinnableBufferCacheEventSource.Log.IsEnabled())
                {
                    PinnableBufferCacheEventSource.Log.DebugMessage1("In System.Net._SslStream.StartWriting Freeing buffer.", this.GetHashCode());
                }
            }
        }
        private Task WriteSingleChunk <TWriteAdapter>(TWriteAdapter writeAdapter, ReadOnlyMemory <byte> buffer)
            where TWriteAdapter : struct, ISslWriteAdapter
        {
            // Request a write IO slot.
            Task ioSlot = writeAdapter.LockAsync();

            if (!ioSlot.IsCompletedSuccessfully)
            {
                // Operation is async and has been queued, return.
                return(WaitForWriteIOSlot(writeAdapter, ioSlot, buffer));
            }

            byte[] rentedBuffer = ArrayPool <byte> .Shared.Rent(buffer.Length + FrameOverhead);

            byte[] outBuffer = rentedBuffer;

            SecurityStatusPal status = _sslState.EncryptData(buffer, ref outBuffer, out int encryptedBytes);

            if (status.ErrorCode != SecurityStatusPalErrorCode.OK)
            {
                // Re-handshake status is not supported.
                ArrayPool <byte> .Shared.Return(rentedBuffer);

                ProtocolToken message = new ProtocolToken(null, status);
                return(Task.FromException(new IOException(SR.net_io_encrypt, message.GetException())));
            }

            Task t = writeAdapter.WriteAsync(outBuffer, 0, encryptedBytes);

            if (t.IsCompletedSuccessfully)
            {
                ArrayPool <byte> .Shared.Return(rentedBuffer);

                _sslState.FinishWrite();
                return(t);
            }
            else
            {
                return(CompleteAsync(t, rentedBuffer));
            }

            async Task WaitForWriteIOSlot(TWriteAdapter wAdapter, Task lockTask, ReadOnlyMemory <byte> buff)
            {
                await lockTask.ConfigureAwait(false);

                await WriteSingleChunk(wAdapter, buff).ConfigureAwait(false);
            }

            async Task CompleteAsync(Task writeTask, byte[] bufferToReturn)
            {
                try
                {
                    await writeTask.ConfigureAwait(false);
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(bufferToReturn);

                    _sslState.FinishWrite();
                }
            }
        }
Exemple #3
0
        private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest)
        {
            if (asyncRequest != null)
            {
                asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncWriteCallback);
            }

            // We loop to this method from the callback.
            // If the last chunk was just completed from async callback (count < 0), we complete user request.
            if (count >= 0)
            {
                byte[] outBuffer = null;
                if (_pinnableOutputBufferInUse == null)
                {
                    if (_pinnableOutputBuffer == null)
                    {
                        _pinnableOutputBuffer = s_PinnableWriteBufferCache.AllocateBuffer();
                    }

                    _pinnableOutputBufferInUse = buffer;
                    outBuffer = _pinnableOutputBuffer;
                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Trying Pinnable", this.GetHashCode(), count, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer));
                    }
                }
                else
                {
                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.StartWriting BufferInUse", this.GetHashCode(), count);
                    }
                }

                do
                {
                    if (count == 0 && !SslStreamPal.CanEncryptEmptyMessage)
                    {
                        // If it's an empty message and the PAL doesn't support that,
                        // we're done.
                        break;
                    }

                    // Request a write IO slot.
                    if (_sslState.CheckEnqueueWrite(asyncRequest))
                    {
                        // Operation is async and has been queued, return.
                        return;
                    }

                    int chunkBytes = Math.Min(count, _sslState.MaxDataSize);
                    int encryptedBytes;
                    SecurityStatusPal status = _sslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes);
                    if (status.ErrorCode != SecurityStatusPalErrorCode.OK)
                    {
                        // Re-handshake status is not supported.
                        ProtocolToken message = new ProtocolToken(null, status);
                        throw new IOException(SR.net_io_encrypt, message.GetException());
                    }

                    if (PinnableBufferCacheEventSource.Log.IsEnabled())
                    {
                        PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Got Encrypted Buffer",
                                                                         this.GetHashCode(), encryptedBytes, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer));
                    }

                    if (asyncRequest != null)
                    {
                        // Prepare for the next request.
                        asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback);
                        Task t = _sslState.InnerStream.WriteAsync(outBuffer, 0, encryptedBytes);
                        if (t.IsCompleted)
                        {
                            t.GetAwaiter().GetResult();
                        }
                        else
                        {
                            IAsyncResult ar = TaskToApm.Begin(t, s_writeCallback, asyncRequest);
                            if (!ar.CompletedSynchronously)
                            {
                                return;
                            }
                            TaskToApm.End(ar);
                        }
                    }
                    else
                    {
                        _sslState.InnerStream.Write(outBuffer, 0, encryptedBytes);
                    }

                    offset += chunkBytes;
                    count  -= chunkBytes;

                    // Release write IO slot.
                    _sslState.FinishWrite();
                } while (count != 0);
            }

            if (asyncRequest != null)
            {
                asyncRequest.CompleteUser();
            }

            if (buffer == _pinnableOutputBufferInUse)
            {
                _pinnableOutputBufferInUse = null;
                if (PinnableBufferCacheEventSource.Log.IsEnabled())
                {
                    PinnableBufferCacheEventSource.Log.DebugMessage1("In System.Net._SslStream.StartWriting Freeing buffer.", this.GetHashCode());
                }
            }
        }
Exemple #4
0
        private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest)
        {
            if (asyncRequest != null)
            {
                asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncWriteCallback);
            }

            // We loop to this method from the callback.
            // If the last chunk was just completed from async callback (count < 0), we complete user request.
            if (count >= 0)
            {
                do
                {
                    if (count == 0 && !SslStreamPal.CanEncryptEmptyMessage)
                    {
                        // If it's an empty message and the PAL doesn't support that,
                        // we're done.
                        break;
                    }

                    // Request a write IO slot.
                    if (_sslState.CheckEnqueueWrite(asyncRequest))
                    {
                        // Operation is async and has been queued, return.
                        return;
                    }

                    int    chunkBytes   = Math.Min(count, _sslState.MaxDataSize);
                    byte[] rentedBuffer = ArrayPool <byte> .Shared.Rent(chunkBytes + FrameOverhead);

                    byte[] outBuffer      = rentedBuffer;
                    int    encryptedBytes = 0;

                    SecurityStatusPal status = _sslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes);
                    if (status.ErrorCode != SecurityStatusPalErrorCode.OK)
                    {
                        // Re-handshake status is not supported.
                        ProtocolToken message = new ProtocolToken(null, status);
                        ArrayPool <byte> .Shared.Return(rentedBuffer);

                        throw new IOException(SR.net_io_encrypt, message.GetException());
                    }

                    if (asyncRequest != null)
                    {
                        // Prepare for the next request.
                        asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback);
                        Task t = _sslState.InnerStream.WriteAsync(outBuffer, 0, encryptedBytes);
                        if (t.IsCompleted)
                        {
                            ArrayPool <byte> .Shared.Return(rentedBuffer);

                            t.GetAwaiter().GetResult();
                        }
                        else
                        {
                            t = t.ContinueWith(s_freeWriteBufferCallback, rentedBuffer, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
                            IAsyncResult ar = TaskToApm.Begin(t, s_writeCallback, asyncRequest);
                            if (!ar.CompletedSynchronously)
                            {
                                return;
                            }
                            TaskToApm.End(ar);
                        }
                    }
                    else
                    {
                        try
                        {
                            _sslState.InnerStream.Write(outBuffer, 0, encryptedBytes);
                        }
                        finally
                        {
                            ArrayPool <byte> .Shared.Return(rentedBuffer);
                        }
                    }

                    offset += chunkBytes;
                    count  -= chunkBytes;

                    // Release write IO slot.
                    _sslState.FinishWrite();
                } while (count != 0);
            }

            if (asyncRequest != null)
            {
                asyncRequest.CompleteUser();
            }
        }