public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode) { if (NetEventSource.IsEnabled) NetEventSource.Enter(null, contextAttribute); int nativeBlockSize = IntPtr.Size; Type handleType = null; switch (contextAttribute) { case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: nativeBlockSize = SecPkgContext_Sizes.SizeOf; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: nativeBlockSize = SecPkgContext_StreamSizes.SizeOf; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: handleType = typeof(SafeFreeContextBuffer); nativeBlockSize = Marshal.SizeOf<SecPkgContext_NegotiationInfoW>(); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: nativeBlockSize = Marshal.SizeOf<Interop.SspiCli.SecPkgContext_IssuerListInfoEx>(); handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: nativeBlockSize = Marshal.SizeOf<SecPkgContext_ConnectionInfo>(); break; default: throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute)); } SafeHandle sspiHandle = null; object attribute = null; try { var nativeBuffer = new byte[nativeBlockSize]; errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle); if (errorCode != 0) { if (NetEventSource.IsEnabled) NetEventSource.Exit(null, $"ERROR = {ErrorDescription(errorCode)}"); return null; } switch (contextAttribute) { case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: attribute = new SecPkgContext_Sizes(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: attribute = new SecPkgContext_StreamSizes(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: attribute = new SecurityPackageInfoClass(sspiHandle, 0); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: unsafe { fixed (void* ptr = nativeBuffer) { attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), SecPkgContext_NegotiationInfoW.NegotiationStateOffest)); } } break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: // Fall-through to RemoteCertificate is intentional. case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: attribute = sspiHandle; sspiHandle = null; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: attribute = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer); sspiHandle = null; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: attribute = new SecPkgContext_ConnectionInfo(nativeBuffer); break; default: // Will return null. break; } } finally { if (sspiHandle != null) { sspiHandle.Dispose(); } } if (NetEventSource.IsEnabled) NetEventSource.Exit(null, attribute); return attribute; }
public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode) { if (NetEventSource.IsEnabled) { NetEventSource.Enter(null, contextAttribute); } int nativeBlockSize = IntPtr.Size; Type handleType = null; switch (contextAttribute) { case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: nativeBlockSize = SecPkgContext_Sizes.SizeOf; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: nativeBlockSize = SecPkgContext_StreamSizes.SizeOf; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: handleType = typeof(SafeFreeContextBuffer); unsafe { nativeBlockSize = sizeof(SecPkgContext_NegotiationInfoW); } break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: nativeBlockSize = Marshal.SizeOf <Interop.SspiCli.SecPkgContext_IssuerListInfoEx>(); handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: nativeBlockSize = Marshal.SizeOf <SecPkgContext_ConnectionInfo>(); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL: nativeBlockSize = Marshal.SizeOf <Interop.SecPkgContext_ApplicationProtocol>(); break; default: throw new ArgumentException(System.StringsHelper.Format(Strings.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute)); } SafeHandle sspiHandle = null; object attribute = null; try { var nativeBuffer = new byte[nativeBlockSize]; errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle); if (errorCode != 0) { if (NetEventSource.IsEnabled) { NetEventSource.Exit(null, $"ERROR = {ErrorDescription(errorCode)}"); } return(null); } switch (contextAttribute) { case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: attribute = new SecPkgContext_Sizes(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: attribute = new SecPkgContext_StreamSizes(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: attribute = new SecurityPackageInfoClass(sspiHandle, 0); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: unsafe { fixed(void *ptr = &nativeBuffer[0]) { attribute = new NegotiationInfoClass(sspiHandle, (int)((SecPkgContext_NegotiationInfoW *)ptr)->NegotiationState); } } break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: // Fall-through to RemoteCertificate is intentional. case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: attribute = sspiHandle; sspiHandle = null; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: attribute = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer); sspiHandle = null; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: attribute = new SecPkgContext_ConnectionInfo(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL: unsafe { fixed(void *ptr = nativeBuffer) { attribute = Marshal.PtrToStructure <Interop.SecPkgContext_ApplicationProtocol>(new IntPtr(ptr)); } } break; default: // Will return null. break; } } finally { if (sspiHandle != null) { sspiHandle.Dispose(); } } if (NetEventSource.IsEnabled) { NetEventSource.Exit(null, attribute); } return(attribute); }
public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode) { if (GlobalLog.IsEnabled) { GlobalLog.Enter(nameof(QueryContextAttributes), contextAttribute.ToString()); } int nativeBlockSize = IntPtr.Size; Type handleType = null; switch (contextAttribute) { case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: nativeBlockSize = SecPkgContext_Sizes.SizeOf; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: nativeBlockSize = SecPkgContext_StreamSizes.SizeOf; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: handleType = typeof(SafeFreeContextBuffer); nativeBlockSize = Marshal.SizeOf <SecPkgContext_NegotiationInfoW>(); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: nativeBlockSize = Marshal.SizeOf <Interop.SspiCli.SecPkgContext_IssuerListInfoEx>(); handleType = typeof(SafeFreeContextBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: nativeBlockSize = Marshal.SizeOf <SecPkgContext_ConnectionInfo>(); break; default: throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute)); } SafeHandle sspiHandle = null; object attribute = null; try { var nativeBuffer = new byte[nativeBlockSize]; errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle); if (errorCode != 0) { if (GlobalLog.IsEnabled) { GlobalLog.Leave("Win32:QueryContextAttributes", "ERROR = " + ErrorDescription(errorCode)); } return(null); } switch (contextAttribute) { case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: attribute = new SecPkgContext_Sizes(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: attribute = new SecPkgContext_StreamSizes(nativeBuffer); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: attribute = new SecurityPackageInfoClass(sspiHandle, 0); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: unsafe { fixed(void *ptr = nativeBuffer) { attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), SecPkgContext_NegotiationInfoW.NegotiationStateOffest)); } } break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: // Fall-through to RemoteCertificate is intentional. case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: attribute = sspiHandle; sspiHandle = null; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: attribute = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer); sspiHandle = null; break; case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: attribute = new SecPkgContext_ConnectionInfo(nativeBuffer); break; default: // Will return null. break; } } finally { if (sspiHandle != null) { sspiHandle.Dispose(); } } if (GlobalLog.IsEnabled) { GlobalLog.Leave(nameof(QueryContextAttributes), LoggingHash.ObjectToString(attribute)); } return(attribute); }
/// <summary> /// Gets SecPkgContext_Sizes via QueryContextAttributes call. /// Throws an exception if the call fails. /// </summary> /// <param name="phContext">Security context.</param> /// <param name="secPkgContext_Sizes">Reference to SecPkgContext_Sizes instance.</param> public static void QueryContextSizes(SecHandle phContext, ref SecPkgContext_Sizes secPkgContext_Sizes) { int result = 0; if (_isNT) result = QueryContextAttributes_NT(phContext, SECPKG_ATTR_SIZES, ref secPkgContext_Sizes); else result = QueryContextAttributes__(phContext, SECPKG_ATTR_SIZES, ref secPkgContext_Sizes); if (result != SspiApi.SEC_E_OK) throw GenuineExceptions.Get_Windows_SspiError(result); }
/// <summary> /// Calls MakeSignature SSPI API function and saves obtained signature to /// outputSignature parameter. /// Throws an exception if the call fails. /// </summary> /// <param name="phContext">Established security context handle.</param> /// <param name="contentBuffer">Content to make signature for.</param> /// <param name="outputSignature">Output stream to write signature to.</param> /// <param name="secPkgContext_Sizes">Security context size constants.</param> public static void MakeSignature(SspiApi.SecHandle phContext, byte[] contentBuffer, BinaryWriter outputSignature, ref SecPkgContext_Sizes secPkgContext_Sizes) { SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative(); SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[2]; byte[] signBuffer = new byte[secPkgContext_Sizes.cbMaxSignature]; using (GCHandleKeeper pinnedSignBuffer = new GCHandleKeeper(signBuffer, GCHandleType.Pinned)) { // the first is for getting a sign secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN; secBuffers[0].cbBuffer = secPkgContext_Sizes.cbMaxSignature; secBuffers[0].pvBuffer = pinnedSignBuffer.GCHandle.AddrOfPinnedObject(); // pin contentBuffer secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA; secBuffers[1].cbBuffer = (int) contentBuffer.Length; using (GCHandleKeeper pinnedContentBuffer = new GCHandleKeeper(contentBuffer, GCHandleType.Pinned)) { secBuffers[1].pvBuffer = pinnedContentBuffer.GCHandle.AddrOfPinnedObject(); // setup descriptor secDesc.ulVersion = SspiApi.SECBUFFER_VERSION; secDesc.cBuffers = 2; using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned)) { secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject(); int result = 0; if (_isNT) result = MakeSignature_NT(phContext, 0, ref secDesc, 0); else result = MakeSignature__(phContext, 0, ref secDesc, 0); if (result != SspiApi.SEC_E_OK) throw GenuineExceptions.Get_Windows_SspiError(result); outputSignature.Write(signBuffer, 0, secBuffers[0].cbBuffer); } // pin sec buffers } // pin the content buffer } // pin the signature buffer }
/// <summary> /// Calls EncryptMessage SSPI API function. /// Throws an exception if the call fails. /// </summary> /// <param name="phContext">Established security context handle.</param> /// <param name="sourceContent">Source data.</param> /// <param name="outputContent">Writer to write encrypted data to.</param> /// <param name="secPkgContext_Sizes">Current package's sizes.</param> public static void EncryptMessage(SspiApi.SecHandle phContext, Stream sourceContent, BinaryWriter outputContent, ref SecPkgContext_Sizes secPkgContext_Sizes) { SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative(); // for token, data and padding SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[3]; byte[] signature = new byte[secPkgContext_Sizes.cbSecurityTrailer]; byte[] message = new byte[(int) sourceContent.Length]; byte[] padding = new byte[secPkgContext_Sizes.cbBlockSize]; GenuineUtility.ReadDataFromStream(sourceContent, message, 0, message.Length); using (GCHandleKeeper pinnedSignature = new GCHandleKeeper(signature, GCHandleType.Pinned)) { // the first is for signature secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN; secBuffers[0].cbBuffer = signature.Length; secBuffers[0].pvBuffer = pinnedSignature.GCHandle.AddrOfPinnedObject(); using (GCHandleKeeper pinnedMessage = new GCHandleKeeper(message, GCHandleType.Pinned)) { // the second contains data secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA; secBuffers[1].cbBuffer = message.Length; secBuffers[1].pvBuffer = pinnedMessage.GCHandle.AddrOfPinnedObject(); using (GCHandleKeeper pinnedPadding = new GCHandleKeeper(padding, GCHandleType.Pinned)) { // the third is for padding secBuffers[2].BufferType = SspiApi.SECBUFFER_PADDING; secBuffers[2].cbBuffer = padding.Length; secBuffers[2].pvBuffer = pinnedPadding.GCHandle.AddrOfPinnedObject(); // setup descriptor secDesc.ulVersion = SspiApi.SECBUFFER_VERSION; secDesc.cBuffers = 3; using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned)) { secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject(); // make the call int result = 0; if (_isNT) result = EncryptMessage_NT(phContext, 0, ref secDesc, 0); else result = EncryptMessage__(phContext, 0, ref secDesc, 0); if (result != SspiApi.SEC_E_OK) throw GenuineExceptions.Get_Windows_SspiError(result); } } } } // write sizes outputContent.Write( (int) secBuffers[0].cbBuffer ); outputContent.Write( (int) secBuffers[1].cbBuffer ); outputContent.Write( (int) secBuffers[2].cbBuffer ); // and content outputContent.Write( signature, 0, secBuffers[0].cbBuffer ); outputContent.Write( message, 0, secBuffers[1].cbBuffer ); outputContent.Write( padding, 0, secBuffers[2].cbBuffer ); }
private static extern int QueryContextAttributes__(SecHandle phContext, int ulAttribute, ref SecPkgContext_Sizes pBuffer);