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; }
public static unsafe int EncryptDecryptHelper(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool encrypt, bool isGssBlob) { int num6; SecurityBufferStruct[] structArray2; SecurityBufferDescriptor inputOutput = new SecurityBufferDescriptor(input.Length); SecurityBufferStruct[] structArray = new SecurityBufferStruct[input.Length]; byte[][] bufferArray = new byte[input.Length][]; if (((structArray2 = structArray) == null) || (structArray2.Length == 0)) { fixed (IntPtr* ptrRef = null) { } } inputOutput.UnmanagedPointer = (void*) ptrRef; GCHandle[] handleArray = new GCHandle[input.Length]; try { int num2; for (int i = 0; i < input.Length; i++) { SecurityBuffer buffer = input[i]; structArray[i].count = buffer.size; structArray[i].type = buffer.type; if ((buffer.token == null) || (buffer.token.Length == 0)) { structArray[i].token = IntPtr.Zero; } else { handleArray[i] = GCHandle.Alloc(buffer.token, GCHandleType.Pinned); structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.token, buffer.offset); bufferArray[i] = buffer.token; } } if (encrypt) { num2 = SafeDeleteContext.EncryptMessage(context, inputOutput, sequenceNumber); } else { num2 = SafeDeleteContext.DecryptMessage(context, inputOutput, sequenceNumber); } for (int j = 0; j < input.Length; j++) { SecurityBuffer buffer2 = input[j]; buffer2.size = structArray[j].count; buffer2.type = structArray[j].type; if (buffer2.size == 0) { buffer2.offset = 0; buffer2.token = null; continue; } if ((isGssBlob && !encrypt) && (buffer2.type == BufferType.Data)) { buffer2.token = DiagnosticUtility.Utility.AllocateByteArray(buffer2.size); Marshal.Copy(structArray[j].token, buffer2.token, 0, buffer2.size); continue; } int index = 0; while (index < input.Length) { if (bufferArray[index] != null) { byte* numPtr = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(bufferArray[index], 0); if ((((void*) structArray[j].token) >= numPtr) && ((((void*) structArray[j].token) + buffer2.size) <= (numPtr + bufferArray[index].Length))) { buffer2.offset = (int) ((long) ((((void*) structArray[j].token) - numPtr) / 1)); buffer2.token = bufferArray[index]; break; } } index++; } if (index >= input.Length) { buffer2.size = 0; buffer2.offset = 0; buffer2.token = null; } if ((buffer2.offset < 0) || (buffer2.offset > ((buffer2.token == null) ? 0 : buffer2.token.Length))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.IdentityModel.SR.GetString("SspiWrapperEncryptDecryptAssert1", new object[] { buffer2.offset }))); } if ((buffer2.size < 0) || (buffer2.size > ((buffer2.token == null) ? 0 : (buffer2.token.Length - buffer2.offset)))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.IdentityModel.SR.GetString("SspiWrapperEncryptDecryptAssert2", new object[] { buffer2.size }))); } } num6 = num2; } finally { for (int k = 0; k < handleArray.Length; k++) { if (handleArray[k].IsAllocated) { handleArray[k].Free(); } } } return num6; }
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(); } } }
internal static int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SspiContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref SspiContextFlags outFlags) { return SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags); }
public static int DecryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool isGssBlob) { return EncryptDecryptHelper(context, input, sequenceNumber, false, isGssBlob); }
public static unsafe int EncryptDecryptHelper(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool encrypt, bool isGssBlob) { SecurityBufferDescriptor sdcInOut = new SecurityBufferDescriptor(input.Length); SecurityBufferStruct[] unmanagedBuffer = new SecurityBufferStruct[input.Length]; byte[][] buffers = new byte[input.Length][]; fixed(void *unmanagedBufferPtr = unmanagedBuffer) { sdcInOut.UnmanagedPointer = unmanagedBufferPtr; GCHandle[] pinnedBuffers = new GCHandle[input.Length]; try { for (int i = 0; i < input.Length; ++i) { SecurityBuffer iBuffer = input[i]; unmanagedBuffer[i].count = iBuffer.size; unmanagedBuffer[i].type = iBuffer.type; if (iBuffer.token == null || iBuffer.token.Length == 0) { unmanagedBuffer[i].token = IntPtr.Zero; } else { pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); buffers[i] = iBuffer.token; } } int errorCode; if (encrypt) { errorCode = SafeDeleteContext.EncryptMessage(context, sdcInOut, sequenceNumber); } else { errorCode = SafeDeleteContext.DecryptMessage(context, sdcInOut, sequenceNumber); } // Marshalling back returned sizes (do not marshal the "token" field) for (int i = 0; i < input.Length; ++i) { SecurityBuffer iBuffer = input[i]; iBuffer.size = unmanagedBuffer[i].count; iBuffer.type = unmanagedBuffer[i].type; if (iBuffer.size == 0) { iBuffer.offset = 0; iBuffer.token = null; } else if (isGssBlob && !encrypt && iBuffer.type == BufferType.Data) { iBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(iBuffer.size); Marshal.Copy(unmanagedBuffer[i].token, iBuffer.token, 0, iBuffer.size); } else { checked { // Find the buffer this is inside of. Usually they all point inside buffer 0. int j; for (j = 0; j < input.Length; j++) { if (buffers[j] == null) { continue; } byte *bufferAddress = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0); if ((byte *)unmanagedBuffer[i].token >= bufferAddress && (byte *)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length) { iBuffer.offset = (int)((byte *)unmanagedBuffer[i].token - bufferAddress); iBuffer.token = buffers[j]; break; } } if (j >= input.Length) { iBuffer.size = 0; iBuffer.offset = 0; iBuffer.token = null; } if (!(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length))) { DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset)); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset))); } if (!(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset))) { DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size)); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size))); } } } } return(errorCode); } finally { for (int i = 0; i < pinnedBuffers.Length; ++i) { if (pinnedBuffers[i].IsAllocated) { pinnedBuffers[i].Free(); } } } } }
public static int EncryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { return EncryptDecryptHelper(context, input, sequenceNumber, true, false); }
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; }
//------------------------------------------------------------------- internal static unsafe int AcceptSecurityContext( SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, SspiContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref SspiContextFlags outFlags) { if (inCredentials == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials"); } SecurityBufferDescriptor inSecurityBufferDescriptor = null; if (inSecBuffer != null) { inSecurityBufferDescriptor = new SecurityBufferDescriptor(1); } else if (inSecBuffers != null) { inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length); } SecurityBufferDescriptor outSecurityBufferDescriptor = new SecurityBufferDescriptor(1); // actually this is returned in outFlags bool isSspiAllocated = (inFlags & SspiContextFlags.AllocateMemory) != 0 ? true : false; int errorCode = -1; SSPIHandle contextHandle = new SSPIHandle(); if (refContext != null) { contextHandle = refContext._handle; } // these are pinned user byte arrays passed along with SecurityBuffers GCHandle[] pinnedInBytes = null; GCHandle pinnedOutBytes = new GCHandle(); // optional output buffer that may need to be freed SafeFreeContextBuffer outFreeContextBuffer = null; try { pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { if (inSecurityBufferDescriptor != null) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; SecurityBuffer securityBuffer; for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) { securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index]; if (securityBuffer != null) { // Copy the SecurityBuffer content into unmanaged place holder inUnmanagedBuffer[index].count = securityBuffer.size; inUnmanagedBuffer[index].type = securityBuffer.type; // use the unmanaged token if it's not null; otherwise use the managed buffer if (securityBuffer.unmanagedToken != null) { inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { inUnmanagedBuffer[index].token = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } } } } SecurityBufferStruct[] outUnmanagedBuffer = new SecurityBufferStruct[1]; fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr; // Copy the SecurityBuffer content into unmanaged place holder outUnmanagedBuffer[0].count = outSecBuffer.size; outUnmanagedBuffer[0].type = outSecBuffer.type; if (outSecBuffer.token == null || outSecBuffer.token.Length == 0) { outUnmanagedBuffer[0].token = IntPtr.Zero; } else { outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (isSspiAllocated) { outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle(); } if (refContext == null || refContext.IsInvalid) { refContext = new SafeDeleteContext(); } errorCode = MustRunAcceptSecurityContext( inCredentials, contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor, inFlags, endianness, refContext, outSecurityBufferDescriptor, ref outFlags, outFreeContextBuffer ); // Get unmanaged buffer with index 0 as the only one passed into PInvoke outSecBuffer.size = outUnmanagedBuffer[0].count; outSecBuffer.type = outUnmanagedBuffer[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size); Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size); } else { outSecBuffer.token = null; } } } } finally { if (pinnedInBytes != null) { for (int index = 0; index < pinnedInBytes.Length; index++) { if (pinnedInBytes[index].IsAllocated) { pinnedInBytes[index].Free(); } } } if (pinnedOutBytes.IsAllocated) { pinnedOutBytes.Free(); } if (outFreeContextBuffer != null) { outFreeContextBuffer.Close(); } } return errorCode; }
internal void DecryptInPlace(byte[] encryptedContent, out int dataStartOffset, out int dataLen) { this.ThrowIfDisposed(); dataStartOffset = this.StreamSizes.header; dataLen = 0; byte[] data = new byte[0]; byte[] buffer2 = new byte[0]; byte[] buffer3 = new byte[0]; SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, System.IdentityModel.BufferType.Data), new SecurityBuffer(data, System.IdentityModel.BufferType.Empty), new SecurityBuffer(buffer2, System.IdentityModel.BufferType.Empty), new SecurityBuffer(buffer3, System.IdentityModel.BufferType.Empty) }; int error = SspiWrapper.DecryptMessage(this.securityContext, input, 0, false); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } for (int i = 0; i < input.Length; i++) { if (input[i].type == System.IdentityModel.BufferType.Data) { dataLen = input[i].size; return; } } this.OnBadData(); }
internal void EncryptInPlace(byte[] buffer, int bufferStartOffset, int dataLen, out int encryptedDataLen) { this.ThrowIfDisposed(); encryptedDataLen = 0; if ((((bufferStartOffset + dataLen) + this.StreamSizes.header) + this.StreamSizes.trailer) > buffer.Length) { this.OnBadData(); } byte[] data = new byte[0]; int offset = (bufferStartOffset + this.StreamSizes.header) + dataLen; SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(buffer, bufferStartOffset, this.StreamSizes.header, System.IdentityModel.BufferType.Header), new SecurityBuffer(buffer, bufferStartOffset + this.StreamSizes.header, dataLen, System.IdentityModel.BufferType.Data), new SecurityBuffer(buffer, offset, this.StreamSizes.trailer, System.IdentityModel.BufferType.Trailer), new SecurityBuffer(data, System.IdentityModel.BufferType.Empty) }; int error = SspiWrapper.EncryptMessage(this.securityContext, input, 0); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } int size = 0; for (int i = 0; i < input.Length; i++) { if (input[i].type == System.IdentityModel.BufferType.Trailer) { size = input[i].size; encryptedDataLen = (this.StreamSizes.header + dataLen) + size; return; } } this.OnBadData(); }
public byte[] Decrypt(byte[] encryptedContent) { if (encryptedContent == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptedContent"); } this.ThrowIfDisposed(); SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Stream), new SecurityBuffer(0, BufferType.Data) }; int error = SspiWrapper.DecryptMessage(this.securityContext, input, 0, true); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } for (int i = 0; i < input.Length; i++) { if (input[i].type == BufferType.Data) { return input[i].token; } } this.OnBadData(); return null; }
public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy) { this.ThrowIfDisposed(); int error = 0; SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect; if (this.doMutualAuth) { inFlags |= SspiContextFlags.MutualAuth; } if (this.impersonationLevel == TokenImpersonationLevel.Delegation) { inFlags |= SspiContextFlags.Delegate; } else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification)) { inFlags |= SspiContextFlags.InitIdentify; } else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous)) { inFlags |= SspiContextFlags.InitAnonymous; } ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy); if (this.isServer) { if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing"))); } if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy) { inFlags |= SspiContextFlags.ChannelBindingProxyBindings; } } List<SecurityBuffer> list = new List<SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } if (this.isServer) { if (helper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } } else if (helper.ChannelBinding != null) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } SecurityBuffer[] inputBuffers = null; if (list.Count > 0) { inputBuffers = list.ToArray(); } SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token); if (!this.isServer) { error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); } else { bool flag = this.securityContext == null; SspiContextFlags contextFlags = this.contextFlags; error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); if ((error == -2146893048) && !flag) { this.contextFlags = contextFlags; this.CloseContext(); error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags); } } if ((error & -2147483648) != 0) { if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint) error))) && SspiWrapper.IsNegotiateExPackagePresent()) { if (this.MaxPromptAttempts >= 1) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials"))); } IntPtr zero = IntPtr.Zero; uint num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi); if (num2 == 0) { IntPtr ppNewAuthIdentity = IntPtr.Zero; if (!this.allowNtlm) { UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity); } else { ppNewAuthIdentity = zero; } this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity); if (IntPtr.Zero != ppNewAuthIdentity) { UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity); } this.CloseContext(); this.MaxPromptAttempts++; return this.GetOutgoingBlob(null, channelbinding, protectionPolicy); } if (IntPtr.Zero != zero) { UnsafeNativeMethods.SspiFreeAuthIdentity(zero); } this.CloseContext(); this.isCompleted = true; throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int) num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials"))); } this.CloseContext(); this.isCompleted = true; if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022))) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation"))); } throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName }))); } if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation) { if (this.isServer) { SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this); } else { SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this); } } if (error == 0) { this.isCompleted = true; if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding)) { helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName); } } return outputBuffer.token; }
public byte[] Encrypt(byte[] input) { if (input == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("input"); } this.ThrowIfDisposed(); SecurityBuffer[] bufferArray = new SecurityBuffer[3]; byte[] data = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(this.SecuritySizes.SecurityTrailer); bufferArray[0] = new SecurityBuffer(data, 0, data.Length, BufferType.Token); byte[] dst = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(input.Length); Buffer.BlockCopy(input, 0, dst, 0, input.Length); bufferArray[1] = new SecurityBuffer(dst, 0, dst.Length, BufferType.Data); byte[] buffer3 = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(this.SecuritySizes.BlockSize); bufferArray[2] = new SecurityBuffer(buffer3, 0, buffer3.Length, BufferType.Padding); int error = SspiWrapper.EncryptMessage(this.securityContext, bufferArray, 0); if (error != 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } int count = 0; int size = 0; for (int i = 0; i < bufferArray.Length; i++) { if (bufferArray[i].type == BufferType.Token) { count = bufferArray[i].size; } else if (bufferArray[i].type == BufferType.Padding) { size = bufferArray[i].size; } } byte[] buffer4 = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray((count + dst.Length) + size); Buffer.BlockCopy(data, 0, buffer4, 0, count); Buffer.BlockCopy(dst, 0, buffer4, count, dst.Length); Buffer.BlockCopy(buffer3, 0, buffer4, count + dst.Length, size); return buffer4; }
/// <summary> /// The decrypted data will start header bytes from the start of /// encryptedContent array. /// </summary> internal unsafe void DecryptInPlace(byte[] encryptedContent, out int dataStartOffset, out int dataLen) { ThrowIfDisposed(); dataStartOffset = StreamSizes.header; dataLen = 0; byte[] emptyBuffer1 = new byte[0]; byte[] emptyBuffer2 = new byte[0]; byte[] emptyBuffer3 = new byte[0]; SecurityBuffer[] securityBuffer = new SecurityBuffer[4]; securityBuffer[0] = new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Data); securityBuffer[1] = new SecurityBuffer(emptyBuffer1, BufferType.Empty); securityBuffer[2] = new SecurityBuffer(emptyBuffer2, BufferType.Empty); securityBuffer[3] = new SecurityBuffer(emptyBuffer3, BufferType.Empty); int errorCode = SspiWrapper.DecryptMessage(this.securityContext, securityBuffer, 0, false); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Data) { dataLen = securityBuffer[i].size; return; } } OnBadData(); }
internal static int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext refContext, SspiContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref SspiContextFlags outFlags) { return SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags); }
/// <summary> /// Assumes that the data to encrypt is "header" bytes ahead of bufferStartOffset /// </summary> internal unsafe void EncryptInPlace(byte[] buffer, int bufferStartOffset, int dataLen, out int encryptedDataLen) { ThrowIfDisposed(); encryptedDataLen = 0; if (bufferStartOffset + dataLen + StreamSizes.header + StreamSizes.trailer > buffer.Length) { OnBadData(); } byte[] emptyBuffer = new byte[0]; int trailerOffset = bufferStartOffset + StreamSizes.header + dataLen; SecurityBuffer[] securityBuffer = new SecurityBuffer[4]; securityBuffer[0] = new SecurityBuffer(buffer, bufferStartOffset, StreamSizes.header, BufferType.Header); securityBuffer[1] = new SecurityBuffer(buffer, bufferStartOffset + StreamSizes.header, dataLen, BufferType.Data); securityBuffer[2] = new SecurityBuffer(buffer, trailerOffset, StreamSizes.trailer, BufferType.Trailer); securityBuffer[3] = new SecurityBuffer(emptyBuffer, BufferType.Empty); int errorCode = SspiWrapper.EncryptMessage(this.securityContext, securityBuffer, 0); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } int trailerSize = 0; for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Trailer) { trailerSize = securityBuffer[i].size; encryptedDataLen = StreamSizes.header + dataLen + trailerSize; return; } } OnBadData(); }
internal static unsafe int InitializeSecurityContext(SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, string targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref SspiContextFlags outFlags) { if (inCredentials == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials"); } SecurityBufferDescriptor inputBuffer = null; if (inSecBuffer != null) { inputBuffer = new SecurityBufferDescriptor(1); } else if (inSecBuffers != null) { inputBuffer = new SecurityBufferDescriptor(inSecBuffers.Length); } SecurityBufferDescriptor outputBuffer = new SecurityBufferDescriptor(1); bool flag = (inFlags & SspiContextFlags.AllocateMemory) != SspiContextFlags.Zero; int num = -1; SSPIHandle handle = new SSPIHandle(); if (refContext != null) { handle = refContext._handle; } GCHandle[] handleArray = null; GCHandle handle2 = new GCHandle(); SafeFreeContextBuffer handleTemplate = null; try { handle2 = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); SecurityBufferStruct[] structArray = new SecurityBufferStruct[(inputBuffer == null) ? 1 : inputBuffer.Count]; try { SecurityBufferStruct[] structArray3; if (((structArray3 = structArray) == null) || (structArray3.Length == 0)) { ptrRef = null; goto Label_00A9; } fixed (IntPtr* ptrRef = structArray3) { Label_00A9: if (inputBuffer != null) { inputBuffer.UnmanagedPointer = (void*) ptrRef; handleArray = new GCHandle[inputBuffer.Count]; for (int i = 0; i < inputBuffer.Count; i++) { SecurityBuffer buffer2 = (inSecBuffer != null) ? inSecBuffer : inSecBuffers[i]; if (buffer2 != null) { structArray[i].count = buffer2.size; structArray[i].type = buffer2.type; if (buffer2.unmanagedToken != null) { structArray[i].token = buffer2.unmanagedToken.DangerousGetHandle(); } else if ((buffer2.token == null) || (buffer2.token.Length == 0)) { structArray[i].token = IntPtr.Zero; } else { handleArray[i] = GCHandle.Alloc(buffer2.token, GCHandleType.Pinned); structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2.token, buffer2.offset); } } } } SecurityBufferStruct[] structArray2 = new SecurityBufferStruct[1]; try { SecurityBufferStruct[] structArray4; if (((structArray4 = structArray2) == null) || (structArray4.Length == 0)) { ptrRef2 = null; goto Label_01CF; } fixed (IntPtr* ptrRef2 = structArray4) { Label_01CF: outputBuffer.UnmanagedPointer = (void*) ptrRef2; structArray2[0].count = outSecBuffer.size; structArray2[0].type = outSecBuffer.type; if ((outSecBuffer.token == null) || (outSecBuffer.token.Length == 0)) { structArray2[0].token = IntPtr.Zero; } else { structArray2[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (flag) { handleTemplate = SafeFreeContextBuffer.CreateEmptyHandle(); } if ((refContext == null) || refContext.IsInvalid) { refContext = new SafeDeleteContext(); } if ((targetName == null) || (targetName.Length == 0)) { targetName = " "; } fixed (char* str = ((char*) targetName)) { char* chPtr = str; num = MustRunInitializeSecurityContext(inCredentials, handle.IsZero ? null : ((void*) &handle), (targetName == " ") ? null : ((byte*) chPtr), inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate); } outSecBuffer.size = structArray2[0].count; outSecBuffer.type = structArray2[0].type; if (outSecBuffer.size > 0) { outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size); Marshal.Copy(structArray2[0].token, outSecBuffer.token, 0, outSecBuffer.size); return num; } outSecBuffer.token = null; return num; } } finally { ptrRef2 = null; } return num; } } finally { ptrRef = null; } } finally { if (handleArray != null) { for (int j = 0; j < handleArray.Length; j++) { if (handleArray[j].IsAllocated) { handleArray[j].Free(); } } } if (handle2.IsAllocated) { handle2.Free(); } if (handleTemplate != null) { handleTemplate.Close(); } } return num; }