private void QueryBufferSizes(out SecurityPackageContextSizes sizes) { var contextAddRefSuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { var result = NativeMethods.QueryContextAttributes(ref _handle, QueryContextAttributes.Sizes, out sizes); DangerousRelease(); if (result != NativeMethods.SEC_E_OK) { throw Win32Exception.Create(result, "Unable to get the query context attribute sizes."); } } }
public void DecryptMessage(int messageLength, byte[] encryptedBytes, out byte[] decryptedBytes) { decryptedBytes = null; var encryptedMessage = new byte[messageLength]; Array.Copy(encryptedBytes, 0, encryptedMessage, 0, messageLength); var securityTrailerLength = encryptedBytes.Length - messageLength; var securityTrailer = new byte[securityTrailerLength]; Array.Copy(encryptedBytes, messageLength, securityTrailer, 0, securityTrailerLength); var buffers = new[] { new SecurityBuffer(encryptedBytes, SecurityBufferType.Data), new SecurityBuffer(securityTrailer, SecurityBufferType.Stream) }; var descriptor = new SecurityBufferDescriptor(buffers); var 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 = NativeMethods.DecryptMessage(ref _handle, ref descriptor, 0, out quality); if (result != NativeMethods.SEC_E_OK) { throw Win32Exception.Create(result, "Unable to decrypt message."); } decryptedBytes = descriptor.ToByteArray(); } finally { descriptor.Free(); } } }
public void MakeSignature(byte[] inBytes, out byte[] outBytes) { outBytes = null; var contextAddRefSuccess = false; SecurityPackageContextSizes sizes; QueryBufferSizes(out sizes); var buffers = new[] { 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 { var result = NativeMethods.MakeSignature(ref _handle, MakeSignatureQualityOfProtection.None, ref descriptor, 0); DangerousRelease(); if (result != NativeMethods.SEC_E_OK) { throw Win32Exception.Create(result, "Unable to encrypt message."); } outBytes = descriptor.ToByteArray(); } finally { descriptor.Free(); } } }
public void Acquire() { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { long timestamp; var result = NativeMethods.AcquireCredentialsHandle(null, PackageInfo.Name, CredentialUse, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref _handle, out timestamp); if (result != NativeMethods.SEC_E_OK) { SetHandleAsInvalid(); throw Win32Exception.Create(result, "Unable to acquire credential."); } Expiry = timestamp.ToDateTime(); } }
private void QueryContextString(QueryContextAttributes attribute, out string names) { if (attribute != QueryContextAttributes.Names && attribute != QueryContextAttributes.Authority) { throw new InvalidOperationException("Only names and authorities are strings"); } var contextAddRefSuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { var ptr = new IntPtr(); var result = NativeMethods.QueryContextAttributes(ref _handle, attribute, out ptr); DangerousRelease(); if (result != NativeMethods.SEC_E_OK) { throw Win32Exception.Create(result, "Unable to get the query context attribute names."); } names = Marshal.PtrToStringAuto(ptr); } }
public static IList <SecurityPackageInfo> Enumerate() { var ptr = new IntPtr(); try { var count = 0; var status = NativeMethods.EnumerateSecurityPackages(ref count, ref ptr); if (status != 0) { throw Win32Exception.Create(status, "Failed to get enumerate packages."); } return(ptr.ToEnumerable <SecurityPackageInfo>(count).ToArray()); } finally { if (ptr != IntPtr.Zero) { NativeMethods.FreeContextBuffer(ptr); } } }
public static SecurityPackageInfo Query(string name) { var ptr = IntPtr.Zero; try { var status = NativeMethods.QuerySecurityPackageInfo(name, out ptr); if (status != 0) { throw Win32Exception.Create(status, "Failed to get package \"" + name + "\"."); } var secPkgInfo = ptr.ToStructure <SecurityPackageInfo>(); return(secPkgInfo); } finally { if (ptr != IntPtr.Zero) { NativeMethods.FreeContextBuffer(ptr); } } }
public string GetPrincipalName() { var success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref success); var buffer = new IntPtr(); try { var status = NativeMethods.QueryCredentialsAttributes(ref _handle, QueryCredentialsAttribute.Names, out buffer); if (status != 0) { throw Win32Exception.Create(status, "Failed to query principal name"); } return(buffer == IntPtr.Zero ? string.Empty : Marshal.PtrToStringUni(buffer)); } finally { if (buffer != IntPtr.Zero) { NativeMethods.FreeContextBuffer(buffer); } } } finally { if (success) { DangerousRelease(); } } }
public void AcceptToken(byte[] inBytes, out byte[] outBytes) { outBytes = null; var outputBuffer = new SecurityBufferDescriptor((int)_credential.PackageInfo.MaxTokenSize); var credentialAddRefSuccess = false; var contextAddRefSuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { _credential.DangerousAddRef(ref credentialAddRefSuccess); DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (credentialAddRefSuccess) { _credential.DangerousRelease(); credentialAddRefSuccess = false; } if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { try { var flags = SspiContextFlags.MutualAuth; var clientToken = new SecurityBufferDescriptor(inBytes); uint result; long timestamp; var credentialHandle = _credential.Handle; if (_handle.IsZero) { result = NativeMethods.AcceptSecurityContext( ref credentialHandle, IntPtr.Zero, ref clientToken, flags, DataRepresentation.Network, ref _handle, ref outputBuffer, out flags, out timestamp); } else { try { result = NativeMethods.AcceptSecurityContext( ref credentialHandle, ref _handle, ref clientToken, flags, DataRepresentation.Network, ref _handle, ref outputBuffer, out flags, out timestamp); } finally { clientToken.Free(); } } _credential.DangerousRelease(); DangerousRelease(); if (result != NativeMethods.SEC_E_OK && result != NativeMethods.SEC_I_CONTINUE_NEEDED) { throw Win32Exception.Create(result, "Unable to initialize security context."); } outBytes = outputBuffer.ToByteArray(); IsInitialized = result == NativeMethods.SEC_E_OK; } finally { outputBuffer.Free(); } } }
public void Initialize(string servicePrincipalName, byte[] inBytes, out byte[] outBytes) { outBytes = null; var outputBuffer = new SecurityBufferDescriptor((int)_credential.PackageInfo.MaxTokenSize); var credentialAddRefSuccess = false; var contextAddRefSuccess = false; RuntimeHelpers.PrepareConstrainedRegions(); try { _credential.DangerousAddRef(ref credentialAddRefSuccess); DangerousAddRef(ref contextAddRefSuccess); } catch (Exception ex) { if (credentialAddRefSuccess) { _credential.DangerousRelease(); credentialAddRefSuccess = false; } if (contextAddRefSuccess) { DangerousRelease(); contextAddRefSuccess = false; } if (!(ex is ObjectDisposedException)) { throw; } } finally { try { uint result; long timestamp; var credentialHandle = _credential.Handle; if (inBytes == null || inBytes.Length == 0) { result = NativeMethods.InitializeSecurityContext( ref credentialHandle, IntPtr.Zero, servicePrincipalName, _requestedContextFlags, 0, DataRepresentation.Network, IntPtr.Zero, 0, ref _handle, ref outputBuffer, out _receivedContextFlags, out timestamp); } else { var serverToken = new SecurityBufferDescriptor(inBytes); try { result = NativeMethods.InitializeSecurityContext( ref credentialHandle, ref _handle, servicePrincipalName, _requestedContextFlags, 0, DataRepresentation.Network, ref serverToken, 0, ref _handle, ref outputBuffer, out _receivedContextFlags, out timestamp); } finally { serverToken.Free(); } } _credential.DangerousRelease(); DangerousRelease(); if (result != NativeMethods.SEC_E_OK && result != NativeMethods.SEC_I_CONTINUE_NEEDED) { throw Win32Exception.Create(result, "Unable to initialize security context."); } outBytes = outputBuffer.ToByteArray(); IsInitialized = result == NativeMethods.SEC_E_OK; } finally { outputBuffer.Free(); } } }
public void VerifySignature(byte[] inBytes, out byte[] outBytes) { bool contextAddRefSuccess = false; SecurityPackageContextSizes sizes; QueryBufferSizes(out sizes); var buffers = new[] { 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 { var status = NativeMethods.VerifySignature(ref _handle, ref descriptor, 0, MakeSignatureQualityOfProtection.None); DangerousRelease(); switch ((long)status) { case NativeMethods.SEC_E_OK: outBytes = descriptor.ToByteArray(); break; case NativeMethods.SEC_E_OUT_OF_SEQUENCE: case NativeMethods.SEC_E_MESSAGE_ALTERED: outBytes = null; break; default: throw Win32Exception.Create(status, "Unable to encrypt message."); } } finally { descriptor.Free(); } } }