/// <summary> /// Initializes a new instance of the <see cref="SecurityBufferDescriptor" /> struct. /// </summary> /// <param name="buffers">The buffers.</param> /// <exception cref="System.ArgumentException">cannot be null or 0 length;buffers</exception> public SecurityBufferDescriptor(SecurityBuffer[] buffers) { if (buffers == null || buffers.Length == 0) { throw new ArgumentException("cannot be null or 0 length", "buffers"); } BufferType = SecurityBufferType.Version; NumBuffers = buffers.Length; //Allocate memory for SecBuffer Array.... BufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityBuffer)) * NumBuffers); for (int i = 0; i < buffers.Length; i++) { var currentBuffer = buffers[i]; var currentOffset = i * Marshal.SizeOf(typeof(SecurityBuffer)); Marshal.WriteInt32(BufferPtr, currentOffset, currentBuffer.Count); var length = currentOffset + Marshal.SizeOf(typeof(int)); Marshal.WriteInt32(BufferPtr, length, (int)currentBuffer.BufferType); length = currentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int)); Marshal.WriteIntPtr(BufferPtr, length, currentBuffer.Token); } }
/// <summary> /// Initializes a new instance of the <see cref="SecurityBufferDescriptor" /> struct. /// </summary> /// <param name="secBufferBytes">The sec buffer bytes.</param> public SecurityBufferDescriptor(byte[] secBufferBytes) { BufferType = SecurityBufferType.Version; NumBuffers = 1; var buffer = new SecurityBuffer(secBufferBytes); BufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buffer)); Marshal.StructureToPtr(buffer, BufferPtr, false); }
public void EncryptMessage(byte[] inBytes, out byte[] outBytes) { outBytes = null; bool contextAddRefSuccess = false; SecurityPackageContextSizes sizes; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { uint result = Win32.QueryContextAttributes( ref _sspiHandle, QueryContextAttributes.Sizes, out sizes); DangerousRelease(); if (result != Win32.SEC_E_OK) { throw Win32.CreateException(result, "Unable to get the query context attribute sizes."); } } var buffers = new SecurityBuffer[] { new SecurityBuffer(new byte[sizes.SecurityTrailer], SecurityBufferType.Token), new SecurityBuffer(inBytes, SecurityBufferType.Data), new SecurityBuffer(new byte[sizes.BlockSize], SecurityBufferType.Padding) }; var descriptor = new SecurityBufferDescriptor(buffers); RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { try { uint result = Win32.EncryptMessage( ref _sspiHandle, EncryptQualityOfProtection.WrapNoEncrypt, ref descriptor, 0); DangerousRelease(); if (result != Win32.SEC_E_OK) { throw Win32.CreateException(result, "Unable to encrypt message."); } outBytes = descriptor.ToByteArray(); } finally { descriptor.Dispose(); } } }
public void DecryptMessage(int messageLength, byte[] encryptedBytes, out byte[] decryptedBytes) { decryptedBytes = null; byte[] encryptedMessage = new byte[messageLength]; Array.Copy(encryptedBytes, 0, encryptedMessage, 0, messageLength); int securityTrailerLength = encryptedBytes.Length - messageLength; byte[] securityTrailer = new byte[securityTrailerLength]; Array.Copy(encryptedBytes, messageLength, securityTrailer, 0, securityTrailerLength); var buffers = new SecurityBuffer[] { new SecurityBuffer(encryptedBytes, SecurityBufferType.Data), new SecurityBuffer(securityTrailer, SecurityBufferType.Stream) }; var descriptor = new SecurityBufferDescriptor(buffers); bool contextAddRefSuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { try { uint quality; var result = Win32.DecryptMessage( ref _sspiHandle, ref descriptor, 0, out quality); if (result != Win32.SEC_E_OK) { throw Win32.CreateException(result, "Unable to decrypt message."); } decryptedBytes = descriptor.ToByteArray(); } finally { descriptor.Dispose(); } } }