Example #1
0
        internal X509Certificate2 GetRemoteCertificate(out X509Certificate2Collection remoteCertificateStore)
        {
            remoteCertificateStore = null;
            if (this.m_SecurityContext == null)
            {
                return(null);
            }
            X509Certificate2    certificate = null;
            SafeFreeCertContext certContext = null;

            try
            {
                certContext = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.RemoteCertificate) as SafeFreeCertContext;
                if ((certContext != null) && !certContext.IsInvalid)
                {
                    certificate = new X509Certificate2(certContext.DangerousGetHandle());
                }
            }
            finally
            {
                if (certContext != null)
                {
                    remoteCertificateStore = UnmanagedCertificateContext.GetStore(certContext);
                    certContext.Close();
                }
            }
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, SR.GetString("net_log_remote_certificate", new object[] { (certificate == null) ? "null" : certificate.ToString(true) }));
            }
            return(certificate);
        }
Example #2
0
        public static void QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo)
        {
            var interopConnectionInfo = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPISecureChannel,
                securityContext,
                Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO) as SecPkgContext_ConnectionInfo;

            connectionInfo = new SslConnectionInfo(interopConnectionInfo);
        }
Example #3
0
        public static void QueryContextStreamSizes(SafeDeleteContext securityContext, out StreamSizes streamSizes)
        {
            var interopStreamSizes = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPISecureChannel,
                securityContext,
                Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES) as SecPkgContext_StreamSizes;

            streamSizes = new StreamSizes(interopStreamSizes);
        }
Example #4
0
        internal static byte[] GetNegotiatedApplicationProtocol(SafeDeleteContext context)
        {
            Interop.SecPkgContext_ApplicationProtocol alpnContext = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPISecureChannel,
                context,
                Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL) as Interop.SecPkgContext_ApplicationProtocol;

            // Check if the context returned is alpn data, with successful negotiation.
            if (alpnContext == null ||
                alpnContext.ProtoNegoExt != Interop.ApplicationProtocolNegotiationExt.ALPN ||
                alpnContext.ProtoNegoStatus != Interop.ApplicationProtocolNegotiationStatus.Success)
            {
                return(null);
            }

            return(alpnContext.Protocol);
        }
Example #5
0
        internal void ProcessHandshakeSuccess()
        {
            StreamSizes sizes = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.StreamSizes) as StreamSizes;

            if (sizes != null)
            {
                try
                {
                    this.m_HeaderSize  = sizes.header;
                    this.m_TrailerSize = sizes.trailer;
                    this.m_MaxDataSize = sizes.maximumMessage - (this.m_HeaderSize + this.m_TrailerSize);
                }
                catch (Exception exception)
                {
                    NclUtilities.IsFatal(exception);
                    throw;
                }
            }
            this.m_ConnectionInfo = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.ConnectionInfo) as SslConnectionInfo;
        }
Example #6
0
 private unsafe string[] GetIssuers()
 {
     string[] strArray = new string[0];
     if (this.IsValidContext)
     {
         IssuerListInfoEx ex = (IssuerListInfoEx)SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, ContextAttribute.IssuerListInfoEx);
         try
         {
             if (ex.cIssuers <= 0)
             {
                 return(strArray);
             }
             uint cIssuers = ex.cIssuers;
             strArray = new string[ex.cIssuers];
             _CERT_CHAIN_ELEMENT *handle = (_CERT_CHAIN_ELEMENT *)ex.aIssuers.DangerousGetHandle();
             for (int i = 0; i < cIssuers; i++)
             {
                 _CERT_CHAIN_ELEMENT *_cert_chain_elementPtr2 = handle + i;
                 uint   cbSize                   = _cert_chain_elementPtr2->cbSize;
                 byte * pCertContext             = (byte *)_cert_chain_elementPtr2->pCertContext;
                 byte[] encodedDistinguishedName = new byte[cbSize];
                 for (int j = 0; j < cbSize; j++)
                 {
                     encodedDistinguishedName[j] = pCertContext[j];
                 }
                 X500DistinguishedName name = new X500DistinguishedName(encodedDistinguishedName);
                 strArray[i] = name.Name;
             }
         }
         finally
         {
             if (ex.aIssuers != null)
             {
                 ex.aIssuers.Close();
             }
         }
     }
     return(strArray);
 }
        internal static int MakeSignature(SafeDeleteContext securityContext, byte[] buffer, int offset, int count, ref byte[] output)
        {
            SecPkgContext_Sizes sizes = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPIAuth,
                securityContext,
                Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES
                ) as SecPkgContext_Sizes;

            // alloc new output buffer if not supplied or too small
            int resultSize = count + sizes.cbMaxSignature;

            if (output == null || output.Length < resultSize)
            {
                output = new byte[resultSize];
            }

            // make a copy of user data for in-place encryption
            Buffer.BlockCopy(buffer, offset, output, sizes.cbMaxSignature, count);

            // setup security buffers for ssp call
            SecurityBuffer[] securityBuffer = new SecurityBuffer[2];
            securityBuffer[0] = new SecurityBuffer(output, 0, sizes.cbMaxSignature, SecurityBufferType.SECBUFFER_TOKEN);
            securityBuffer[1] = new SecurityBuffer(output, sizes.cbMaxSignature, count, SecurityBufferType.SECBUFFER_DATA);

            // call SSP Function
            int errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0);

            // throw if error
            if (errorCode != 0)
            {
                NetEventSource.Info($"MakeSignature threw error: {errorCode.ToString("x", NumberFormatInfo.InvariantInfo)}");
                throw new Win32Exception(errorCode);
            }

            // return signed size
            return(securityBuffer[0].size + securityBuffer[1].size);
        }
        internal static string QueryContextAuthenticationPackage(SafeDeleteContext securityContext)
        {
            var negotiationInfoClass = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO) as NegotiationInfoClass;

            return(negotiationInfoClass?.AuthenticationPackage);
        }
 internal static string QueryContextClientSpecifiedSpn(SafeDeleteContext securityContext)
 {
     return(SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET) as string);
 }
Example #10
0
 internal static string QueryContextAssociatedName(SafeDeleteContext securityContext)
 {
     return(SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES) as string);
 }
Example #11
0
        internal static int Encrypt(
            SafeDeleteContext securityContext,
            byte[] buffer,
            int offset,
            int count,
            bool isConfidential,
            bool isNtlm,
            ref byte[] output,
            uint sequenceNumber)
        {
            SecPkgContext_Sizes sizes = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPIAuth,
                securityContext,
                Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES
                ) as SecPkgContext_Sizes;

            try
            {
                int maxCount = checked (Int32.MaxValue - 4 - sizes.cbBlockSize - sizes.cbSecurityTrailer);

                if (count > maxCount || count < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount));
                }
            }
            catch (Exception e) when(!ExceptionCheck.IsFatal(e))
            {
                NetEventSource.Fail(null, "Arguments out of range.");
                throw;
            }

            int resultSize = count + sizes.cbSecurityTrailer + sizes.cbBlockSize;

            if (output == null || output.Length < resultSize + 4)
            {
                output = new byte[resultSize + 4];
            }

            // Make a copy of user data for in-place encryption.
            Buffer.BlockCopy(buffer, offset, output, 4 + sizes.cbSecurityTrailer, count);

            // Prepare buffers TOKEN(signature), DATA and Padding.
            var securityBuffer = new SecurityBuffer[3];

            securityBuffer[0] = new SecurityBuffer(output, 4, sizes.cbSecurityTrailer, SecurityBufferType.SECBUFFER_TOKEN);
            securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer, count, SecurityBufferType.SECBUFFER_DATA);
            securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer + count, sizes.cbBlockSize, SecurityBufferType.SECBUFFER_PADDING);

            int errorCode;

            if (isConfidential)
            {
                errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber);
            }
            else
            {
                if (isNtlm)
                {
                    securityBuffer[1].type |= SecurityBufferType.SECBUFFER_READONLY;
                }

                errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0);
            }

            if (errorCode != 0)
            {
                Exception e = new Win32Exception(errorCode);
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(null, e);
                }
                throw e;
            }

            // Compacting the result.
            resultSize = securityBuffer[0].size;
            bool forceCopy = false;

            if (resultSize != sizes.cbSecurityTrailer)
            {
                forceCopy = true;
                Buffer.BlockCopy(output, securityBuffer[1].offset, output, 4 + resultSize, securityBuffer[1].size);
            }

            resultSize += securityBuffer[1].size;
            if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.cbSecurityTrailer)))
            {
                Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size);
            }

            resultSize += securityBuffer[2].size;
            unchecked
            {
                output[0] = (byte)((resultSize) & 0xFF);
                output[1] = (byte)(((resultSize) >> 8) & 0xFF);
                output[2] = (byte)(((resultSize) >> 16) & 0xFF);
                output[3] = (byte)(((resultSize) >> 24) & 0xFF);
            }

            return(resultSize + 4);
        }
Example #12
0
 internal static string QueryContextClientSpecifiedSpn(SafeDeleteContext securityContext)
 {
     return(SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.ClientSpecifiedSpn) as string);
 }
Example #13
0
        internal static int Encrypt(
            SafeDeleteContext securityContext,
            byte[] buffer,
            int offset,
            int count,
            bool isConfidential,
            bool isNtlm,
            ref byte[] output,
            uint sequenceNumber)
        {
            SecSizes sizes = SSPIWrapper.QueryContextAttributes(
                GlobalSSPI.SSPIAuth,
                securityContext,
                Interop.SspiCli.ContextAttribute.Sizes
                ) as SecSizes;

            try
            {
                int maxCount = checked (Int32.MaxValue - 4 - sizes.BlockSize - sizes.SecurityTrailer);

                if (count > maxCount || count < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount));
                }
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range.");
                    }

                    Debug.Fail("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt", "Arguments out of range.");
                }

                throw;
            }

            int resultSize = count + sizes.SecurityTrailer + sizes.BlockSize;

            if (output == null || output.Length < resultSize + 4)
            {
                output = new byte[resultSize + 4];
            }

            // Make a copy of user data for in-place encryption.
            Buffer.BlockCopy(buffer, offset, output, 4 + sizes.SecurityTrailer, count);

            // Prepare buffers TOKEN(signature), DATA and Padding.
            var securityBuffer = new SecurityBuffer[3];

            securityBuffer[0] = new SecurityBuffer(output, 4, sizes.SecurityTrailer, SecurityBufferType.Token);
            securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer, count, SecurityBufferType.Data);
            securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer + count, sizes.BlockSize, SecurityBufferType.Padding);

            int errorCode;

            if (isConfidential)
            {
                errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber);
            }
            else
            {
                if (isNtlm)
                {
                    securityBuffer[1].type |= SecurityBufferType.ReadOnlyFlag;
                }

                errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0);
            }

            if (errorCode != 0)
            {
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Encrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo));
                }
                throw new Win32Exception(errorCode);
            }

            // Compacting the result.
            resultSize = securityBuffer[0].size;
            bool forceCopy = false;

            if (resultSize != sizes.SecurityTrailer)
            {
                forceCopy = true;
                Buffer.BlockCopy(output, securityBuffer[1].offset, output, 4 + resultSize, securityBuffer[1].size);
            }

            resultSize += securityBuffer[1].size;
            if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.SecurityTrailer)))
            {
                Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size);
            }

            resultSize += securityBuffer[2].size;
            unchecked
            {
                // TODO (Issue #6063): Should be offset by offset
                output[0] = (byte)((resultSize) & 0xFF);
                output[1] = (byte)(((resultSize) >> 8) & 0xFF);
                output[2] = (byte)(((resultSize) >> 16) & 0xFF);
                output[3] = (byte)(((resultSize) >> 24) & 0xFF);
            }

            return(resultSize + 4);
        }