public static unsafe object QueryContextAttributes( SafeDeleteContext securityContext, ContextAttribute contextAttribute) { int nativeBlockSize = IntPtr.Size; Type handleType = null; switch (contextAttribute) { case ContextAttribute.Flags: break; case ContextAttribute.Sizes: nativeBlockSize = SecSizes.SizeOf; break; case ContextAttribute.StreamSizes: nativeBlockSize = StreamSizes.SizeOf; break; case ContextAttribute.Names: handleType = typeof(SafeFreeContextBuffer); break; case ContextAttribute.PackageInfo: handleType = typeof(SafeFreeContextBuffer); break; case ContextAttribute.NegotiationInfo: handleType = typeof(SafeFreeContextBuffer); nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo)); break; case ContextAttribute.RemoteCertificate: handleType = typeof(SafeFreeCertContext); break; case ContextAttribute.LocalCertificate: handleType = typeof(SafeFreeCertContext); break; case ContextAttribute.ConnectionInfo: nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo)); break; case ContextAttribute.Lifespan: nativeBlockSize = LifeSpan_Struct.Size; break; case ContextAttribute.SessionKey: handleType = typeof(SafeFreeContextBuffer); nativeBlockSize = SecPkgContext_SessionKey.Size; break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int)contextAttribute, typeof(ContextAttribute))); } SafeHandle sspiHandle = null; object attribute = null; try { byte[] nativeBuffer = new byte[nativeBlockSize]; int errorCode = QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } switch (contextAttribute) { case ContextAttribute.Flags: fixed (byte* pnativeBuffer = nativeBuffer) { attribute = (object)Marshal.ReadInt32(new IntPtr(pnativeBuffer)); } break; case ContextAttribute.Sizes: attribute = new SecSizes(nativeBuffer); break; case ContextAttribute.StreamSizes: attribute = new StreamSizes(nativeBuffer); break; case ContextAttribute.Names: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; case ContextAttribute.PackageInfo: attribute = new SecurityPackageInfoClass(sspiHandle, 0); break; case ContextAttribute.NegotiationInfo: unsafe { fixed (void* ptr = nativeBuffer) { attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffset)); } } break; case ContextAttribute.LocalCertificate: goto case ContextAttribute.RemoteCertificate; case ContextAttribute.RemoteCertificate: attribute = sspiHandle; sspiHandle = null; break; case ContextAttribute.ConnectionInfo: attribute = new SslConnectionInfo(nativeBuffer); break; case ContextAttribute.Lifespan: attribute = new LifeSpan(nativeBuffer); break; case ContextAttribute.SessionKey: unsafe { fixed (void* ptr = nativeBuffer) { attribute = new SecuritySessionKeyClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr))); } } break; default: // will return null break; } } finally { if (sspiHandle != null) { sspiHandle.Close(); } } return attribute; }
static SecurityPackageInfoClass[] EnumerateSecurityPackages() { if (SecurityPackages != null) { return SecurityPackages; } int moduleCount = 0; SafeFreeContextBuffer arrayBaseHandle = null; try { int errorCode = SafeFreeContextBuffer.EnumeratePackages(out moduleCount, out arrayBaseHandle); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } SecurityPackageInfoClass[] securityPackages = new SecurityPackageInfoClass[moduleCount]; for (int i = 0; i < moduleCount; i++) { securityPackages[i] = new SecurityPackageInfoClass(arrayBaseHandle, i); } SecurityPackages = securityPackages; } finally { if (arrayBaseHandle != null) { arrayBaseHandle.Close(); } } return SecurityPackages; }