Beispiel #1
0
        private SafeFreeCertContext ExtractCertificateHandle(ContextAttribute contextAttribute)
        {
            SafeFreeCertContext result = SspiWrapper.QueryContextAttributes(this.securityContext, contextAttribute) as SafeFreeCertContext;

            return(result);
        }
        void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool ownCredentialsHandle         = false;
            SafeDeleteContext securityContext = null;

            try
            {
                if (credentialsHandle == null)
                {
                    if (networkCredential == null || networkCredential == CredentialCache.DefaultNetworkCredentials)
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Outbound);
                    }
                    else
                    {
                        AuthIdentityEx authIdentity = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", CredentialUse.Outbound, ref authIdentity);
                    }
                    ownCredentialsHandle = true;
                }

                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory
                                               | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.ReplayDetect
                                               | SspiContextFlags.SequenceDetect;


                // we only accept Identity or Impersonation (Impersonation is default).
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    fContextReq |= SspiContextFlags.InitIdentify;
                }

                SspiContextFlags contextFlags     = SspiContextFlags.Zero;
                SecurityBuffer   inSecurityBuffer = null;
                if (channelBinding != null)
                {
                    inSecurityBuffer = new SecurityBuffer(channelBinding);
                }
                SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                int statusCode = SspiWrapper.InitializeSecurityContext(
                    credentialsHandle,
                    ref securityContext,
                    this.servicePrincipalName,
                    fContextReq,
                    Endianness.Native,
                    inSecurityBuffer,
                    outSecurityBuffer,
                    ref contextFlags);

                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    SecurityTraceRecordHelper.TraceChannelBindingInformation(null, false, channelBinding);
                }

                if (statusCode != (int)SecurityStatus.OK)
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.FailInitializeSecurityContext), new Win32Exception(statusCode)));
                    }
                }

#if REMOVEGSS
                //
                // ... and strip GSS-framing from it
                //
                int offset = 0;
                int len    = outSecurityBuffer.token.Length;
                DEREncoding.VerifyTokenHeader(outSecurityBuffer.token, ref offset, ref len);
                this.apreq = SecurityUtils.CloneBuffer(outSecurityBuffer.token, offset, len);
#else
                this.apreq = outSecurityBuffer.token;
#endif

                // Expiration
                LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan);
                this.effectiveTime  = lifeSpan.EffectiveTimeUtc;
                this.expirationTime = lifeSpan.ExpiryTimeUtc;

                // SessionKey
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);
            }
            finally
            {
                if (securityContext != null)
                {
                    securityContext.Close();
                }

                if (ownCredentialsHandle && credentialsHandle != null)
                {
                    credentialsHandle.Close();
                }
            }
        }
Beispiel #3
0
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            SecurityBuffer incomingSecurity = null;

            if (incomingBlob != null)
            {
                incomingSecurity = new SecurityBuffer(incomingBlob, BufferType.Token);
            }

            SecurityBuffer outgoingSecurity = new SecurityBuffer(null, BufferType.Token);

            this.remoteCertificate = null;
            int statusCode = 0;

            if (this.isServer == true)
            {
                statusCode = SspiWrapper.AcceptSecurityContext(
                    this.credentialsHandle,
                    ref this.securityContext,
                    ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero),
                    Endianness.Native,
                    incomingSecurity,
                    outgoingSecurity,
                    ref this.attributes
                    );
            }
            else
            {
                statusCode = SspiWrapper.InitializeSecurityContext(
                    this.credentialsHandle,
                    ref this.securityContext,
                    this.destination,
                    ClientStandardFlags,
                    Endianness.Native,
                    incomingSecurity,
                    outgoingSecurity,
                    ref this.attributes
                    );
            }

            if ((statusCode & unchecked ((int)0x80000000)) != 0)
            {
                this.Dispose();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                // ensure that the key negotiated is strong enough
                if (SecurityUtils.ShouldValidateSslCipherStrength())
                {
                    SslConnectionInfo connectionInfo = (SslConnectionInfo)SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo);
                    if (connectionInfo == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.CannotObtainSslConnectionInfo)));
                    }
                    SecurityUtils.ValidateSslCipherStrength(connectionInfo.DataKeySize);
                }
                this.isCompleted = true;
            }
            else if (statusCode == (int)SecurityStatus.CredentialsNeeded)
            {
                // the server requires the client to supply creds
                // Currently we dont attempt to find the client cert to choose at runtime
                // so just re-call the function
                AcquireClientCredentials();
                if (this.ClientCertificate != null)
                {
                    this.wasClientCertificateSent = true;
                }
                return(this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy));
            }
            else if (statusCode != (int)SecurityStatus.ContinueNeeded)
            {
                this.Dispose();
                if (statusCode == (int)SecurityStatus.InternalError)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.LsaAuthorityNotContacted)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
                }
            }
            return(outgoingSecurity.token);
        }
        private void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, System.IdentityModel.SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool flag = false;

            System.IdentityModel.SafeDeleteContext context = null;
            try
            {
                if (credentialsHandle == null)
                {
                    if ((networkCredential == null) || (networkCredential == CredentialCache.DefaultNetworkCredentials))
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", System.IdentityModel.CredentialUse.Outbound, new string[0]);
                    }
                    else
                    {
                        AuthIdentityEx authdata = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain, new string[0]);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", System.IdentityModel.CredentialUse.Outbound, ref authdata);
                    }
                    flag = true;
                }
                SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    inFlags |= SspiContextFlags.InitIdentify;
                }
                SspiContextFlags zero = SspiContextFlags.Zero;
                System.IdentityModel.SecurityBuffer inputBuffer = null;
                if (channelBinding != null)
                {
                    inputBuffer = new System.IdentityModel.SecurityBuffer(channelBinding);
                }
                System.IdentityModel.SecurityBuffer outputBuffer = new System.IdentityModel.SecurityBuffer(0, System.IdentityModel.BufferType.Token);
                int error = SspiWrapper.InitializeSecurityContext(credentialsHandle, ref context, this.servicePrincipalName, inFlags, System.IdentityModel.Endianness.Native, inputBuffer, outputBuffer, ref zero);
                switch (error)
                {
                case 0:
                    break;

                case 0x90312:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error)));

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailInitializeSecurityContext"), new Win32Exception(error)));
                }
                this.apreq = outputBuffer.token;
                LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.Lifespan);
                this.effectiveTime  = span.EffectiveTimeUtc;
                this.expirationTime = span.ExpiryTimeUtc;
                SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
            }
            finally
            {
                if (context != null)
                {
                    context.Close();
                }
                if (flag && (credentialsHandle != null))
                {
                    credentialsHandle.Close();
                }
            }
        }
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            this.ThrowIfDisposed();
            SecurityBuffer inputBuffer = null;

            if (incomingBlob != null)
            {
                inputBuffer = new SecurityBuffer(incomingBlob, System.IdentityModel.BufferType.Token);
            }
            SecurityBuffer outputBuffer = new SecurityBuffer(null, System.IdentityModel.BufferType.Token);

            this.remoteCertificate = null;
            int error = 0;

            if (this.isServer)
            {
                error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero), Endianness.Native, inputBuffer, outputBuffer, ref this.attributes);
            }
            else
            {
                error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.destination, ClientStandardFlags, Endianness.Native, inputBuffer, outputBuffer, ref this.attributes);
            }
            if ((error & -2147483648) != 0)
            {
                this.Dispose();
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            }
            if (error == 0)
            {
                if (System.ServiceModel.Security.SecurityUtils.ShouldValidateSslCipherStrength())
                {
                    SslConnectionInfo info = (SslConnectionInfo)SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo);
                    if (info == null)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("CannotObtainSslConnectionInfo")));
                    }
                    System.ServiceModel.Security.SecurityUtils.ValidateSslCipherStrength(info.DataKeySize);
                }
                this.isCompleted = true;
            }
            else
            {
                if (error == 0x90320)
                {
                    this.AcquireClientCredentials();
                    if (this.ClientCertificate != null)
                    {
                        this.wasClientCertificateSent = true;
                    }
                    return(this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy));
                }
                if (error != 0x90312)
                {
                    this.Dispose();
                    if (error == -2146893052)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("LsaAuthorityNotContacted")));
                    }
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                }
            }
            return(outputBuffer.token);
        }
        // This internal API is not thread-safe.  It is acceptable since ..
        // 1) From public OM, Initialize happens at ctor time.
        // 2) From internal OM (Sfx), Initialize happens right after ctor (single thread env).
        //    i.e. ReadToken and then AuthenticateToken.
        internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            if (this.isAuthenticated)
            {
                return;
            }
            bool ownCredentialsHandle         = false;
            SafeDeleteContext securityContext = null;
            SafeCloseHandle   tokenHandle     = null;

#if RECOMPUTEGSS
            int    tokenSize  = DEREncoding.TokenSize(this.request.Length);
            byte[] rawRequest = new byte[tokenSize];
            int    offset     = 0;
            int    len        = this.request.Length;
            DEREncoding.MakeTokenHeader(this.request.Length, rawRequest, ref offset, ref len);
            System.Buffer.BlockCopy(this.request, 0, rawRequest, offset, this.request.Length);
#else
            byte[] rawRequest = this.request;
#endif

            try
            {
                if (credentialsHandle == null)
                {
                    credentialsHandle    = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound);
                    ownCredentialsHandle = true;
                }

                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.ReplayDetect
                                               | SspiContextFlags.SequenceDetect;

                ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy);

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    fContextReq |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    fContextReq |= SspiContextFlags.ChannelBindingProxyBindings;
                }

                SspiContextFlags contextFlags      = SspiContextFlags.Zero;
                SecurityBuffer   outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                List <SecurityBuffer> list = new List <SecurityBuffer>(2);
                list.Add(new SecurityBuffer(rawRequest, BufferType.Token));

                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }

                SecurityBuffer[] inSecurityBuffer = null;
                if (list.Count > 0)
                {
                    inSecurityBuffer = list.ToArray();
                }

                int statusCode = SspiWrapper.AcceptSecurityContext(credentialsHandle,
                                                                   ref securityContext,
                                                                   fContextReq,
                                                                   Endianness.Native,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref contextFlags);


                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, true, channelBinding);
                }

                if (statusCode != (int)SecurityStatus.OK)
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    }
                    else if (statusCode == (int)SecurityStatus.OutOfMemory)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosApReqInvalidOrOutOfMemory), new Win32Exception(statusCode)));
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.FailAcceptSecurityContext), new Win32Exception(statusCode)));
                    }
                }

                // Expiration
                LifeSpan lifeSpan       = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan);
                DateTime effectiveTime  = lifeSpan.EffectiveTimeUtc;
                DateTime expirationTime = lifeSpan.ExpiryTimeUtc;

                // SessionKey
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);

                // WindowsSecurityToken
                statusCode = SspiWrapper.QuerySecurityContextToken(securityContext, out tokenHandle);
                if (statusCode != (int)SecurityStatus.OK)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
                }

                WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeKerberos);
                Initialize(this.id, SecurityUtils.AuthTypeKerberos, effectiveTime, expirationTime, windowsIdentity, false);

                // Authenticated
                this.isAuthenticated = true;
            }
            finally
            {
                if (tokenHandle != null)
                {
                    tokenHandle.Close();
                }

                if (securityContext != null)
                {
                    securityContext.Close();
                }

                if (ownCredentialsHandle && credentialsHandle != null)
                {
                    credentialsHandle.Close();
                }
            }
        }
Beispiel #7
0
        internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            if (!this.isAuthenticated)
            {
                bool flag = false;
                SafeDeleteContext refContext = null;
                SafeCloseHandle   token      = null;
                byte[]            request    = this.request;
                try
                {
                    if (credentialsHandle == null)
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound, new string[0]);
                        flag = true;
                    }
                    SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                    ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy);
                    if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SecurityChannelBindingMissing")));
                    }
                    if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                    {
                        inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                    }
                    if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                    {
                        inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                    }
                    SspiContextFlags      zero         = SspiContextFlags.Zero;
                    SecurityBuffer        outputBuffer = new SecurityBuffer(0, BufferType.Token);
                    List <SecurityBuffer> list         = new List <SecurityBuffer>(2)
                    {
                        new SecurityBuffer(request, 2)
                    };
                    if (helper.ShouldAddChannelBindingToASC())
                    {
                        list.Add(new SecurityBuffer(helper.ChannelBinding));
                    }
                    SecurityBuffer[] inputBuffers = null;
                    if (list.Count > 0)
                    {
                        inputBuffers = list.ToArray();
                    }
                    int error = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref refContext, inFlags, Endianness.Native, inputBuffers, outputBuffer, ref zero);
                    switch (error)
                    {
                    case 0:
                        break;

                    case 0x90312:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error)));

                    case -2146893056:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosApReqInvalidOrOutOfMemory"), new Win32Exception(error)));

                    default:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailAcceptSecurityContext"), new Win32Exception(error)));
                    }
                    LifeSpan span                  = (LifeSpan)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.Lifespan);
                    DateTime effectiveTimeUtc      = span.EffectiveTimeUtc;
                    DateTime expiryTimeUtc         = span.ExpiryTimeUtc;
                    SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.SessionKey);
                    this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
                    error = SspiWrapper.QuerySecurityContextToken(refContext, out token);
                    if (error != 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                    }
                    System.Security.Principal.WindowsIdentity windowsIdentity = new System.Security.Principal.WindowsIdentity(token.DangerousGetHandle(), "Kerberos");
                    base.Initialize(this.id, "Kerberos", effectiveTimeUtc, expiryTimeUtc, windowsIdentity, false);
                    this.isAuthenticated = true;
                }
                finally
                {
                    if (token != null)
                    {
                        token.Close();
                    }
                    if (refContext != null)
                    {
                        refContext.Close();
                    }
                    if (flag && (credentialsHandle != null))
                    {
                        credentialsHandle.Close();
                    }
                }
            }
        }