/// <summary>
        /// Writes a sequence of bytes to the current stream. The data is encrypted first before sending out.
        /// </summary>
        /// <param name="buffer">The buffer to be sent.</param>
        /// <param name="offset">The offset in buffer at which to begin writing to the stream.</param>
        /// <param name="count">The number of bytes to be written.</param>
        /// <exception cref="IOException">Raised when attempting to read from/write to a remote connection which
        /// has been closed</exception>
        /// <exception cref="ArgumentOutOfRangeException">Raised when the offset incremented by count exceeds
        /// the length of buffer</exception>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (offset > buffer.Length - 1)
            {
                throw new ArgumentOutOfRangeException("offset");
            }

            if (offset + count > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            byte[] outBuffer = new byte[count];
            Array.Copy(buffer, offset, outBuffer, 0, count);

            // Encrypt message
            SecurityPackageContextStreamSizes streamSizes =
                (SecurityPackageContextStreamSizes)context.QueryContextAttributes("SECPKG_ATTR_STREAM_SIZES");
            SecurityBuffer messageBuffer = new SecurityBuffer(SecurityBufferType.Data, buffer);
            SecurityBuffer headerBuffer  = new SecurityBuffer(
                SecurityBufferType.StreamHeader,
                new byte[streamSizes.Header]);
            SecurityBuffer trailerBuffer = new SecurityBuffer(
                SecurityBufferType.StreamTrailer,
                new byte[streamSizes.Trailer]);
            SecurityBuffer emptyBuffer = new SecurityBuffer(SecurityBufferType.Empty, null);

            context.Encrypt(headerBuffer, messageBuffer, trailerBuffer, emptyBuffer);
            byte[] encryptedMsg = ArrayUtility.ConcatenateArrays(
                headerBuffer.Buffer,
                messageBuffer.Buffer,
                trailerBuffer.Buffer);
            clientStream.Write(encryptedMsg, 0, encryptedMsg.Length);
        }
Exemple #2
0
        /// <summary>
        /// Writes a sequence of bytes to the current stream. The data is encrypted first before sending out.
        /// </summary>
        /// <param name="buffer">The buffer to be sent.</param>
        /// <param name="offset">The offset in buffer at which to begin writing to the stream.</param>
        /// <param name="count">The number of bytes to be written.</param>
        /// <exception cref="IOException">Raised when attempting to read from/write to a remote connection which
        /// has been closed</exception>
        /// <exception cref="ArgumentOutOfRangeException">Raised when the offset incremented by count exceeds
        /// the length of buffer</exception>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (offset > buffer.Length - 1)
            {
                throw new ArgumentOutOfRangeException("offset");
            }

            if (offset + count > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            // Get stream attribute
            SecurityPackageContextStreamSizes streamSizes =
                (SecurityPackageContextStreamSizes)context.QueryContextAttributes("SECPKG_ATTR_STREAM_SIZES");

            int         chunckSize = (int)streamSizes.MaximumMessage;
            List <byte> byteList   = new List <byte>();

            while (count > 0)
            {
                int bufferSize = count;
                if (bufferSize > chunckSize)
                {
                    bufferSize = chunckSize;
                }

                byte[] outBuffer = new byte[bufferSize];
                Array.Copy(buffer, offset, outBuffer, 0, bufferSize);
                count  -= bufferSize;
                offset += bufferSize;

                // Encrypt Chunck
                SecurityBuffer messageBuffer = new SecurityBuffer(SecurityBufferType.Data, outBuffer);
                SecurityBuffer headerBuffer  = new SecurityBuffer(
                    SecurityBufferType.StreamHeader,
                    new byte[streamSizes.Header]);
                SecurityBuffer trailerBuffer = new SecurityBuffer(
                    SecurityBufferType.StreamTrailer,
                    new byte[streamSizes.Trailer]);
                SecurityBuffer emptyBuffer = new SecurityBuffer(SecurityBufferType.Empty, null);

                context.Encrypt(headerBuffer, messageBuffer, trailerBuffer, emptyBuffer);
                byte[] encryptedChunck = ArrayUtility.ConcatenateArrays(
                    headerBuffer.Buffer,
                    messageBuffer.Buffer,
                    trailerBuffer.Buffer);
                byteList.AddRange(encryptedChunck);
            }

            byte[] encryptedMsg = byteList.ToArray();
            serverStream.Write(encryptedMsg, 0, encryptedMsg.Length);
        }
        /// <summary>
        /// Called by clients to authenticate the server and optionally the client in
        /// a client-server connection.
        /// </summary>
        /// <param name="targetHost">The name of the server that share this connection.</param>
        public void AuthenticateAsClient(object targetHost)
        {
            if (targetHost is string)
            {
                dtlsClientContext = new DtlsClientSecurityContext(
                    SecurityPackageType.Schannel,
                    null,
                    (string)targetHost,
                    ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect |
                    ClientSecurityContextAttribute.Confidentiality | ClientSecurityContextAttribute.ExtendedError |
                    ClientSecurityContextAttribute.AllocMemory | ClientSecurityContextAttribute.Datagram |
                    ClientSecurityContextAttribute.UseSuppliedCreds,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

                try
                {
                    // First Initialize.
                    byte[] serverToken = null;
                    dtlsClientContext.Initialize(serverToken);
                    this.SendData(dtlsClientContext.Token);

                    while (dtlsClientContext.NeedContinueProcessing)
                    {
                        if (dtlsClientContext.HasMoreFragments)
                        {
                            dtlsClientContext.Initialize(null);
                        }
                        else
                        {
                            serverToken = this.GetReceivedData(this.timeout);
                            dtlsClientContext.Initialize(serverToken);
                        }
                        if (dtlsClientContext.Token != null)
                        {
                            this.SendData(dtlsClientContext.Token);
                        }
                    }

                    isAuthenticated = true;

                    dtlsStreamSizes = dtlsClientContext.StreamSizes;
                }
                catch
                {
                    // Don't throw exception in ThreadPool thread
                }
            }
        }
        /// <summary>
        /// Called by servers to authenticate the server and optionally the client in
        ///     a client-server connection using the specified certificate.
        /// </summary>
        /// <param name="cert">The certificate used to authenticate the server.</param>
        private void AuthenticateAsServer(object cert)
        {
            if (cert is X509Certificate)
            {
                dtlsServerContext = new DtlsServerSecurityContext(
                    SecurityPackageType.Schannel,
                    new CertificateCredential((X509Certificate)cert),
                    null,
                    ServerSecurityContextAttribute.ReplayDetect | ServerSecurityContextAttribute.SequenceDetect |
                    ServerSecurityContextAttribute.Confidentiality | ServerSecurityContextAttribute.ExtendedError |
                    ServerSecurityContextAttribute.AllocMemory | ServerSecurityContextAttribute.Datagram,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

                try
                {
                    // First accept.
                    byte[] clientToken = this.GetReceivedData(this.timeout);
                    dtlsServerContext.Accept(clientToken);
                    this.SendData(dtlsServerContext.Token);

                    while (dtlsServerContext.NeedContinueProcessing)
                    {
                        if (dtlsServerContext.HasMoreFragments)
                        {
                            dtlsServerContext.Accept(null);
                        }
                        else
                        {
                            clientToken = this.GetReceivedData(this.timeout);
                            dtlsServerContext.Accept(clientToken);
                        }
                        if (dtlsServerContext.Token != null)
                        {
                            this.SendData(dtlsServerContext.Token);
                        }
                    }


                    isAuthenticated = true;

                    dtlsStreamSizes = dtlsServerContext.StreamSizes;
                }
                catch
                {
                    // Don't throw exception in ThreadPool thread
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Called by servers to authenticate the server and optionally the client in
        ///     a client-server connection using the specified certificate.
        /// </summary>
        /// <param name="data">The authenticate as server data.</param>
        private void AuthenticateAsServerTask(AuthenticateAsServerData data)
        {
            try
            {
                var cert = data.Certificate;

                dtlsServerContext = new DtlsServerSecurityContext(
                    SecurityPackageType.Schannel,
                    new CertificateCredential((X509Certificate)cert),
                    null,
                    ServerSecurityContextAttribute.ReplayDetect | ServerSecurityContextAttribute.SequenceDetect |
                    ServerSecurityContextAttribute.Confidentiality | ServerSecurityContextAttribute.ExtendedError |
                    ServerSecurityContextAttribute.Datagram,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

                // First accept.
                byte[] clientToken = this.GetReceivedData(this.timeout);
                dtlsServerContext.Accept(clientToken);
                this.SendData(dtlsServerContext.Token);

                while (dtlsServerContext.NeedContinueProcessing)
                {
                    if (dtlsServerContext.HasMoreFragments)
                    {
                        dtlsServerContext.Accept(null);
                    }
                    else
                    {
                        clientToken = this.GetReceivedData(this.timeout);
                        dtlsServerContext.Accept(clientToken);
                    }
                    if (dtlsServerContext.Token != null)
                    {
                        this.SendData(dtlsServerContext.Token);
                    }
                }


                isAuthenticated = true;

                dtlsStreamSizes = dtlsServerContext.StreamSizes;
            }
            catch (Exception ex)
            {
                data.Exception = ex;
            }
        }