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); }