using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.Crypt32;
using static Vanara.PInvoke.Schannel;
using TimeStamp = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// Functions and definitions from Secur32.dll
public static partial class Secur32
{
/// Undocumented.
/// Argument passed in
/// Principal ID
/// Key Version
/// Returned ptr to key.
/// returned status.
[PInvokeData("sspi.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void SEC_GET_KEY_FN(IntPtr Arg, IntPtr Principal, uint KeyVer, out IntPtr Key, out int Status);
/// Bit flags that specify the attributes required by the server to establish the context.
[PInvokeData("sspi.h", MSDNShortId = "a53f733e-b646-4431-b021-a2c446308849")]
[Flags]
public enum ASC_REQ : uint
{
/// The server is allowed to impersonate the client. Ignore this flag for constrained delegation.
ASC_REQ_DELEGATE = 0x00000001,
/// The mutual authentication policy of the service will be satisfied.
ASC_REQ_MUTUAL_AUTH = 0x00000002,
/// Detect replayed packets.
ASC_REQ_REPLAY_DETECT = 0x00000004,
/// Detect messages received out of sequence.
ASC_REQ_SEQUENCE_DETECT = 0x00000008,
/// Encrypt messages by using the EncryptMessage function.
ASC_REQ_CONFIDENTIALITY = 0x00000010,
/// A new session key must be negotiated. This value is supported only by the Kerberos security package.
ASC_REQ_USE_SESSION_KEY = 0x00000020,
///
ASC_REQ_SESSION_TICKET = 0x00000040,
///
/// Credential Security Support Provider (CredSSP) will allocate output buffers. When you have finished using the output buffers,
/// free them by calling the FreeContextBuffer function.
///
ASC_REQ_ALLOCATE_MEMORY = 0x00000100,
///
ASC_REQ_USE_DCE_STYLE = 0x00000200,
///
ASC_REQ_DATAGRAM = 0x00000400,
/// The security context will not handle formatting messages.
ASC_REQ_CONNECTION = 0x00000800,
///
ASC_REQ_CALL_LEVEL = 0x00001000,
///
ASC_REQ_FRAGMENT_SUPPLIED = 0x00002000,
/// When errors occur, the remote party will be notified.
ASC_REQ_EXTENDED_ERROR = 0x00008000,
/// Support a stream-oriented connection.
ASC_REQ_STREAM = 0x00010000,
/// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions.
ASC_REQ_INTEGRITY = 0x00020000,
///
ASC_REQ_LICENSING = 0x00040000,
///
ASC_REQ_IDENTIFY = 0x00080000,
///
ASC_REQ_ALLOW_NULL_SESSION = 0x00100000,
///
ASC_REQ_ALLOW_NON_USER_LOGONS = 0x00200000,
///
ASC_REQ_ALLOW_CONTEXT_REPLAY = 0x00400000,
///
ASC_REQ_FRAGMENT_TO_FIT = 0x00800000,
///
ASC_REQ_NO_TOKEN = 0x01000000,
///
ASC_REQ_PROXY_BINDINGS = 0x04000000,
///
ASC_REQ_ALLOW_MISSING_BINDINGS = 0x10000000,
}
/// A set of bit flags that indicate the attributes of the established context.
[PInvokeData("sspi.h", MSDNShortId = "a53f733e-b646-4431-b021-a2c446308849")]
[Flags]
public enum ASC_RET : uint
{
///
/// The server in the transport application can build new security contexts impersonating the client that will be accepted by
/// other servers as the client's contexts. Delegate works only if MUTUAL_AUTH is set. DELEGATE is currently supported only by
/// Kerberos. Further, Kerberos will delegate only to a server that has the flag TRUSTED_FOR_DELEGATION. Do not use this flag for
/// constrained delegation.
///
ASC_RET_DELEGATE = 0x00000001,
///
/// The communicating parties must authenticate their identities to each other. Without MUTUAL_AUTH, the client authenticates its
/// identity to the server. With MUTUAL_AUTH, the server also must authenticate its identity to the client.
///
/// When using the Schannel security package, the server sets the ASC_RET_MUTUAL_AUTH constant only in the last call to
/// AcceptSecurityContext(Negotiate), after certificate mapping has successfully completed.
///
///
ASC_RET_MUTUAL_AUTH = 0x00000002,
///
/// The security package detects replayed packets and notifies the caller if a packet has been replayed. The use of this flag
/// implies all of the conditions specified by the INTEGRITY flag.
///
ASC_RET_REPLAY_DETECT = 0x00000004,
///
/// The context must be allowed to detect out-of-order delivery of packets later through the message support functions. Use of
/// this flag implies all of the conditions specified by the INTEGRITY flag.
///
ASC_RET_SEQUENCE_DETECT = 0x00000008,
///
/// The context can protect data while in transit using the EncryptMessage (General) and DecryptMessage (General) functions. The
/// CONFIDENTIALITY flag does not work if the generated context is for the Guest account.
///
ASC_RET_CONFIDENTIALITY = 0x00000010,
/// A new session key must be negotiated.
ASC_RET_USE_SESSION_KEY = 0x00000020,
///
ASC_RET_SESSION_TICKET = 0x00000040,
///
/// The security package must allocate memory. The caller must eventually call the FreeContextBuffer function to free memory
/// allocated by the security package.
///
ASC_RET_ALLOCATED_MEMORY = 0x00000100,
/// The caller expects a three-leg authentication transaction.
ASC_RET_USED_DCE_STYLE = 0x00000200,
/// Datagram semantics must be used. For more information, see Datagram Contexts.
ASC_RET_DATAGRAM = 0x00000400,
/// Connection semantics must be used. For more information, see Connection-Oriented Contexts.
ASC_RET_CONNECTION = 0x00000800,
///
ASC_RET_CALL_LEVEL = 0x00002000,
///
ASC_RET_THIRD_LEG_FAILED = 0x00004000,
/// Error reply messages for the peer must be generated if the context fails.
ASC_RET_EXTENDED_ERROR = 0x00008000,
/// Stream semantics must be used. For more information, see Stream Contexts.
ASC_RET_STREAM = 0x00010000,
/// Buffer integrity can be verified but no sequencing or reply detection is enabled.
ASC_RET_INTEGRITY = 0x00020000,
///
ASC_RET_LICENSING = 0x00040000,
///
/// When a server impersonates a context that has this flag set, that impersonation yields extremely limited access.
/// Impersonation with IDENTIFY set is used to verify the client's identity.
///
ASC_RET_IDENTIFY = 0x00080000,
///
ASC_RET_NULL_SESSION = 0x00100000,
///
ASC_RET_ALLOW_NON_USER_LOGONS = 0x00200000,
///
ASC_RET_ALLOW_CONTEXT_REPLAY = 0x00400000,
///
ASC_RET_FRAGMENT_ONLY = 0x00800000,
///
ASC_RET_NO_TOKEN = 0x01000000,
///
ASC_RET_NO_ADDITIONAL_TOKEN = 0x02000000,
}
/// The data representation, such as byte ordering, on the target.
[PInvokeData("sspi.h", MSDNShortId = "a53f733e-b646-4431-b021-a2c446308849")]
[Flags]
public enum DREP
{
///
SECURITY_NATIVE_DREP = 0x00000010,
///
SECURITY_NETWORK_DREP = 0x00000000
}
/// Property to return from the SASL context.
[PInvokeData("sspi.h", MSDNShortId = "c9c424d3-07e6-4ed0-9189-c932af0475d9")]
public enum SASL_OPTION
{
///
/// Data type of buffer: ULONG
///
/// State of SASL processing of the Authz value provided by the SASL application. The valid states for processing are
/// Sasl_AuthZIDForbidden and Sasl_AuthZIDProcessed.
///
///
SASL_OPTION_AUTHZ_PROCESSING = 4,
///
/// Data type of buffer: Array of binary characters
///
/// String of characters passed from the SASL client to the server. If the AuthZ_Processing state is Sasl_AuthZIDForbidden, the
/// return value SEC_E_UNSUPPORTED_FUNCTION is returned.
///
///
SASL_OPTION_AUTHZ_STRING = 3,
///
/// Data type of buffer: ULONG
/// Maximum size of the receiving buffer on the local computer.
///
SASL_OPTION_RECV_SIZE = 2,
///
/// Data type of buffer: ULONG
///
/// Maximum message data size that can be transmitted. This value is the maximum buffer size that can be transmitted to the
/// remote SASL process minus the block size, the trailer size, and the maximum signature size.
///
///
SASL_OPTION_SEND_SIZE = 1,
}
/// En/Decryption options.
[PInvokeData("sspi.h", MSDNShortId = "86598BAA-0E87-46A9-AA1A-BF04BF0CDAFA")]
public enum SEC_WINNT_AUTH_IDENTITY_ENCRYPT
{
///
/// The encrypted structure can only be decrypted by a security context in the same logon session. This option is used to protect
/// an identity buffer that is being sent over a local RPC.
///
SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON = 0x1,
///
/// The encrypted structure can only be decrypted by the same process. Calling the function with this option is equivalent to
/// calling SspiEncryptAuthIdentity. This option is used to protect an identity buffer that is being persisted in a process's
/// private memory for an extended period.
///
SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_PROCESS = 0x2
}
/// The type used by negotiable security packages.
[PInvokeData("sspi.h", MSDNShortId = "a6083d76-1774-428c-85ca-fea817827d6a")]
[Flags]
public enum SEC_WINNT_AUTH_IDENTITY_FLAGS
{
/// Credentials are in ANSI form.
SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1,
/// Credentials are in Unicode form.
SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2,
/// All data is in one buffer.
SEC_WINNT_AUTH_IDENTITY_MARSHALLED = 0x4,
///
/// Used with the Kerberos security support provider (SSP). Credentials are for identity only. The Kerberos package is directed
/// to not include authorization data in the ticket.
///
SEC_WINNT_AUTH_IDENTITY_ONLY = 0x8,
///
/// The structure is encrypted by the SspiEncryptAuthIdentity function or by the SspiEncryptAuthIdentityEx function with the
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_PROCESS option. It can only be decrypted by the same process.
/// Windows Server 2008 R2 and Windows 7: This flag is not supported.
///
SEC_WINNT_AUTH_IDENTITY_FLAGS_PROCESS_ENCRYPTED = 0x10,
///
/// The structure is encrypted by the SspiEncryptAuthIdentityEx function with the SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON
/// option under the SYSTEM security context. It can only be decrypted by a thread running as SYSTEM.
/// Windows Server 2008 R2 and Windows 7: This flag is not supported.
///
SEC_WINNT_AUTH_IDENTITY_FLAGS_SYSTEM_PROTECTED = 0x20,
///
/// The structure is encrypted by the SspiEncryptAuthIdentityEx function with the SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON
/// option under a non-SYSTEM security context. It can only be decrypted by a thread running in the same logon session in which
/// it was encrypted.
/// Windows Server 2008 R2 and Windows 7: This flag is not supported.
///
SEC_WINNT_AUTH_IDENTITY_FLAGS_USER_PROTECTED = 0x40,
///
/// The authentication identity buffer is cbStructureLength + 8 padding bytes that are necessary for in-place encryption or
/// decryption of the identity.
///
/// The authentication identity buffer is cbStructureLength + 8 padding bytes that are necessary for in-place encryption or
/// decryption of the identity.
///
///
SEC_WINNT_AUTH_IDENTITY_FLAGS_RESERVED = 0x10000,
/// Undocumented.
SEC_WINNT_AUTH_IDENTITY_FLAGS_NULL_USER = 0x20000,
/// Undocumented.
SEC_WINNT_AUTH_IDENTITY_FLAGS_NULL_DOMAIN = 0x40000,
///
/// When the credential type is password, the presence of this flag specifies that the structure is an online ID credential. The
/// DomainOffset and DomainLength members correspond to the online ID provider name.
/// Windows Server 2008 R2 and Windows 7: This flag is not supported.
///
SEC_WINNT_AUTH_IDENTITY_FLAGS_ID_PROVIDER = 0x80000,
}
///
[Flags]
public enum SecBufferType : uint
{
/// The buffer contains an alert message.
SECBUFFER_ALERT = 0x11,
/// The buffer contains a bitmask for a SECBUFFER_READONLY_WITH_CHECKSUM buffer.
SECBUFFER_ATTRMASK = 0xF0000000,
/// The buffer contains channel binding information.
SECBUFFER_CHANNEL_BINDINGS = 0xE,
/// The buffer contains a DOMAIN_PASSWORD_INFORMATION structure.
//[CorrespondingType(typeof(DOMAIN_PASSWORD_INFORMATION))]
SECBUFFER_CHANGE_PASS_RESPONSE = 0xF,
///
/// The buffer contains common data. The security package can read and write this data, for example, to encrypt some or all of it.
///
SECBUFFER_DATA = 0x1,
///
/// The buffer contains the setting for the maximum transmission unit (MTU) size for DTLS only. The default value is 1096 and the
/// valid configurable range is between 200 and 64*1024.
///
SECBUFFER_DTLS_MTU = 0x18,
///
/// This is a placeholder in the buffer array. The caller can supply several such entries in the array, and the security package
/// can return information in them. For more information, see SSPI Context Semantics.
///
SECBUFFER_EMPTY = 0x0,
/// The security package uses this value to indicate the number of extra or unprocessed bytes in a message.
SECBUFFER_EXTRA = 0x5,
///
/// The buffer contains a protocol-specific list of object identifiers (OIDs). It is not usually of interest to callers.
///
SECBUFFER_MECHLIST = 0xB,
/// The buffer contains a signature of a SECBUFFER_MECHLIST buffer. It is not usually of interest to callers.
SECBUFFER_MECHLIST_SIGNATURE = 0xC,
///
/// The security package uses this value to indicate the number of missing bytes in a particular message. The pvBuffer member is
/// ignored in this type.
///
SECBUFFER_MISSING = 0x4,
///
/// These are transport-to-package–specific parameters. For example, the NetWare redirector may supply the server object
/// identifier, while DCE RPC can supply an association UUID, and so on.
///
SECBUFFER_PKG_PARAMS = 0x3,
/// The buffer contains the preshared key. The maximum allowed PSK buffer size is 256 bytes.
SECBUFFER_PRESHARED_KEY = 0x16,
/// The buffer contains the preshared key identity.
SECBUFFER_PRESHARED_KEY_IDENTITY = 0x17,
/// The buffer contains the SRTP master key identifier.
SECBUFFER_SRTP_MASTER_KEY_IDENTIFIER = 0x14,
/// The buffer contains the list of SRTP protection profiles, in descending order of preference.
SECBUFFER_SRTP_PROTECTION_PROFILES = 0x13,
/// The buffer contains a protocol-specific header for a particular record. It is not usually of interest to callers.
SECBUFFER_STREAM_HEADER = 0x7,
/// The buffer contains a protocol-specific trailer for a particular record. It is not usually of interest to callers.
SECBUFFER_STREAM_TRAILER = 0x6,
/// This flag is reserved. Do not use it.
SECBUFFER_TARGET = 0xD,
///
/// The buffer specifies the service principal name (SPN) of the target.
/// This value is supported by the Digest security package when used with channel bindings.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
SECBUFFER_TARGET_HOST = 0x10,
///
/// The buffer contains the security token portion of the message. This is read-only for input parameters or read/write for
/// output parameters.
///
SECBUFFER_TOKEN = 0x2,
///
/// The buffer contains the supported token binding protocol version and key parameters, in descending order of preference.
///
SECBUFFER_TOKEN_BINDING = 0x15,
///
/// The buffer contains a list of application protocol IDs, one list per application protocol negotiation extension type to be enabled.
///
SECBUFFER_APPLICATION_PROTOCOLS = 18,
/// Undocumented.
SECBUFFER_NEGOTIATION_INFO = 8,
/// Undocumented.
SECBUFFER_PADDING = 9,
///
/// The buffer is read-only with no checksum. This flag is intended for sending header information to the security package for
/// computing the checksum. The package can read this buffer, but cannot modify it.
///
SECBUFFER_READONLY = 0x80000000,
/// The buffer is read-only with a checksum.
SECBUFFER_READONLY_WITH_CHECKSUM = 0x10000000,
/// Undocumented.
SECBUFFER_RESERVED = 0x60000000,
/// Undocumented.
SECBUFFER_STREAM = 10,
}
/// Specifies the attribute of the context to be returned.
[PInvokeData("sspi.h", MSDNShortId = "FD91EE99-F94E-44CE-9331-933D0CAA5F75")]
public enum SECPKG_ATTR : uint
{
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure.
/// Returns a handle to the access token.
///
[CorrespondingType(typeof(SecPkgContext_AccessToken), CorrespondingAction.Get)]
SECPKG_ATTR_ACCESS_TOKEN = 18,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionAppData structure.
/// Returns or specifies application data for the session.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_SessionAppData), CorrespondingAction.GetSet)]
SECPKG_ATTR_APP_DATA = 0x5e,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Authority structure.
/// Queries the name of the authenticating authority.
///
[CorrespondingType(typeof(SecPkgContext_Authority), CorrespondingAction.Get)]
SECPKG_ATTR_AUTHORITY = 6,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientSpecifiedTarget structure that represents the service
/// principal name (SPN) of the initial target supplied by the client.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
[CorrespondingType(typeof(SecPkgContext_ClientSpecifiedTarget), CorrespondingAction.Get)]
SECPKG_ATTR_CLIENT_SPECIFIED_TARGET = 27,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ConnectionInfo structure.
/// Returns detailed information on the established connection.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_ConnectionInfo), CorrespondingAction.Get)]
SECPKG_ATTR_CONNECTION_INFO = 0x5a,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials.
/// If the client credential is user name and password, the buffer is a packed KERB_INTERACTIVE_LOGON structure.
/// If the client credential is user name and smart card PIN, the buffer is a packed KERB_CERTIFICATE_LOGON structure.
/// If the client credential is an online identity credential, the buffer is a marshaled SEC_WINNT_AUTH_IDENTITY_EX2 structure.
/// This attribute is supported only on the CredSSP server.
///
/// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
///
[CorrespondingType(typeof(SecPkgContext_ClientCreds), CorrespondingAction.Get)]
SECPKG_ATTR_CREDS_2 = 0x80000086,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_DceInfo structure.
/// Queries for authorization data used by DCE services.
///
[CorrespondingType(typeof(SecPkgContext_DceInfo), CorrespondingAction.Get)]
SECPKG_ATTR_DCE_INFO = 3,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Bindings structure that specifies channel binding information.
/// This attribute is supported only by the Schannel security package.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
[CorrespondingType(typeof(SecPkgContext_Bindings), CorrespondingAction.Get)]
SECPKG_ATTR_ENDPOINT_BINDINGS = 26,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_EapKeyBlock structure.
/// Queries for key data used by the EAP TLS protocol.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_EapKeyBlock), CorrespondingAction.Get)]
SECPKG_ATTR_EAP_KEY_BLOCK = 0x5b,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Flags structure.
/// Returns information about the negotiated context flags.
///
[CorrespondingType(typeof(SecPkgContext_Flags), CorrespondingAction.Get)]
SECPKG_ATTR_FLAGS = 14,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_IssuerListInfoEx structure.
/// Returns a list of certificate issuers that are accepted by the server.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_IssuerListInfoEx), CorrespondingAction.Get)]
SECPKG_ATTR_ISSUER_LIST_EX = 0x59,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_KeyInfo structure.
/// Queries information about the keys used in a security context.
///
[CorrespondingType(typeof(SecPkgContext_KeyInfo), CorrespondingAction.Get)]
SECPKG_ATTR_KEY_INFO = 5,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_LastClientTokenStatus structure that specifies whether the token
/// from the most recent call to the InitializeSecurityContext function is the last token from the client.
/// This value is supported only by the Negotiate, Kerberos, and NTLM security packages.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
[CorrespondingType(typeof(SecPkgContext_LastClientTokenStatus), CorrespondingAction.Get)]
SECPKG_ATTR_LAST_CLIENT_TOKEN_STATUS = 30,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Lifespan structure.
/// Queries the life span of the context.
///
[CorrespondingType(typeof(SecPkgContext_Lifespan), CorrespondingAction.Get)]
SECPKG_ATTR_LIFESPAN = 2,
///
/// The pBuffer parameter contains a pointer to a PCCERT_CONTEXTstructure.
/// Finds a certificate context that contains a local end certificate.
/// This attribute is supported only by the Schannel security package.
///
SECPKG_ATTR_LOCAL_CERT_CONTEXT = 0x54,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Names structure.
/// Queries the name associated with the context.
///
[CorrespondingType(typeof(SecPkgContext_Names), CorrespondingAction.Get)]
SECPKG_ATTR_NAMES = 1,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_NativeNames structure.
/// Returns the principal name (CNAME) from the outbound ticket.
///
[CorrespondingType(typeof(SecPkgContext_NativeNames), CorrespondingAction.Get)]
SECPKG_ATTR_NATIVE_NAMES = 13,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_NegotiationInfo structure.
///
/// Returns information about the security package to be used with the negotiation process and the current state of the
/// negotiation for the use of that package.
///
///
[CorrespondingType(typeof(SecPkgContext_NegotiationInfo), CorrespondingAction.Get)]
SECPKG_ATTR_NEGOTIATION_INFO = 12,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfostructure.
/// Returns information on the SSP in use.
///
[CorrespondingType(typeof(SecPkgContext_PackageInfo), CorrespondingAction.Get)]
SECPKG_ATTR_PACKAGE_INFO = 10,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_PasswordExpiry structure.
/// Returns password expiration information.
///
[CorrespondingType(typeof(SecPkgContext_PasswordExpiry), CorrespondingAction.Get)]
SECPKG_ATTR_PASSWORD_EXPIRY = 8,
///
/// The pBuffer parameter contains a pointer to a PCCERT_CONTEXTstructure.
/// Finds a certificate context that contains the end certificate supplied by the server.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(CERT_CONTEXT), CorrespondingAction.Get)]
SECPKG_ATTR_REMOTE_CERT_CONTEXT = 0x53,
///
/// The pBuffer parameter contains a pointer to a HCERTCONTEXT. Finds a certificate context that contains a certificate supplied
/// by the Root store.
///
SECPKG_ATTR_ROOT_STORE = 0x55,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionKey structure.
/// Returns information about the session keys.
///
[CorrespondingType(typeof(SecPkgContext_SessionKey), CorrespondingAction.Get)]
SECPKG_ATTR_SESSION_KEY = 9,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionInfo structure.
/// Returns information about the session.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_SessionInfo), CorrespondingAction.Get)]
SECPKG_ATTR_SESSION_INFO = 0x5d,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Sizes structure.
/// Queries the sizes of the structures used in the per-message functions.
///
[CorrespondingType(typeof(SecPkgContext_Sizes))]
SECPKG_ATTR_SIZES = 0,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_StreamSizes structure.
/// Queries the sizes of the various parts of a stream used in the per-message functions.
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_StreamSizes), CorrespondingAction.Get)]
SECPKG_ATTR_STREAM_SIZES = 4,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SubjectAttributes structure.
/// This value returns information about the security attributes for the connection.
/// This value is supported only on the CredSSP server.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
[CorrespondingType(typeof(SecPkgContext_SubjectAttributes), CorrespondingAction.Get)]
SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES = 124,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SupportedSignatures structure.
/// This value returns information about the signature types that are supported for the connection.
/// This value is supported only by the Schannel security package.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
[CorrespondingType(typeof(SecPkgContext_SupportedSignatures), CorrespondingAction.Get)]
SECPKG_ATTR_SUPPORTED_SIGNATURES = 0x66,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_TargetInformation structure.
/// Returns information about the name of the remote server.
///
[CorrespondingType(typeof(SecPkgContext_TargetInformation), CorrespondingAction.Get)]
SECPKG_ATTR_TARGET_INFORMATION = 17,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Bindings structure that specifies channel binding information.
/// This value is supported only by the Schannel security package.
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
[CorrespondingType(typeof(SecPkgContext_Bindings), CorrespondingAction.Get)]
SECPKG_ATTR_UNIQUE_BINDINGS = 25,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure that specifies the access token for the
/// current security context.
/// This attribute is supported only on the server.
///
[CorrespondingType(typeof(SecPkgContext_AccessToken), CorrespondingAction.Get)]
SECPKG_ATTR_C_ACCESS_TOKEN = 0x80000012,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure that specifies the access token for the
/// current security context.
/// This attribute is supported only on the server.
///
[CorrespondingType(typeof(SecPkgContext_AccessToken), CorrespondingAction.Get)]
SECPKG_ATTR_C_FULL_ACCESS_TOKEN = 0x80000082,
///
/// The pBuffer parameter contains a pointer to a CERT_TRUST_STATUS structure that specifies trust information about the certificate.
/// This attribute is supported only on the client.
///
[CorrespondingType(typeof(CERT_TRUST_STATUS), CorrespondingAction.Get)]
SECPKG_ATTR_CERT_TRUST_STATUS = 0x80000084,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials.
/// The client credentials can be either user name and password or user name and smart card PIN.
/// This attribute is supported only on the server.
///
[CorrespondingType(typeof(SecPkgContext_ClientCreds), CorrespondingAction.Get)]
SECPKG_ATTR_CREDS = 0x80000080,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfo structure that specifies the name of the
/// authentication package negotiated by the Microsoft Negotiate provider.
///
[CorrespondingType(typeof(SecPkgContext_PackageInfo), CorrespondingAction.Get)]
SECPKG_ATTR_NEGOTIATION_PACKAGE = 0x80000081,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Flags structure that specifies information about the flags in the
/// current security context.
/// This attribute is supported only on the client.
///
[CorrespondingType(typeof(SecPkgContext_Flags), CorrespondingAction.Get)]
SECPKG_ATTR_SERVER_AUTH_FLAGS = 0x80000083,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_EapPrfInfo structure.
///
/// Sets the pseudo-random function (PRF) used by the Extensible Authentication Protocol (EAP). This is the value that is
/// returned by a call to the QueryContextAttributes (Schannel) function when SECPKG_ATTR_EAP_KEY_BLOCK is passed as the value of
/// the ulAttribute parameter.
///
/// This attribute is supported only by the Schannel security package.
///
[CorrespondingType(typeof(SecPkgContext_EapPrfInfo), CorrespondingAction.Set)]
SECPKG_ATTR_EAP_PRF_INFO = 101,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_EarlyStart structure.
/// Sets the False Start feature. See the Building a faster and more secure web blog post for information on this feature.
///
[CorrespondingType(typeof(SecPkgContext_EarlyStart), CorrespondingAction.Set)]
SECPKG_ATTR_EARLY_START = 105,
///
/// Sets and retrieves the MTU (maximum transmission unit) value for use with DTLS. If DTLS is not enabled in a security context,
/// this attribute is not supported.
/// Valid values are between 200 bytes and 64 kilobytes. The default DTLS MTU value in Schannel is 1096 bytes.
///
[CorrespondingType(typeof(ushort), CorrespondingAction.Set)]
SECPKG_ATTR_DTLS_MTU = 34,
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_KeyingMaterialInfo structure. The keying material export feature
/// follows the RFC 5705 standard.
/// This attribute is supported only by the Schannel security package in Windows 10 and Windows Server 2016 or later versions.
///
[CorrespondingType(typeof(SecPkgContext_KeyingMaterialInfo), CorrespondingAction.Set)]
SECPKG_ATTR_KEYING_MATERIAL_INFO = 106,
}
///
///
/// Indicates whether the token from the most recent call to the InitializeSecurityContext function is the last token from the client.
///
/// This enumeration is used in the SecPkgContext_LastClientTokenStatus structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ne-sspi-secpkg_attr_lct_status typedef enum _SECPKG_ATTR_LCT_STATUS {
// SecPkgAttrLastClientTokenYes, SecPkgAttrLastClientTokenNo, SecPkgAttrLastClientTokenMaybe } SECPKG_ATTR_LCT_STATUS, *PSECPKG_ATTR_LCT_STATUS;
[PInvokeData("sspi.h", MSDNShortId = "b9067862-2339-4543-a8cd-610e6f921bfd")]
public enum SECPKG_ATTR_LCT_STATUS
{
/// The token is the last token from the client.
SecPkgAttrLastClientTokenYes,
/// The token is not the last token from the client.
SecPkgAttrLastClientTokenNo,
/// It is not known whether the token is the last token from the client.
SecPkgAttrLastClientTokenMaybe,
}
/// Bit flags that describe the capabilities of the security package.
[PInvokeData("sspi.h", MSDNShortId = "d0bff3d8-63f1-4a4e-851f-177040af6bd2")]
[Flags]
public enum SECPKG_CALLFLAGS
{
/// The caller is an app container.
SECPKG_CALLFLAGS_APPCONTAINER = 0x00000001,
/// The caller can use default credentials.
SECPKG_CALLFLAGS_AUTHCAPABLE = 0x00000002,
/// The caller can only use supplied credentials.
SECPKG_CALLFLAGS_FORCE_SUPPLIED = 0x00000004,
///
SECPKG_CALLFLAGS_APPCONTAINER_UPNCAPABLE = 0x00000008,
}
/// Flags for ExportSecurityContext.
[PInvokeData("sspi.h", MSDNShortId = "4ebc7f37-b948-4c78-973f-0a74e55c7ee2")]
[Flags]
public enum SECPKG_CONTEXT_EXPORT
{
/// The new security context is reset to its initial state.
SECPKG_CONTEXT_EXPORT_RESET_NEW = 1,
/// The old security context is deleted.
SECPKG_CONTEXT_EXPORT_DELETE_OLD = 2,
///
/// This value is not supported.
///
/// Windows Server 2003 and Windows XP/2000: The security context is to be exported to the kernel.This value is supported only in
/// Schannel kernel mode.
///
///
SECPKG_CONTEXT_EXPORT_TO_KERNEL = 4,
}
/// A flag that indicates how credentials will be used.
[PInvokeData("sspi.h", MSDNShortId = "3b73decf-75d4-4bc4-b7ca-5f16aaadff29")]
public enum SECPKG_CRED
{
/// Allow a local client credential to prepare an outgoing token.
SECPKG_CRED_OUTBOUND = 0x2,
///
/// Validate an incoming server credential. Inbound credentials might be validated by using an authenticating authority when
/// InitializeSecurityContext (CredSSP) or AcceptSecurityContext (CredSSP) is called. If such an authority is not available, the
/// function will fail and return SEC_E_NO_AUTHENTICATING_AUTHORITY. Validation is package specific.
///
SECPKG_CRED_INBOUND = 0x1,
///
SECPKG_CRED_BOTH = 0x3,
///
SECPKG_CRED_DEFAULT = 0x4
}
/// Specifies the attribute to query.
[PInvokeData("sspi.h", MSDNShortId = "a8ba6f73-8469-431b-b185-183b45b2c533")]
public enum SECPKG_CRED_ATTR
{
///
/// Returns the certificate thumbprint in a pbuffer of type SecPkgCredentials_Cert.
/// This attribute is only supported by Kerberos.
///
/// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This attribute is
/// not available.
///
///
[CorrespondingType(typeof(SecPkgCredentials_Cert), CorrespondingAction.Get)]
SECPKG_CRED_ATTR_CERT = 4,
///
/// Returns the name of a credential in a pbuffer of type SecPkgCredentials_Names.
/// This attribute is not supported by Schannel in WOW64 mode.
///
[CorrespondingType(typeof(SecPkgCredentials_Names))]
SECPKG_CRED_ATTR_NAMES = 1,
///
/// Returns the supported algorithms in a pbuffer of type SecPkgCred_SupportedAlgs. All supported algorithms are included,
/// regardless of whether they are supported by the provided certificate or enabled on the local computer.
/// This attribute is supported only by Schannel.
///
[CorrespondingType(typeof(SecPkgCred_SupportedAlgs))]
SECPKG_ATTR_SUPPORTED_ALGS = 0x56,
///
/// Returns the cipher strengths in a pbuffer of type SecPkgCred_CipherStrengths.
/// This attribute is supported only by Schannel.
///
[CorrespondingType(typeof(SecPkgCred_CipherStrengths))]
SECPKG_ATTR_CIPHER_STRENGTHS = 0x57,
///
/// Returns the supported algorithms in a pbuffer of type SecPkgCred_SupportedProtocols. All supported protocols are included,
/// regardless of whether they are supported by the provided certificate or enabled on the local computer.
/// This attribute is supported only by Schannel.
///
[CorrespondingType(typeof(SecPkgCred_SupportedProtocols))]
SECPKG_ATTR_SUPPORTED_PROTOCOLS = 0x58,
}
///
/// Indicates the type of credential used in a client context. The SECPKG_CRED_CLASS enumeration is used in the
/// SecPkgContext_CredInfo structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ne-sspi-_secpkg_cred_class typedef enum _SECPKG_CRED_CLASS {
// SecPkgCredClass_None, SecPkgCredClass_Ephemeral, SecPkgCredClass_PersistedGeneric, SecPkgCredClass_PersistedSpecific,
// SecPkgCredClass_Explicit } SECPKG_CRED_CLASS, *PSECPKG_CRED_CLASS;
[PInvokeData("sspi.h", MSDNShortId = "2f5f9be2-e7b5-4d34-a2ad-89a99db78ad0")]
public enum SECPKG_CRED_CLASS
{
/// No credentials are supplied.
SecPkgCredClass_None = 0,
/// Indicates the credentials used to log on to the system.
SecPkgCredClass_Ephemeral = 10,
/// Indicates saved credentials that are not target specific.
SecPkgCredClass_PersistedGeneric = 20,
/// Indicates saved credentials that are target specific.
SecPkgCredClass_PersistedSpecific = 30,
/// The sec PKG cred class explicit
SecPkgCredClass_Explicit = 40,
}
/// Bit flags that describe the capabilities of the security package.
[PInvokeData("sspi.h", MSDNShortId = "d0bff3d8-63f1-4a4e-851f-177040af6bd2")]
[Flags]
public enum SECPKG_FLAG : uint
{
/// The security package supports the MakeSignature and VerifySignature functions.
SECPKG_FLAG_INTEGRITY = 0x1,
/// The security package supports the EncryptMessage (General) and DecryptMessage (General) functions.
SECPKG_FLAG_PRIVACY = 0x2,
///
/// The package is interested only in the security-token portion of messages, and will ignore any other buffers. This is a
/// performance-related issue.
///
SECPKG_FLAG_TOKEN_ONLY = 0x4,
///
/// Supports datagram-style authentication. For more information, see SSPI Context Semantics.
/// Important The Microsoft Kerberos package does not support datagram contexts in user-to-user mode.
///
SECPKG_FLAG_DATAGRAM = 0x8,
/// Supports connection-oriented style authentication. For more information, see SSPI Context Semantics.
SECPKG_FLAG_CONNECTION = 0x10,
/// Multiple legs are required for authentication.
SECPKG_FLAG_MULTI_REQUIRED = 0x20,
/// Server authentication support is not provided.
SECPKG_FLAG_CLIENT_ONLY = 0x40,
/// Supports extended error handling. For more information, see Extended Error Information.
SECPKG_FLAG_EXTENDED_ERROR = 0x80,
/// Supports Windows impersonation in server contexts.
SECPKG_FLAG_IMPERSONATION = 0x100,
/// Understands Windows principal and target names.
SECPKG_FLAG_ACCEPT_WIN32_NAME = 0x200,
/// Supports stream semantics. For more information, see SSPI Context Semantics.
SECPKG_FLAG_STREAM = 0x400,
/// Can be used by the Microsoft Negotiate security package.
SECPKG_FLAG_NEGOTIABLE = 0x800,
/// Supports GSS compatibility.
SECPKG_FLAG_GSS_COMPATIBLE = 0x1000,
/// Supports LsaLogonUser.
SECPKG_FLAG_LOGON = 0x2000,
/// Token buffers are in ASCII characters format.
SECPKG_FLAG_ASCII_BUFFERS = 0x4000,
///
/// Supports separating large tokens into smaller buffers so that applications can make repeated calls to
/// InitializeSecurityContext (General) and AcceptSecurityContext (General) with the smaller buffers to complete authentication.
///
SECPKG_FLAG_FRAGMENT = 0x8000,
/// Supports mutual authentication.
SECPKG_FLAG_MUTUAL_AUTH = 0x10000,
/// Supports delegation.
SECPKG_FLAG_DELEGATION = 0x20000,
///
/// The security package supports using a checksum instead of in-place encryption when calling the EncryptMessage function.
///
SECPKG_FLAG_READONLY_WITH_CHECKSUM = 0x40000,
/// Supports callers with restricted tokens.
SECPKG_FLAG_RESTRICTED_TOKENS = 0x80000,
///
/// The security package extends the Microsoft Negotiate security package. There can be at most one package of this type.
///
SECPKG_FLAG_NEGO_EXTENDER = 0x00100000,
/// This package is negotiated by the package of type SECPKG_FLAG_NEGO_EXTENDER.
SECPKG_FLAG_NEGOTIABLE2 = 0x00200000,
/// This package receives all calls from app container apps.
SECPKG_FLAG_APPCONTAINER_PASSTHROUGH = 0x00400000,
///
/// This package receives calls from app container apps if one of the following checks succeeds.
///
/// -
/// Caller has default credentials capability.
///
/// -
/// The target is a proxy server.
///
/// -
/// The caller has supplied credentials.
///
///
///
SECPKG_FLAG_APPCONTAINER_CHECKS = 0x00800000,
/// This package is running with Credential Guard enabled.
SECPKG_FLAG_CREDENTIAL_ISOLATION_ENABLED = 0x01000000,
///
SECPKG_FLAG_UNDOCUMENTED1 = 0x02000000,
}
/// The type of security package.
[PInvokeData("sspi.h", MSDNShortId = "2e9f65ec-72a5-4d6f-aa63-f83369f0dd07")]
public enum SECPKG_OPTIONS_TYPE
{
/// The package type is not known.
SECPKG_OPTIONS_TYPE_UNKNOWN = 0,
/// The security package is an LSA authentication package.
SECPKG_OPTIONS_TYPE_LSA = 1,
/// The security package is a Security Support Provider Interface (SSPI) package.
SECPKG_OPTIONS_TYPE_SSPI = 2,
}
/// Package-specific flags that indicate the quality of protection.
[PInvokeData("Sspi.h", MSDNShortId = "aa375348")]
[Flags]
public enum SECQOP : uint
{
/// The message is not encrypted, but a header or trailer is present.
SECQOP_WRAP_NO_ENCRYPT = 0x80000001,
///
/// Send an Schannel alert message. In this case, the pMessage parameter must contain a standard two-byte SSL/TLS event code.
/// This value is supported only by the Schannel SSP.
///
SECQOP_WRAP_OOB_DATA = 0x40000000,
}
///
/// The AcceptSecurityContext (CredSSP) function lets the server component of a transport application establish a security
/// context between the server and a remote client. The remote client calls the InitializeSecurityContext (CredSSP) function to start
/// the process of establishing a security context. The server can require one or more reply tokens from the remote client to
/// complete establishing the security context.
///
///
/// A handle to the server credentials. To retrieve this handle, the server calls the AcquireCredentialsHandle (CredSSP) function
/// with either the SECPKG_CRED_INBOUND or SECPKG_CRED_BOTH flag set.
///
///
/// A pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext (CredSSP), this pointer is NULL. On
/// subsequent calls, phContext specifies the partially formed context returned in the phNewContext parameter by the first call.
///
///
///
/// A pointer to a SecBufferDesc structure generated by a client call to InitializeSecurityContext (CredSSP). The structure contains
/// the input buffer descriptor.
///
///
/// The first buffer must be of type SECBUFFER_TOKEN and contain the security token received from the client. The second
/// buffer should be of type SECBUFFER_EMPTY.
///
///
///
///
/// -Bit flags that specify the attributes required by the server to establish the context. Bit flags can be combined by using
/// bitwise- OR operations. This parameter can be one or more of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// ASC_REQ_ALLOCATE_MEMORY
///
/// Credential Security Support Provider (CredSSP) will allocate output buffers. When you have finished using the output buffers,
/// free them by calling the FreeContextBuffer function.
///
///
/// -
/// ASC_REQ_CONNECTION
/// The security context will not handle formatting messages.
///
/// -
/// ASC_REQ_DELEGATE
/// The server is allowed to impersonate the client. Ignore this flag for constrained delegation.
///
/// -
/// ASC_REQ_EXTENDED_ERROR
/// When errors occur, the remote party will be notified.
///
/// -
/// ASC_REQ_REPLAY_DETECT
/// Detect replayed packets.
///
/// -
/// ASC_REQ_SEQUENCE_DETECT
/// Detect messages received out of sequence.
///
/// -
/// ASC_REQ_STREAM
/// Support a stream-oriented connection.
///
///
///
/// For possible attribute flags and their meanings, see Context Requirements. Flags used for this parameter are prefixed with
/// ASC_REQ, for example, ASC_REQ_DELEGATE.
///
/// The requested attributes may not be supported by the client. For more information, see the pfContextAttr parameter.
///
///
/// The data representation, such as byte ordering, on the target. This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
///
///
/// A pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext (CredSSP), this pointer receives the new
/// context handle. On subsequent calls, phNewContext can be the same as the handle specified in the phContext parameter.
///
///
///
/// A pointer to a SecBufferDesc structure that contains the output buffer descriptor. This buffer is sent to the client for input
/// into additional calls to InitializeSecurityContext (CredSSP). An output buffer may be generated even if the function returns
/// SEC_E_OK. Any buffer generated must be sent back to the client application.
///
///
/// On output, this buffer receives a token for the security context. The token must be sent to the client. The function can also
/// return a buffer of type SECBUFFER_EXTRA.
///
///
///
///
/// A pointer to a set of bit flags that indicate the attributes of the established context. For a description of the various
/// attributes, see Context Requirements. Flags used for this parameter are prefixed with ASC_RET, for example, ASC_RET_DELEGATE.
///
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags not related to
/// security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
///
/// The PTS time stamp.
///
/// This function returns one of the following values.
///
///
/// Return code/value
/// Description
///
/// -
/// SEC_E_INCOMPLETE_MESSAGE 0x80090318L
///
/// The function succeeded. The data in the input buffer is incomplete. The application must read additional data from the client and
/// call AcceptSecurityContext (CredSSP) again.
///
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY 0x80090300L
/// The function failed. There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR 0x80090304L
/// The function failed. An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_INVALID_HANDLE 0x80100003L
/// The function failed. The handle passed to the function is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN 0x80090308L
/// The function failed. The token passed to the function is not valid.
///
/// -
/// SEC_E_LOGON_DENIED 0x8009030CL
/// The logon failed.
///
/// -
/// SEC_E_NO_AUTHENTICATING_AUTHORITY 0x80090311L
/// The function failed. No authority could be contacted for authentication. This could be due to the following conditions:
///
/// -
/// SEC_E_NO_CREDENTIALS 0x8009030EL
/// The function failed. The credentials handle specified in the phCredential parameter is not valid.
///
/// -
/// SEC_E_OK 0x00000000L
///
/// The function succeeded. The security context received from the client was accepted. If the function generated an output token,
/// the token must be sent to the client process.
///
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION 0x80090302L
///
/// The function failed. The fContextReq parameter specified a context attribute flag (ASC_REQ_DELEGATE or ASC_REQ_PROMPT_FOR_CREDS)
/// that was not valid.
///
///
/// -
/// SEC_I_COMPLETE_AND_CONTINUE 0x00090314L
///
/// The function succeeded. The server must call CompleteAuthToken and pass the output token to the client. The server must then wait
/// for a return token from the client before making another call to AcceptSecurityContext (CredSSP).
///
///
/// -
/// SEC_I_COMPLETE_NEEDED 0x00090313L
/// The function succeeded. The server must finish building the message from the client before calling CompleteAuthToken.
///
/// -
/// SEC_I_CONTINUE_NEEDED 0x00090312L
///
/// The function succeeded. The server must send the output token to the client and wait for a returned token. The returned token
/// should be passed in pInput for another call to AcceptSecurityContext (CredSSP).
///
///
///
///
///
///
/// The AcceptSecurityContext (CredSSP) function is the server counterpart to the InitializeSecurityContext (CredSSP) function.
///
///
/// When the server receives a request from a client, it uses the fContextReq parameter to specify what it requires of the session.
/// In this fashion, a server can require that clients be capable of using a confidential or integrity-checked session; it can reject
/// clients that cannot meet that demand. Alternatively, a server can require nothing; whatever the client requires or can provide is
/// returned in the pfContextAttr parameter.
///
///
/// The fContextReq and pfContextAttr parameters are bitmasks that represent various context attributes. For a description of the
/// various attributes, see Context Requirements.
///
///
/// Note While the pfContextAttr parameter is valid on any successful return, you should examine the flags pertaining to
/// security aspects of the context only on the final successful return. Intermediate returns can set, for example, the
/// ISC_RET_ALLOCATED_MEMORY flag.
///
///
/// The caller is responsible for determining whether the final context attributes are sufficient. For example, if confidentiality
/// (encryption) was requested but could not be established, some applications may choose to shut down the connection immediately. If
/// the security context cannot be established, the server must free the partially created context by calling the
/// DeleteSecurityContext function. For information about when to call the DeleteSecurityContext function, see DeleteSecurityContext.\
///
///
/// After the security context has been established, the server application can use the QuerySecurityContextToken function to
/// retrieve a handle to the user account to which the client certificate was mapped. Also, the server can use the
/// ImpersonateSecurityContext function to impersonate the user.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-acceptsecuritycontext KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// AcceptSecurityContext( PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, unsigned long fContextReq, unsigned
// long TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "a53f733e-b646-4431-b021-a2c446308849")]
public static unsafe extern HRESULT AcceptSecurityContext([Optional] CredHandle* phCredential, CtxtHandle* phContext, [In, Optional] SecBufferDesc* pInput, ASC_REQ fContextReq, DREP TargetDataRep,
out CtxtHandle phNewContext, [Optional] SecBufferDesc* pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsTimeStamp);
///
///
/// The AcquireCredentialsHandle (CredSSP) function acquires a handle to preexisting credentials of a security principal. This
/// handle is required by the InitializeSecurityContext (CredSSP) and AcceptSecurityContext (CredSSP) functions. These can be either
/// preexisting credentials, which are established through a system logon that is not described here, or the caller can provide
/// alternative credentials.
///
/// Note This is not a "log on to the network" and does not imply gathering of credentials.
///
///
/// A pointer to a null-terminated string that specifies the name of the principal whose credentials the handle will reference.
///
/// Note If the process that requests the handle does not have access to the credentials, the function returns an error. A
/// null string indicates that the process requires a handle to the credentials of the user under whose security context it is executing.
///
///
///
/// A pointer to a null-terminated string that specifies the name of the security package with which these credentials will be used.
/// This is a security package name returned in the Name member of a SecPkgInfo structure returned by the
/// EnumerateSecurityPackages function. After a context is established, QueryContextAttributes (CredSSP) can be called with
/// ulAttribute set to SECPKG_ATTR_PACKAGE_INFO to return information on the security package in use.
///
///
/// A flag that indicates how these credentials will be used. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_CRED_INBOUND 0x1
///
/// Validate an incoming server credential. Inbound credentials might be validated by using an authenticating authority when
/// InitializeSecurityContext (CredSSP) or AcceptSecurityContext (CredSSP) is called. If such an authority is not available, the
/// function will fail and return SEC_E_NO_AUTHENTICATING_AUTHORITY. Validation is package specific.
///
///
/// -
/// SECPKG_CRED_OUTBOUND 0x0
/// Allow a local client credential to prepare an outgoing token.
///
///
///
///
/// A pointer to a locally unique identifier (LUID) that identifies the user. This parameter is provided for file-system processes
/// such as network redirectors. This parameter can be NULL.
///
///
/// A pointer to a CREDSSP_CRED structure that specifies authentication data for both Schannel and Negotiate packages.
///
/// Reserved. This parameter is not used and should be set to NULL.
/// Reserved. This parameter must be set to NULL.
/// A pointer to the CredHandle structure that will receive the credential handle.
///
/// A pointer to a TimeStamp structure that receives the time at which the returned credentials expire. The structure value received
/// depends on the security package, which must specify the value in local time.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is insufficient memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_NOT_OWNER
/// The caller of the function does not have the necessary credentials.
///
/// -
/// SEC_E_SECPKG_NOT_FOUND
/// The requested security package does not exist.
///
/// -
/// SEC_E_UNKNOWN_CREDENTIALS
/// The credentials supplied to the package were not recognized.
///
///
///
///
///
/// The AcquireCredentialsHandle (CredSSP) function returns a handle to the credentials of a principal, such as a user or
/// client, as used by a specific security package. The function can return the handle to either preexisting credentials or newly
/// created credentials and return it. This handle can be used in subsequent calls to the AcceptSecurityContext (CredSSP) and
/// InitializeSecurityContext (CredSSP) functions.
///
///
/// In general, AcquireCredentialsHandle (CredSSP) does not provide the credentials of other users logged on to the same
/// computer. However, a caller with SE_TCB_NAME privilege can obtain the credentials of an existing logon session by specifying the
/// logon identifier (LUID) of that session. Typically, this is used by kernel-mode modules that must act on behalf of a logged-on user.
///
///
/// A package might call the function in pGetKeyFn provided by the RPC run-time transport. If the transport does not support the
/// notion of callback to retrieve credentials, this parameter must be NULL.
///
/// For kernel mode callers, the following differences must be noted:
///
/// -
/// The two string parameters must be Unicode strings.
///
/// -
/// The buffer values must be allocated in process virtual memory, not from the pool.
///
///
///
/// When you have finished using the returned credentials, free the memory used by the credentials by calling the
/// FreeCredentialsHandle function.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-acquirecredentialshandlea SECURITY_STATUS SEC_ENTRY
// AcquireCredentialsHandleA( LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, void *pvLogonId, void *pAuthData,
// SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "3b73decf-75d4-4bc4-b7ca-5f16aaadff29")]
public static extern HRESULT AcquireCredentialsHandle([Optional] string pszPrincipal, string pszPackage, SECPKG_CRED fCredentialUse, [In, Optional] IntPtr pvLogonId, [In, Optional] IntPtr pAuthData, [In, Optional] IntPtr pGetKeyFn,
[In, Optional] IntPtr pvGetKeyArgument, out CredHandle phCredential, out TimeStamp ptsExpiry);
///
///
/// The AcquireCredentialsHandle (CredSSP) function acquires a handle to preexisting credentials of a security principal. This
/// handle is required by the InitializeSecurityContext (CredSSP) and AcceptSecurityContext (CredSSP) functions. These can be either
/// preexisting credentials, which are established through a system logon that is not described here, or the caller can provide
/// alternative credentials.
///
/// Note This is not a "log on to the network" and does not imply gathering of credentials.
///
///
/// A pointer to a null-terminated string that specifies the name of the principal whose credentials the handle will reference.
///
/// Note If the process that requests the handle does not have access to the credentials, the function returns an error. A
/// null string indicates that the process requires a handle to the credentials of the user under whose security context it is executing.
///
///
///
/// A pointer to a null-terminated string that specifies the name of the security package with which these credentials will be used.
/// This is a security package name returned in the Name member of a SecPkgInfo structure returned by the
/// EnumerateSecurityPackages function. After a context is established, QueryContextAttributes (CredSSP) can be called with
/// ulAttribute set to SECPKG_ATTR_PACKAGE_INFO to return information on the security package in use.
///
///
/// A flag that indicates how these credentials will be used. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_CRED_INBOUND 0x1
///
/// Validate an incoming server credential. Inbound credentials might be validated by using an authenticating authority when
/// InitializeSecurityContext (CredSSP) or AcceptSecurityContext (CredSSP) is called. If such an authority is not available, the
/// function will fail and return SEC_E_NO_AUTHENTICATING_AUTHORITY. Validation is package specific.
///
///
/// -
/// SECPKG_CRED_OUTBOUND 0x0
/// Allow a local client credential to prepare an outgoing token.
///
///
///
///
/// A pointer to a locally unique identifier (LUID) that identifies the user. This parameter is provided for file-system processes
/// such as network redirectors. This parameter can be NULL.
///
///
/// A pointer to a CREDSSP_CRED structure that specifies authentication data for both Schannel and Negotiate packages.
///
/// Reserved. This parameter is not used and should be set to NULL.
/// Reserved. This parameter must be set to NULL.
/// A pointer to the CredHandle structure that will receive the credential handle.
///
/// A pointer to a TimeStamp structure that receives the time at which the returned credentials expire. The structure value received
/// depends on the security package, which must specify the value in local time.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is insufficient memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_NOT_OWNER
/// The caller of the function does not have the necessary credentials.
///
/// -
/// SEC_E_SECPKG_NOT_FOUND
/// The requested security package does not exist.
///
/// -
/// SEC_E_UNKNOWN_CREDENTIALS
/// The credentials supplied to the package were not recognized.
///
///
///
///
///
/// The AcquireCredentialsHandle (CredSSP) function returns a handle to the credentials of a principal, such as a user or
/// client, as used by a specific security package. The function can return the handle to either preexisting credentials or newly
/// created credentials and return it. This handle can be used in subsequent calls to the AcceptSecurityContext (CredSSP) and
/// InitializeSecurityContext (CredSSP) functions.
///
///
/// In general, AcquireCredentialsHandle (CredSSP) does not provide the credentials of other users logged on to the same
/// computer. However, a caller with SE_TCB_NAME privilege can obtain the credentials of an existing logon session by specifying the
/// logon identifier (LUID) of that session. Typically, this is used by kernel-mode modules that must act on behalf of a logged-on user.
///
///
/// A package might call the function in pGetKeyFn provided by the RPC run-time transport. If the transport does not support the
/// notion of callback to retrieve credentials, this parameter must be NULL.
///
/// For kernel mode callers, the following differences must be noted:
///
/// -
/// The two string parameters must be Unicode strings.
///
/// -
/// The buffer values must be allocated in process virtual memory, not from the pool.
///
///
///
/// When you have finished using the returned credentials, free the memory used by the credentials by calling the
/// FreeCredentialsHandle function.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-acquirecredentialshandlea SECURITY_STATUS SEC_ENTRY
// AcquireCredentialsHandleA( LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, void *pvLogonId, void *pAuthData,
// SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "3b73decf-75d4-4bc4-b7ca-5f16aaadff29")]
public static extern HRESULT AcquireCredentialsHandle([Optional] string pszPrincipal, string pszPackage, SECPKG_CRED fCredentialUse, in LUID pvLogonId, in CREDSSP_CRED pAuthData, [In, Optional] SEC_GET_KEY_FN pGetKeyFn,
[In, Optional] IntPtr pvGetKeyArgument, out CredHandle phCredential, out TimeStamp ptsExpiry);
/// Adds a security support provider to the list of providers supported by Microsoft Negotiate.
/// The name of the package to add.
///
/// A pointer to a SECURITY_PACKAGE_OPTIONS structure that specifies additional information about the security package.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-addsecuritypackagea SECURITY_STATUS SEC_ENTRY
// AddSecurityPackageA( LPSTR pszPackageName, PSECURITY_PACKAGE_OPTIONS pOptions );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "35b993d2-87a0-46d0-991f-88358b0cc5e6")]
public static extern HRESULT AddSecurityPackage(string pszPackageName, in SECURITY_PACKAGE_OPTIONS pOptions);
/// Adds a security support provider to the list of providers supported by Microsoft Negotiate.
/// The name of the package to add.
///
/// A pointer to a SECURITY_PACKAGE_OPTIONS structure that specifies additional information about the security package.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-addsecuritypackagea SECURITY_STATUS SEC_ENTRY
// AddSecurityPackageA( LPSTR pszPackageName, PSECURITY_PACKAGE_OPTIONS pOptions );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "35b993d2-87a0-46d0-991f-88358b0cc5e6")]
public static extern HRESULT AddSecurityPackage(string pszPackageName, [Optional] IntPtr pOptions);
///
///
/// The ApplyControlToken function provides a way to apply a control token to a security context. A token can be received when
/// the security context is being established by a call to the InitializeSecurityContext (Schannel) function or with a per-message
/// security service, such as verify or unseal.
///
/// This function is supported only by the Schannel security support provider (SSP).
/// This function is not supported in kernel mode.
/// This function allows additional or replacement tokens to be applied to a context.
///
///
/// A handle to the context to which the token is applied.
///
/// For information about the way the Schannel SSP notifies the remote party of the shutdown, see the Remarks section of
/// DecryptMessage (Schannel). For additional information on the use of this function, see Shutting Down an Schannel Connection.
///
///
///
/// A pointer to a SecBufferDesc structure that contains a pointer to a SecBuffer structure that contains the input token to apply to
/// the context.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
///
/// If the function fails, it returns a nonzero error code. The following error code is one of the possible error codes that can be returned.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
/// This value is returned by Schannel kernel mode to indicate that this function is not supported.
///
///
///
///
///
/// The ApplyControlToken function can modify the context based on this token. Among the tokens that this function can add to
/// the client context are SCHANNEL_ALERT_TOKEN and SCHANNEL_SESSION_TOKEN.
///
///
/// This function can be used to shut down the security context that underlies an existing Schannel connection. For information about
/// how to do this, see Shutting Down an Schannel Connection.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-applycontroltoken KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// ApplyControlToken( PCtxtHandle phContext, PSecBufferDesc pInput );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "5ce13a05-874c-4e1a-9be8-aed98609791e")]
public static extern HRESULT ApplyControlToken(in CtxtHandle phContext, in SecBufferDesc pInput);
///
///
/// The ChangeAccountPassword function changes the password for a Windows domain account by using the specified Security
/// Support Provider.
///
/// This function is supported only by the Microsoft Kerberos, Microsoft Negotiate, and Microsoft NTLM providers.
///
///
/// The name of the provider to use. The value of this parameter must be either "Kerberos", "Negotiate", or "NTLM".
///
/// The domain of the account for which to change the password.
/// The user name of the account for which to change the password.
/// The old password to be changed.
/// The new password for the specified account.
/// TRUE if the calling process is running as the client; otherwise, FALSE.
/// Reserved. Must be set to zero.
///
/// On input, a pointer to a SecBufferDesc structure. The SecBufferDesc structure must contain a single buffer of type
/// SECBUFFER_CHANGE_PASS_RESPONSE. On output, the pvBuffer member of that structure points to a
/// DOMAIN_PASSWORD_INFORMATION structure.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns an error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-changeaccountpassworda SECURITY_STATUS SEC_ENTRY
// ChangeAccountPasswordA( SEC_CHAR *pszPackageName, SEC_CHAR *pszDomainName, SEC_CHAR *pszAccountName, SEC_CHAR *pszOldPassword,
// SEC_CHAR *pszNewPassword, BOOLEAN bImpersonating, unsigned long dwReserved, PSecBufferDesc pOutput );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "a1d1e315-d1a2-499a-b552-83180508271f")]
public static extern HRESULT ChangeAccountPassword(string pszPackageName, string pszDomainName, string pszAccountName, string pszOldPassword, string pszNewPassword, [MarshalAs(UnmanagedType.U1)] bool bImpersonating,
[Optional] uint dwReserved, ref SecBufferDesc pOutput);
///
///
/// The CompleteAuthToken function completes an authentication token. This function is used by protocols, such as DCE, that
/// need to revise the security information after the transport application has updated some message parameters.
///
/// This function is supported only by the Digest security support provider (SSP).
/// CompleteAuthToken is used on the server side only.
///
/// A handle of the context that needs to be completed.
/// A pointer to a SecBufferDesc structure that contains the buffer descriptor for the entire message.
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle that was passed to the function is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
/// The token that was passed to the function is not valid.
///
/// -
/// SEC_E_OUT_OF_SEQUENCE
///
/// The client's security context was located, but the message number is incorrect. This return value is used with the Digest SSP.
///
///
/// -
/// SEC_E_MESSAGE_ALTERED
///
/// The client's security context was located, but the client's message has been tampered with. This return value is used with the
/// Digest SSP.
///
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
///
///
///
/// The client of a transport application calls the CompleteAuthToken function to allow the security package to update a
/// checksum or similar operation after all the protocol headers have been updated by the transport application. The client calls
/// this function only if the InitializeSecurityContext (Digest) call returned SEC_I_COMPLETE_NEEDED or SEC_I_COMPLETE_AND_CONTINUE.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-completeauthtoken SECURITY_STATUS SEC_ENTRY CompleteAuthToken(
// PCtxtHandle phContext, PSecBufferDesc pToken );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "a404d0a3-d1ea-4708-87d7-2d216e9a5f5f")]
public static extern HRESULT CompleteAuthToken(in CtxtHandle phContext, in SecBufferDesc pToken);
///
///
/// The DecryptMessage (Digest) function decrypts a message. Some packages do not encrypt and decrypt messages but rather
/// perform and check an integrity hash.
///
///
/// The Digest security support provider (SSP) provides encryption and decryption confidentiality for messages exchanged between
/// client and server as a SASL mechanism only.
///
///
/// Note EncryptMessage (Digest) and DecryptMessage (Digest) can be called at the same time from two different threads
/// in a single Security Support Provider Interface (SSPI) context if one thread is encrypting and the other is decrypting. If more
/// than one thread is encrypting, or more than one thread is decrypting, each thread should obtain a unique context.
///
///
/// A handle to the security context to be used to decrypt the message.
///
///
/// A pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures. At least one of
/// these must be of type SECBUFFER_DATA. That buffer contains the encrypted message. The encrypted message is decrypted in place,
/// overwriting the original contents of its buffer.
///
///
/// When using the Digest SSP, on input, the structure references one or more SecBuffer structures. One of these must be of type
/// SECBUFFER_DATA or SECBUFFER_STREAM, and it must contain the encrypted message.
///
///
///
///
/// The sequence number expected by the transport application, if any. If the transport application does not maintain sequence
/// numbers, this parameter must be set to zero.
///
/// When using the Digest SSP, this parameter must be set to zero. The Digest SSP manages sequence numbering internally.
///
///
/// A pointer to a variable of type ULONG that receives package-specific flags that indicate the quality of protection.
/// This parameter can be one of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// SECQOP_WRAP_NO_ENCRYPT
/// The message was not encrypted, but a header or trailer was produced.
///
/// -
/// SIGN_ONLY
///
/// When using the Digest SSP, use this flag when the security context is set to verify the signature only. For more information, see
/// Quality of Protection.
///
///
///
///
///
/// If the function verifies that the message was received in the correct sequence, the function returns SEC_E_OK.
/// If the function fails to decrypt the message, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_BUFFER_TOO_SMALL
/// The message buffer is too small. Used with the Digest SSP.
///
/// -
/// SEC_E_CRYPTO_SYSTEM_INVALID
/// The cipher chosen for the security context is not supported. Used with the Digest SSP.
///
/// -
/// SEC_E_INCOMPLETE_MESSAGE
///
/// The data in the input buffer is incomplete. The application needs to read more data from the server and call DecryptMessage
/// (Digest) again.
///
///
/// -
/// SEC_E_INVALID_HANDLE
/// A context handle that is not valid was specified in the phContext parameter. Used with the Digest SSP.
///
/// -
/// SEC_E_MESSAGE_ALTERED
/// The message has been altered. Used with the Digest SSP.
///
/// -
/// SEC_E_OUT_OF_SEQUENCE
/// The message was not received in the correct sequence.
///
/// -
/// SEC_E_QOP_NOT_SUPPORTED
/// Neither confidentiality nor integrity are supported by the security context. Used with the Digest SSP.
///
///
///
///
///
/// Sometimes an application will read data from the remote party, attempt to decrypt it by using DecryptMessage (Digest), and
/// discover that DecryptMessage (Digest) succeeded but the output buffers are empty. This is normal behavior, and
/// applications must be able to deal with it.
///
///
/// Windows XP: This function was also known as UnsealMessage. Applications should now use DecryptMessage
/// (Digest) only.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-decryptmessage SECURITY_STATUS SEC_ENTRY DecryptMessage(
// PCtxtHandle phContext, PSecBufferDesc pMessage, unsigned long MessageSeqNo, unsigned long *pfQOP );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "46d45f59-33fa-434a-b329-20b6257c9a19")]
public static extern HRESULT DecryptMessage(in CtxtHandle phContext, ref SecBufferDesc pMessage, uint MessageSeqNo, out SECQOP pfQOP);
///
/// The DeleteSecurityContext function deletes the local data structures associated with the specified security context
/// initiated by a previous call to the InitializeSecurityContext (General) function or the AcceptSecurityContext (General) function.
///
/// Handle of the security context to delete.
///
/// If the function succeeds or the handle has already been deleted, the return value is SEC_E_OK.
/// If the function fails, the return value can be the following error code.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
///
///
///
/// The DeleteSecurityContext function terminates a security context and frees associated resources.
///
/// The caller must call this function for a security context when that security context is no longer needed. This is true if the
/// security context is partial, incomplete, rejected, or failed. After the security context is successfully deleted, further use of
/// that security context is not permitted and the handle is no longer valid.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-deletesecuritycontext KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// DeleteSecurityContext( PCtxtHandle phContext );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "2a4dd697-ef90-4c37-ab74-0e5ab92794cd")]
public static extern HRESULT DeleteSecurityContext(in CtxtHandle phContext);
/// Deletes a security support provider from the list of providers supported by Microsoft Negotiate.
/// The name of the security provider to delete.
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-deletesecuritypackagea SECURITY_STATUS SEC_ENTRY
// DeleteSecurityPackageA( LPSTR pszPackageName );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "7a9a2c64-92a4-419b-8b20-d0f5cba64147")]
public static extern HRESULT DeleteSecurityPackage(string pszPackageName);
///
///
/// The EncryptMessage (Digest) function encrypts a message to provide privacy. EncryptMessage (Digest) allows the
/// application to choose among cryptographic algorithms supported by the chosen mechanism. The EncryptMessage (Digest)
/// function uses the security context referenced by the context handle. Some packages do not have messages to be encrypted or
/// decrypted but rather provide an integrity hash that can be checked.
///
/// This function is available as a SASL mechanism only.
///
/// NoteEncryptMessage (Digest) and DecryptMessage (Digest) can be called at the same time from two different threads
/// in a single Security Support Provider Interface (SSPI) context if one thread is encrypting and the other is decrypting. If more
/// than one thread is encrypting, or more than one thread is decrypting, each thread should obtain a unique context.
///
///
/// A handle to the security context to be used to encrypt the message.
///
///
/// Package-specific flags that indicate the quality of protection. A security package can use this parameter to enable the selection
/// of cryptographic algorithms.
///
/// When using the Digest SSP, this parameter must be set to zero.
///
///
///
/// A pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures that can be of type
/// SECBUFFER_DATA. That buffer contains the message to be encrypted. The message is encrypted in place, overwriting the original
/// contents of the structure.
///
/// The function does not process buffers with the SECBUFFER_READONLY attribute.
///
/// The length of the SecBuffer structure that contains the message must be no greater than cbMaximumMessage, which is
/// obtained from the QueryContextAttributes (Digest) (SECPKG_ATTR_STREAM_SIZES) function.
///
///
/// When using the Digest SSP, there must be a second buffer of type SECBUFFER_PADDING or SEC_BUFFER_DATA to hold signature
/// information. To get the size of the output buffer, call the QueryContextAttributes (Digest) function and specify
/// SECPKG_ATTR_SIZES. The function will return a SecPkgContext_Sizes structure. The size of the output buffer is the sum of the
/// values in the cbMaxSignature and cbBlockSize members.
///
/// Applications that do not use SSL must supply a SecBuffer of type SECBUFFER_PADDING.
///
///
///
/// The sequence number that the transport application assigned to the message. If the transport application does not maintain
/// sequence numbers, this parameter must be zero.
///
/// When using the Digest SSP, this parameter must be set to zero. The Digest SSP manages sequence numbering internally.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_BUFFER_TOO_SMALL
/// The output buffer is too small. For more information, see Remarks.
///
/// -
/// SEC_E_CONTEXT_EXPIRED
///
/// The application is referencing a context that has already been closed. A properly written application should not receive this error.
///
///
/// -
/// SEC_E_CRYPTO_SYSTEM_INVALID
/// The cipher chosen for the security context is not supported.
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INVALID_HANDLE
/// A context handle that is not valid was specified in the phContext parameter.
///
/// -
/// SEC_E_INVALID_TOKEN
/// No SECBUFFER_DATA type buffer was found.
///
/// -
/// SEC_E_QOP_NOT_SUPPORTED
/// Neither confidentiality nor integrity are supported by the security context.
///
///
///
///
///
/// The EncryptMessage (Digest) function encrypts a message based on the message and the session key from a security context.
///
///
/// If the transport application created the security context to support sequence detection and the caller provides a sequence
/// number, the function includes this information with the encrypted message. Including this information protects against replay,
/// insertion, and suppression of messages. The security package incorporates the sequence number passed down from the transport application.
///
///
/// When you use the Digest SSP, get the size of the output buffer by calling the QueryContextAttributes (Digest) function and
/// specifying SECPKG_ATTR_SIZES. The function will return a SecPkgContext_Sizes structure. The size of the output buffer is the sum
/// of the values in the cbMaxSignature and cbBlockSize members.
///
/// Note These buffers must be supplied in the order shown.
///
///
/// Buffer type
/// Description
///
/// -
/// SECBUFFER_STREAM_HEADER
/// Used internally. No initialization required.
///
/// -
/// SECBUFFER_DATA
/// Contains the plaintext message to be encrypted.
///
/// -
/// SECBUFFER_STREAM_TRAILER
/// Used internally. No initialization required.
///
/// -
/// SECBUFFER_EMPTY
/// Used internally. No initialization required. Size can be zero.
///
///
/// For optimal performance, the pMessage structures should be allocated from contiguous memory.
///
/// Windows XP: This function was also known as SealMessage. Applications should now use EncryptMessage (Digest) only.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-encryptmessage SECURITY_STATUS SEC_ENTRY EncryptMessage(
// PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "0045e931-929b-40c4-a524-5664d2fc5170")]
public static extern HRESULT EncryptMessage(in CtxtHandle phContext, SECQOP fQOP, ref SecBufferDesc pMessage, uint MessageSeqNo);
///
/// The EnumerateSecurityPackages function returns an array of SecPkgInfo structures that provide information about the
/// security packages available to the client.
///
///
/// A pointer to a ULONG variable that receives the number of packages available on the system. This includes packages that
/// are already loaded and packages available on demand.
///
///
///
/// A pointer to a variable that receives a pointer to an array of SecPkgInfo structures. Each structure contains information from
/// the security support provider (SSP) that describes the capabilities of the security package available within that SSP.
///
/// When you have finished using the array, free the memory by calling the FreeContextBuffer function.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
///
/// If the function fails, it returns a nonzero error code. Possible values include, but are not limited to, those in the following table.
///
///
///
/// Return code/value
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY 0x80090300L
/// There was not sufficient memory to allocate one or more of the buffers.
///
/// -
/// SEC_E_INVALID_HANDLE 0x80090301L
/// An invalid handle was specified.
///
/// -
/// SEC_E_SECPKG_NOT_FOUND 0x80090305L
/// The specified package was not found.
///
///
///
///
/// The caller can use the Name member of a SecPkgInfo structure to specify a security package in a call to the
/// AcquireCredentialsHandle (General) function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-enumeratesecuritypackagesa SECURITY_STATUS SEC_ENTRY
// EnumerateSecurityPackagesA( unsigned long *pcPackages, PSecPkgInfoA *ppPackageInfo );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "900790a6-111d-43f5-9316-e85aab03a3bc")]
public static extern HRESULT EnumerateSecurityPackages(out uint pcPackages, out SafeContextBuffer ppPackageInfo);
///
/// The ExportSecurityContext function creates a serialized representation of a security context that can later be imported
/// into a different process by calling ImportSecurityContext. The process that imports the security context must be running on the
/// same computer as the process that called ExportSecurityContext.
///
/// A handle of the security context to be exported.
///
/// This parameter can be a bitwise- OR combination of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_CONTEXT_EXPORT_RESET_NEW 1 (0x1)
/// The new security context is reset to its initial state.
///
/// -
/// SECPKG_CONTEXT_EXPORT_DELETE_OLD 2 (0x2)
/// The old security context is deleted.
///
/// -
/// SECPKG_CONTEXT_EXPORT_TO_KERNEL 4 (0x4)
///
/// This value is not supported. Windows Server 2003 and Windows XP/2000: The security context is to be exported to the kernel.This
/// value is supported only in Schannel kernel mode.
///
///
///
///
///
/// A pointer to a buffer of type SECBUFFER_EMPTY that receives the serialized security context. When you have finished using
/// this context, free it by calling the FreeContextBuffer function.
///
///
/// A pointer to receive the handle of the context's token.
/// When you have finished using the user token, release the handle by calling the CloseHandle function.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INVALID_HANDLE
/// The phContext parameter does not point to a valid handle.
///
/// -
/// SEC_E_NOT_SUPPORTED
/// Schannel kernel mode does not support this function.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-exportsecuritycontext KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// ExportSecurityContext( PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, void **pToken );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "4ebc7f37-b948-4c78-973f-0a74e55c7ee2")]
public static extern HRESULT ExportSecurityContext(in CtxtHandle phContext, SECPKG_CONTEXT_EXPORT fFlags, ref SecBuffer pPackedContext, out SafeHTOKEN pToken);
///
/// The FreeContextBuffer function enables callers of security package functions to free memory buffers allocated by the
/// security package.
///
/// A pointer to memory to be freed.
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
///
///
/// Memory buffers are typically allocated by the InitializeSecurityContext (General) and AcceptSecurityContext (General) functions.
///
/// The FreeContextBuffer function can free any memory allocated by a security package.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-freecontextbuffer SECURITY_STATUS SEC_ENTRY FreeContextBuffer(
// PVOID pvContextBuffer );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "3c3d27bb-4f9a-4979-b679-1e10fa1ff221")]
public static extern HRESULT FreeContextBuffer(IntPtr pvContextBuffer);
///
///
/// The FreeCredentialsHandle function notifies the security system that the credentials are no longer needed. An application
/// calls this function to free the credential handle acquired in the call to the AcquireCredentialsHandle (General) function after
/// calling the DeleteSecurityContext function to free any context handles associated with the credential. When all references to
/// this credential set have been removed, the credentials themselves can be removed.
///
/// Failure to free credentials handles will result in memory leaks.
///
/// A pointer to the CredHandle handle obtained by using the AcquireCredentialsHandle (General) function.
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns the following error code.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-freecredentialshandle KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// FreeCredentialsHandle( PCredHandle phCredential );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "e089618c-8233-475a-9725-39265c6427ab")]
public static extern HRESULT FreeCredentialsHandle(ref CredHandle phCredential);
///
/// The ImpersonateSecurityContext function allows a server to impersonate a client by using a token previously obtained by a
/// call to AcceptSecurityContext (General) or QuerySecurityContextToken. This function allows the application server to act as the
/// client, and thus all necessary access controls are enforced.
///
///
/// The handle of the context to impersonate. This handle must have been obtained by a call to the AcceptSecurityContext (General) function.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns the following error code.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_NO_IMPERSONATION
/// The client could not be impersonated.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
/// This value is returned by Schannel kernel mode to indicate that this function is not supported.
///
///
///
///
///
/// The server application calls the ImpersonateSecurityContext function when it needs to impersonate the client. Before doing
/// so, the server must have obtained a valid context handle. To obtain the context handle, the server must call
/// AcceptSecurityContext (General) to submit the client's incoming security token to the security system. The server gets a context
/// handle if the inbound context is validated. The function creates an impersonation token and allows the thread or process to run
/// with the impersonation context.
///
///
/// When using the Schannel security support provider (SSP), the server application must pass the ASC_REQ_MUTUAL_AUTH flag
/// when calling AcceptSecurityContext (General). This ensures that the client is asked for a client certificate during the SSL/TLS
/// handshake. When a client certificate is received, the Schannel package verifies the client certificate and attempts to map it to
/// a user account. When this mapping is successful, then a client user token is created and this function succeeds.
///
///
/// The application server must call the RevertSecurityContext function when it finishes or when it needs to restore its own security context.
///
///
/// ImpersonateSecurityContext is not available with all security packages on all platforms. Typically, it is implemented only
/// on platforms and with security packages that support impersonation. To learn whether a security package supports impersonation,
/// call the QuerySecurityPackageInfo function.
///
///
/// Note If the ImpersonateSecurityContext function fails, the client is not impersonated, and all subsequent client
/// requests are made in the security context of the process that called the function. If the calling process is running as a
/// privileged account, it can perform actions that the client would not be allowed to perform. To avoid security risks, the calling
/// process should always check the return value. If the return value indicates that the function call failed, no client requests
/// should be executed.
///
///
/// All impersonate functions, including ImpersonateSecurityContext allow the requested impersonation if one of the following
/// is true:
///
///
/// -
///
/// The requested impersonation level of the token is less than SecurityImpersonation, such as SecurityIdentification
/// or SecurityAnonymous.
///
///
/// -
/// The caller has the SeImpersonatePrivilege privilege.
///
/// -
///
/// A process (or another process in the caller's logon session) created the token using explicit credentials through LogonUser or
/// LsaLogonUser function.
///
///
/// -
/// The authenticated identity is same as the caller.
///
///
/// Windows XP with SP1 and earlier: The SeImpersonatePrivilege privilege is not supported.
/// Windows XP: The SeImpersonatePrivilege privilege is not supported until Windows XP with Service Pack 2 (SP2).
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-impersonatesecuritycontext KSECDDDECLSPEC SECURITY_STATUS
// SEC_ENTRY ImpersonateSecurityContext( PCtxtHandle phContext );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "167eaf3b-b794-4587-946d-fa596f1f9411")]
public static extern HRESULT ImpersonateSecurityContext(in CtxtHandle phContext);
///
/// The ImportSecurityContext function imports a security context. The security context must have been exported to the process
/// calling ImportSecurityContext by a previous call to ExportSecurityContext.
///
/// A string that contains the name of the security package to which the security context was exported.
/// A pointer to a buffer that contains the serialized security context created by ExportSecurityContext.
/// A handle to the context's token.
///
/// A handle of the new security context created from pPackedContext. When you have finished using the context, delete it by calling
/// the DeleteSecurityContext function.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_UNKNOWN_CREDENTIALS
/// The credentials supplied to the package were not recognized.
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_NOT_OWNER
/// The caller of the function does not have the necessary credentials.
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-importsecuritycontexta SECURITY_STATUS SEC_ENTRY
// ImportSecurityContextA( LPSTR pszPackage, PSecBuffer pPackedContext, VOID *Token, PCtxtHandle phContext );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "0f8e65d0-69cf-42ba-a903-1922d731e5ec")]
public static extern HRESULT ImportSecurityContext(string pszPackage, ref SecBuffer pPackedContext, HTOKEN Token, out SafeCtxtHandle phContext);
///
///
/// The InitializeSecurityContext (General) function initiates the client side, outbound security context from a credential
/// handle. The function is used to build a security context between the client application and a remote peer.
/// InitializeSecurityContext (General) returns a token that the client must pass to the remote peer, which the peer in turn
/// submits to the local security implementation through the AcceptSecurityContext (General) call. The token generated should be
/// considered opaque by all callers.
///
///
/// Typically, the InitializeSecurityContext (General) function is called in a loop until a sufficient security context is established.
///
/// For information about using this function with a specific security support provider (SSP), see the following topics.
///
///
/// Topic
/// Description
///
/// -
/// InitializeSecurityContext (CredSSP)
///
/// Initiates the client side, outbound security context from a credential handle by using the Credential Security Support Provider (CredSSP).
///
///
/// -
/// InitializeSecurityContext (Digest)
/// Initiates the client side, outbound security context from a credential handle by using the Digest security package.
///
/// -
/// InitializeSecurityContext (Kerberos)
/// Initiates the client side, outbound security context from a credential handle by using the Kerberos security package.
///
/// -
/// InitializeSecurityContext (Negotiate)
/// Initiates the client side, outbound security context from a credential handle by using the Negotiate security package.
///
/// -
/// InitializeSecurityContext (NTLM)
/// Initiates the client side, outbound security context from a credential handle by using the NTLM security package.
///
/// -
/// InitializeSecurityContext (Schannel)
/// Initiates the client side, outbound security context from a credential handle by using the Schannel security package.
///
///
///
///
/// A handle to the credentials returned by AcquireCredentialsHandle (General). This handle is used to build the security context.
/// The InitializeSecurityContext (General) function requires at least OUTBOUND credentials.
///
///
///
/// A pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext (General), this pointer is
/// NULL. On the second call, this parameter is a pointer to the handle to the partially formed context returned in the
/// phNewContext parameter by the first call.
///
/// This parameter is optional with the Microsoft Digest SSP and can be set to NULL.
///
/// When using the Schannel SSP, on the first call to InitializeSecurityContext (General), specify NULL. On future
/// calls, specify the token received in the phNewContext parameter after the first call to this function.
///
///
/// TBD
///
///
/// Bit flags that indicate requests for the context. Not all packages can support all requirements. Flags used for this parameter
/// are prefixed with ISC_REQ_, for example, ISC_REQ_DELEGATE. This parameter can be one or more of the following attributes flags.
///
///
///
/// Value
/// Meaning
///
/// -
/// ISC_REQ_ALLOCATE_MEMORY
///
/// The security package allocates output buffers for you. When you have finished using the output buffers, free them by calling the
/// FreeContextBuffer function.
///
///
/// -
/// ISC_REQ_CONFIDENTIALITY
/// Encrypt messages by using the EncryptMessage function.
///
/// -
/// ISC_REQ_CONNECTION
///
/// The security context will not handle formatting messages. This value is the default for the Kerberos, Negotiate, and NTLM
/// security packages.
///
///
/// -
/// ISC_REQ_DELEGATE
///
/// The server can use the context to authenticate to other servers as the client. The ISC_REQ_MUTUAL_AUTH flag must be set for this
/// flag to work. Valid for Kerberos. Ignore this flag for constrained delegation.
///
///
/// -
/// ISC_REQ_EXTENDED_ERROR
/// When errors occur, the remote party will be notified.
///
/// -
/// ISC_REQ_HTTP
/// Use Digest for HTTP. Omit this flag to use Digest as a SASL mechanism.
///
/// -
/// ISC_REQ_INTEGRITY
/// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions.
///
/// -
/// ISC_REQ_MANUAL_CRED_VALIDATION
/// Schannel must not authenticate the server automatically.
///
/// -
/// ISC_REQ_MUTUAL_AUTH
/// The mutual authentication policy of the service will be satisfied.
///
/// -
/// ISC_REQ_NO_INTEGRITY
///
/// If this flag is set, the ISC_REQ_INTEGRITY flag is ignored. This value is supported only by the Negotiate and Kerberos security packages.
///
///
/// -
/// ISC_REQ_REPLAY_DETECT
/// Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature functions.
///
/// -
/// ISC_REQ_SEQUENCE_DETECT
/// Detect messages received out of sequence.
///
/// -
/// ISC_REQ_STREAM
/// Support a stream-oriented connection.
///
/// -
/// ISC_REQ_USE_SESSION_KEY
/// A new session key must be negotiated. This value is supported only by the Kerberos security package.
///
/// -
/// ISC_REQ_USE_SUPPLIED_CREDS
/// Schannel must not attempt to supply credentials for the client automatically.
///
///
/// The requested attributes may not be supported by the client. For more information, see the pfContextAttr parameter.
/// For further descriptions of the various attributes, see Context Requirements.
///
/// This parameter is reserved and must be set to zero.
///
/// The data representation, such as byte ordering, on the target. This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
/// This parameter is not used with Digest or Schannel. Set it to zero.
///
///
/// A pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. Unless the client
/// context was initiated by the server, the value of this parameter must be NULL on the first call to the function. On
/// subsequent calls to the function or when the client context was initiated by the server, the value of this parameter is a pointer
/// to a buffer allocated with enough memory to hold the token returned by the remote computer.
///
/// This parameter is reserved and must be set to zero.
///
///
/// A pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext (General), this pointer receives the
/// new context handle. On the second call, phNewContext can be the same as the handle specified in the phContext parameter.
///
///
/// When using the Schannel SSP, on calls after the first call, pass the handle returned here as the phContext parameter and specify
/// NULL for phNewContext.
///
///
///
///
/// A pointer to a SecBufferDesc structure that contains pointers to the SecBuffer structure that receives the output data. If a
/// buffer was typed as SEC_READWRITE in the input, it will be there on output. The system will allocate a buffer for the security
/// token if requested (through ISC_REQ_ALLOCATE_MEMORY) and fill in the address in the buffer descriptor for the security token.
///
/// When using the Microsoft Digest SSP, this parameter receives the challenge response that must be sent to the server.
///
/// When using the Schannel SSP, if the ISC_REQ_ALLOCATE_MEMORY flag is specified, the Schannel SSP will allocate memory for the
/// buffer and put the appropriate information in the SecBufferDesc. In addition, the caller must pass in a buffer of type
/// SECBUFFER_ALERT. On output, if an alert is generated, this buffer contains information about that alert, and the function fails.
///
///
///
///
/// A pointer to a variable to receive a set of bit flags that indicate the attributes of the established context. For a description
/// of the various attributes, see Context Requirements.
///
/// Flags used for this parameter are prefixed with ISC_RET, such as ISC_RET_DELEGATE.
/// For a list of valid values, see the fContextReq parameter.
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags that are not
/// related to security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
/// Note Particular context attributes can change during negotiation with a remote peer.
///
///
///
/// A pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security package
/// always return this value in local time. This parameter is optional and NULL should be passed for short-lived clients.
///
/// There is no expiration time for Microsoft Digest SSP security contexts or credentials.
///
///
/// If the function succeeds, the function returns one of the following success codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_I_COMPLETE_AND_CONTINUE
///
/// The client must call CompleteAuthToken and then pass the output to the server. The client then waits for a returned token and
/// passes it, in another call, to InitializeSecurityContext (General).
///
///
/// -
/// SEC_I_COMPLETE_NEEDED
/// The client must finish building the message and then call the CompleteAuthToken function.
///
/// -
/// SEC_I_CONTINUE_NEEDED
///
/// The client must send the output token to the server and wait for a return token. The returned token is then passed in another
/// call to InitializeSecurityContext (General). The output token can be empty.
///
///
/// -
/// SEC_I_INCOMPLETE_CREDENTIALS
///
/// Use with Schannel. The server has requested client authentication, and the supplied credentials either do not include a
/// certificate or the certificate was not issued by a certification authority that is trusted by the server. For more information,
/// see Remarks.
///
///
/// -
/// SEC_E_INCOMPLETE_MESSAGE
///
/// Use with Schannel. Data for the whole message was not read from the wire. When this value is returned, the pInput buffer contains
/// a SecBuffer structure with a BufferType member of SECBUFFER_MISSING. The cbBuffer member of SecBuffer contains a value that
/// indicates the number of additional bytes that the function must read from the client before this function succeeds. While this
/// number is not always accurate, using it can help improve performance by avoiding multiple calls to this function.
///
///
/// -
/// SEC_E_OK
///
/// The security context was successfully initialized. There is no need for another InitializeSecurityContext (General) call. If the
/// function returns an output token, that is, if the SECBUFFER_TOKEN in pOutput is of nonzero length, that token must be sent to the server.
///
///
///
/// If the function fails, the function returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
///
/// The error is due to a malformed input token, such as a token corrupted in transit, a token of incorrect size, or a token passed
/// into the wrong security package. Passing a token to the wrong package can happen if the client and server did not negotiate the
/// proper security package.
///
///
/// -
/// SEC_E_LOGON_DENIED
/// The logon failed.
///
/// -
/// SEC_E_NO_AUTHENTICATING_AUTHORITY
///
/// No authority could be contacted for authentication. The domain name of the authenticating party could be wrong, the domain could
/// be unreachable, or there might have been a trust relationship failure.
///
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_TARGET_UNKNOWN
/// The target was not recognized.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// A context attribute flag that is not valid (ISC_REQ_DELEGATE or ISC_REQ_PROMPT_FOR_CREDS) was specified in the fContextReq parameter.
///
///
/// -
/// SEC_E_WRONG_PRINCIPAL
///
/// The principal that received the authentication request is not the same as the one passed into the pszTargetName parameter. This
/// indicates a failure in mutual authentication.
///
///
///
///
///
///
/// The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality
/// was requested, but could not be established, some applications may choose to shut down the connection immediately.
///
///
/// If attributes of the security context are not sufficient, the client must free the partially created context by calling the
/// DeleteSecurityContext function.
///
/// The InitializeSecurityContext (General) function is used by a client to initialize an outbound context.
/// For a two-leg security context, the calling sequence is as follows:
///
/// -
/// The client calls the function with phContext set to NULL and fills in the buffer descriptor with the input message.
///
/// -
///
/// The security package examines the parameters and constructs an opaque token, placing it in the TOKEN element in the buffer array.
/// If the fContextReq parameter includes the ISC_REQ_ALLOCATE_MEMORY flag, the security package allocates the memory and returns the
/// pointer in the TOKEN element.
///
///
/// -
///
/// The client sends the token returned in the pOutput buffer to the target server. The server then passes the token as an input
/// argument in a call to the AcceptSecurityContext (General) function.
///
///
/// -
///
/// AcceptSecurityContext (General) may return a token, which the server sends to the client for a second call to
/// InitializeSecurityContext (General) if the first call returned SEC_I_CONTINUE_NEEDED.
///
///
///
/// For multiple-leg security contexts, such as mutual authentication, the calling sequence is as follows:
///
/// -
/// The client calls the function as described earlier, but the package returns the SEC_I_CONTINUE_NEEDED success code.
///
/// -
/// The client sends the output token to the server and waits for the server's reply.
///
/// -
///
/// Upon receipt of the server's response, the client calls InitializeSecurityContext (General) again, with phContext set to
/// the handle that was returned from the last call. The token received from the server is supplied in the pInput parameter.
///
///
///
/// If the server has successfully responded, the security package returns SEC_E_OK and a secure session is established.
/// If the function returns one of the error responses, the server's response is not accepted, and the session is not established.
///
/// If the function returns SEC_I_CONTINUE_NEEDED, SEC_I_COMPLETE_NEEDED, or SEC_I_COMPLETE_AND_CONTINUE, steps 2 and 3 are repeated.
///
///
/// To initialize a security context, more than one call to this function may be required, depending on the underlying authentication
/// mechanism as well as the choices specified in the fContextReq parameter.
///
///
/// The fContextReq and pfContextAttributes parameters are bitmasks that represent various context attributes. For a description of
/// the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only
/// on the final successful return should you examine the flags that pertain to security aspects of the context. Intermediate returns
/// can set, for example, the ISC_RET_ALLOCATED_MEMORY flag.
///
///
/// If the ISC_REQ_USE_SUPPLIED_CREDS flag is set, the security package must look for a SECBUFFER_PKG_PARAMS buffer type in the
/// pInput input buffer. This is not a generic solution, but it allows for a strong pairing of security package and application when appropriate.
///
/// If ISC_REQ_ALLOCATE_MEMORY was specified, the caller must free the memory by calling the FreeContextBuffer function.
///
/// For example, the input token could be the challenge from a LAN Manager. In this case, the output token would be the
/// NTLM-encrypted response to the challenge.
///
///
/// The action the client takes depends on the return code from this function. If the return code is SEC_E_OK, there will be no
/// second InitializeSecurityContext (General) call, and no response from the server is expected. If the return code is
/// SEC_I_CONTINUE_NEEDED, the client expects a token in response from the server and passes it in a second call to
/// InitializeSecurityContext (General). The SEC_I_COMPLETE_NEEDED return code indicates that the client must finish building
/// the message and call the CompleteAuthToken function. The SEC_I_COMPLETE_AND_CONTINUE code incorporates both of these actions.
///
///
/// If InitializeSecurityContext (General) returns success on the first (or only) call, then the caller must eventually call
/// the DeleteSecurityContext function on the returned handle, even if the call fails on a later leg of the authentication exchange.
///
///
/// The client may call InitializeSecurityContext (General) again after it has completed successfully. This indicates to the
/// security package that a reauthentication is wanted.
///
///
/// Kernel mode callers have the following differences: the target name is a Unicode string that must be allocated in virtual memory
/// by using VirtualAlloc; it must not be allocated from the pool. Buffers passed and supplied in pInput and pOutput must be in
/// virtual memory, not in the pool.
///
///
/// When using the Schannel SSP, if the function returns SEC_I_INCOMPLETE_CREDENTIALS, check that you specified a valid and trusted
/// certificate in your credentials. The certificate is specified when calling the AcquireCredentialsHandle (General) function. The
/// certificate must be a client authentication certificate issued by a certification authority (CA) trusted by the server. To obtain
/// a list of the CAs trusted by the server, call the QueryContextAttributes (General) function and specify the
/// SECPKG_ATTR_ISSUER_LIST_EX attribute.
///
///
/// When using the Schannel SSP, after a client application receives an authentication certificate from a CA that is trusted by the
/// server, the application creates a new credential by calling the AcquireCredentialsHandle (General) function and then calling
/// InitializeSecurityContext (General) again, specifying the new credential in the phCredential parameter.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-initializesecuritycontexta SECURITY_STATUS SEC_ENTRY
// InitializeSecurityContextA( PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, unsigned long fContextReq,
// unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext,
// PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "21d965d4-3c03-4e29-a70d-4538c5c366b0")]
public static unsafe extern HRESULT InitializeSecurityContext([In, Optional] CredHandle* phCredential, [In, Optional] CtxtHandle* phContext, [Optional] string pszTargetName, ASC_REQ fContextReq, [Optional] uint Reserved1, DREP TargetDataRep,
[In, Optional] SecBufferDesc* pInput, [Optional] uint Reserved2, ref CtxtHandle phNewContext, [Optional] SecBufferDesc* pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsExpiry);
///
///
/// The InitializeSecurityContext (General) function initiates the client side, outbound security context from a credential
/// handle. The function is used to build a security context between the client application and a remote peer.
/// InitializeSecurityContext (General) returns a token that the client must pass to the remote peer, which the peer in turn
/// submits to the local security implementation through the AcceptSecurityContext (General) call. The token generated should be
/// considered opaque by all callers.
///
///
/// Typically, the InitializeSecurityContext (General) function is called in a loop until a sufficient security context is established.
///
/// For information about using this function with a specific security support provider (SSP), see the following topics.
///
///
/// Topic
/// Description
///
/// -
/// InitializeSecurityContext (CredSSP)
///
/// Initiates the client side, outbound security context from a credential handle by using the Credential Security Support Provider (CredSSP).
///
///
/// -
/// InitializeSecurityContext (Digest)
/// Initiates the client side, outbound security context from a credential handle by using the Digest security package.
///
/// -
/// InitializeSecurityContext (Kerberos)
/// Initiates the client side, outbound security context from a credential handle by using the Kerberos security package.
///
/// -
/// InitializeSecurityContext (Negotiate)
/// Initiates the client side, outbound security context from a credential handle by using the Negotiate security package.
///
/// -
/// InitializeSecurityContext (NTLM)
/// Initiates the client side, outbound security context from a credential handle by using the NTLM security package.
///
/// -
/// InitializeSecurityContext (Schannel)
/// Initiates the client side, outbound security context from a credential handle by using the Schannel security package.
///
///
///
///
/// A handle to the credentials returned by AcquireCredentialsHandle (General). This handle is used to build the security context.
/// The InitializeSecurityContext (General) function requires at least OUTBOUND credentials.
///
///
///
/// A pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext (General), this pointer is
/// NULL. On the second call, this parameter is a pointer to the handle to the partially formed context returned in the
/// phNewContext parameter by the first call.
///
/// This parameter is optional with the Microsoft Digest SSP and can be set to NULL.
///
/// When using the Schannel SSP, on the first call to InitializeSecurityContext (General), specify NULL. On future
/// calls, specify the token received in the phNewContext parameter after the first call to this function.
///
///
/// TBD
///
///
/// Bit flags that indicate requests for the context. Not all packages can support all requirements. Flags used for this parameter
/// are prefixed with ISC_REQ_, for example, ISC_REQ_DELEGATE. This parameter can be one or more of the following attributes flags.
///
///
///
/// Value
/// Meaning
///
/// -
/// ISC_REQ_ALLOCATE_MEMORY
///
/// The security package allocates output buffers for you. When you have finished using the output buffers, free them by calling the
/// FreeContextBuffer function.
///
///
/// -
/// ISC_REQ_CONFIDENTIALITY
/// Encrypt messages by using the EncryptMessage function.
///
/// -
/// ISC_REQ_CONNECTION
///
/// The security context will not handle formatting messages. This value is the default for the Kerberos, Negotiate, and NTLM
/// security packages.
///
///
/// -
/// ISC_REQ_DELEGATE
///
/// The server can use the context to authenticate to other servers as the client. The ISC_REQ_MUTUAL_AUTH flag must be set for this
/// flag to work. Valid for Kerberos. Ignore this flag for constrained delegation.
///
///
/// -
/// ISC_REQ_EXTENDED_ERROR
/// When errors occur, the remote party will be notified.
///
/// -
/// ISC_REQ_HTTP
/// Use Digest for HTTP. Omit this flag to use Digest as a SASL mechanism.
///
/// -
/// ISC_REQ_INTEGRITY
/// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions.
///
/// -
/// ISC_REQ_MANUAL_CRED_VALIDATION
/// Schannel must not authenticate the server automatically.
///
/// -
/// ISC_REQ_MUTUAL_AUTH
/// The mutual authentication policy of the service will be satisfied.
///
/// -
/// ISC_REQ_NO_INTEGRITY
///
/// If this flag is set, the ISC_REQ_INTEGRITY flag is ignored. This value is supported only by the Negotiate and Kerberos security packages.
///
///
/// -
/// ISC_REQ_REPLAY_DETECT
/// Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature functions.
///
/// -
/// ISC_REQ_SEQUENCE_DETECT
/// Detect messages received out of sequence.
///
/// -
/// ISC_REQ_STREAM
/// Support a stream-oriented connection.
///
/// -
/// ISC_REQ_USE_SESSION_KEY
/// A new session key must be negotiated. This value is supported only by the Kerberos security package.
///
/// -
/// ISC_REQ_USE_SUPPLIED_CREDS
/// Schannel must not attempt to supply credentials for the client automatically.
///
///
/// The requested attributes may not be supported by the client. For more information, see the pfContextAttr parameter.
/// For further descriptions of the various attributes, see Context Requirements.
///
/// This parameter is reserved and must be set to zero.
///
/// The data representation, such as byte ordering, on the target. This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
/// This parameter is not used with Digest or Schannel. Set it to zero.
///
///
/// A pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. Unless the client
/// context was initiated by the server, the value of this parameter must be NULL on the first call to the function. On
/// subsequent calls to the function or when the client context was initiated by the server, the value of this parameter is a pointer
/// to a buffer allocated with enough memory to hold the token returned by the remote computer.
///
/// This parameter is reserved and must be set to zero.
///
///
/// A pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext (General), this pointer receives the
/// new context handle. On the second call, phNewContext can be the same as the handle specified in the phContext parameter.
///
///
/// When using the Schannel SSP, on calls after the first call, pass the handle returned here as the phContext parameter and specify
/// NULL for phNewContext.
///
///
///
///
/// A pointer to a SecBufferDesc structure that contains pointers to the SecBuffer structure that receives the output data. If a
/// buffer was typed as SEC_READWRITE in the input, it will be there on output. The system will allocate a buffer for the security
/// token if requested (through ISC_REQ_ALLOCATE_MEMORY) and fill in the address in the buffer descriptor for the security token.
///
/// When using the Microsoft Digest SSP, this parameter receives the challenge response that must be sent to the server.
///
/// When using the Schannel SSP, if the ISC_REQ_ALLOCATE_MEMORY flag is specified, the Schannel SSP will allocate memory for the
/// buffer and put the appropriate information in the SecBufferDesc. In addition, the caller must pass in a buffer of type
/// SECBUFFER_ALERT. On output, if an alert is generated, this buffer contains information about that alert, and the function fails.
///
///
///
///
/// A pointer to a variable to receive a set of bit flags that indicate the attributes of the established context. For a description
/// of the various attributes, see Context Requirements.
///
/// Flags used for this parameter are prefixed with ISC_RET, such as ISC_RET_DELEGATE.
/// For a list of valid values, see the fContextReq parameter.
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags that are not
/// related to security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
/// Note Particular context attributes can change during negotiation with a remote peer.
///
///
///
/// A pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security package
/// always return this value in local time. This parameter is optional and NULL should be passed for short-lived clients.
///
/// There is no expiration time for Microsoft Digest SSP security contexts or credentials.
///
///
/// If the function succeeds, the function returns one of the following success codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_I_COMPLETE_AND_CONTINUE
///
/// The client must call CompleteAuthToken and then pass the output to the server. The client then waits for a returned token and
/// passes it, in another call, to InitializeSecurityContext (General).
///
///
/// -
/// SEC_I_COMPLETE_NEEDED
/// The client must finish building the message and then call the CompleteAuthToken function.
///
/// -
/// SEC_I_CONTINUE_NEEDED
///
/// The client must send the output token to the server and wait for a return token. The returned token is then passed in another
/// call to InitializeSecurityContext (General). The output token can be empty.
///
///
/// -
/// SEC_I_INCOMPLETE_CREDENTIALS
///
/// Use with Schannel. The server has requested client authentication, and the supplied credentials either do not include a
/// certificate or the certificate was not issued by a certification authority that is trusted by the server. For more information,
/// see Remarks.
///
///
/// -
/// SEC_E_INCOMPLETE_MESSAGE
///
/// Use with Schannel. Data for the whole message was not read from the wire. When this value is returned, the pInput buffer contains
/// a SecBuffer structure with a BufferType member of SECBUFFER_MISSING. The cbBuffer member of SecBuffer contains a value that
/// indicates the number of additional bytes that the function must read from the client before this function succeeds. While this
/// number is not always accurate, using it can help improve performance by avoiding multiple calls to this function.
///
///
/// -
/// SEC_E_OK
///
/// The security context was successfully initialized. There is no need for another InitializeSecurityContext (General) call. If the
/// function returns an output token, that is, if the SECBUFFER_TOKEN in pOutput is of nonzero length, that token must be sent to the server.
///
///
///
/// If the function fails, the function returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
///
/// The error is due to a malformed input token, such as a token corrupted in transit, a token of incorrect size, or a token passed
/// into the wrong security package. Passing a token to the wrong package can happen if the client and server did not negotiate the
/// proper security package.
///
///
/// -
/// SEC_E_LOGON_DENIED
/// The logon failed.
///
/// -
/// SEC_E_NO_AUTHENTICATING_AUTHORITY
///
/// No authority could be contacted for authentication. The domain name of the authenticating party could be wrong, the domain could
/// be unreachable, or there might have been a trust relationship failure.
///
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_TARGET_UNKNOWN
/// The target was not recognized.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// A context attribute flag that is not valid (ISC_REQ_DELEGATE or ISC_REQ_PROMPT_FOR_CREDS) was specified in the fContextReq parameter.
///
///
/// -
/// SEC_E_WRONG_PRINCIPAL
///
/// The principal that received the authentication request is not the same as the one passed into the pszTargetName parameter. This
/// indicates a failure in mutual authentication.
///
///
///
///
///
///
/// The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality
/// was requested, but could not be established, some applications may choose to shut down the connection immediately.
///
///
/// If attributes of the security context are not sufficient, the client must free the partially created context by calling the
/// DeleteSecurityContext function.
///
/// The InitializeSecurityContext (General) function is used by a client to initialize an outbound context.
/// For a two-leg security context, the calling sequence is as follows:
///
/// -
/// The client calls the function with phContext set to NULL and fills in the buffer descriptor with the input message.
///
/// -
///
/// The security package examines the parameters and constructs an opaque token, placing it in the TOKEN element in the buffer array.
/// If the fContextReq parameter includes the ISC_REQ_ALLOCATE_MEMORY flag, the security package allocates the memory and returns the
/// pointer in the TOKEN element.
///
///
/// -
///
/// The client sends the token returned in the pOutput buffer to the target server. The server then passes the token as an input
/// argument in a call to the AcceptSecurityContext (General) function.
///
///
/// -
///
/// AcceptSecurityContext (General) may return a token, which the server sends to the client for a second call to
/// InitializeSecurityContext (General) if the first call returned SEC_I_CONTINUE_NEEDED.
///
///
///
/// For multiple-leg security contexts, such as mutual authentication, the calling sequence is as follows:
///
/// -
/// The client calls the function as described earlier, but the package returns the SEC_I_CONTINUE_NEEDED success code.
///
/// -
/// The client sends the output token to the server and waits for the server's reply.
///
/// -
///
/// Upon receipt of the server's response, the client calls InitializeSecurityContext (General) again, with phContext set to
/// the handle that was returned from the last call. The token received from the server is supplied in the pInput parameter.
///
///
///
/// If the server has successfully responded, the security package returns SEC_E_OK and a secure session is established.
/// If the function returns one of the error responses, the server's response is not accepted, and the session is not established.
///
/// If the function returns SEC_I_CONTINUE_NEEDED, SEC_I_COMPLETE_NEEDED, or SEC_I_COMPLETE_AND_CONTINUE, steps 2 and 3 are repeated.
///
///
/// To initialize a security context, more than one call to this function may be required, depending on the underlying authentication
/// mechanism as well as the choices specified in the fContextReq parameter.
///
///
/// The fContextReq and pfContextAttributes parameters are bitmasks that represent various context attributes. For a description of
/// the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only
/// on the final successful return should you examine the flags that pertain to security aspects of the context. Intermediate returns
/// can set, for example, the ISC_RET_ALLOCATED_MEMORY flag.
///
///
/// If the ISC_REQ_USE_SUPPLIED_CREDS flag is set, the security package must look for a SECBUFFER_PKG_PARAMS buffer type in the
/// pInput input buffer. This is not a generic solution, but it allows for a strong pairing of security package and application when appropriate.
///
/// If ISC_REQ_ALLOCATE_MEMORY was specified, the caller must free the memory by calling the FreeContextBuffer function.
///
/// For example, the input token could be the challenge from a LAN Manager. In this case, the output token would be the
/// NTLM-encrypted response to the challenge.
///
///
/// The action the client takes depends on the return code from this function. If the return code is SEC_E_OK, there will be no
/// second InitializeSecurityContext (General) call, and no response from the server is expected. If the return code is
/// SEC_I_CONTINUE_NEEDED, the client expects a token in response from the server and passes it in a second call to
/// InitializeSecurityContext (General). The SEC_I_COMPLETE_NEEDED return code indicates that the client must finish building
/// the message and call the CompleteAuthToken function. The SEC_I_COMPLETE_AND_CONTINUE code incorporates both of these actions.
///
///
/// If InitializeSecurityContext (General) returns success on the first (or only) call, then the caller must eventually call
/// the DeleteSecurityContext function on the returned handle, even if the call fails on a later leg of the authentication exchange.
///
///
/// The client may call InitializeSecurityContext (General) again after it has completed successfully. This indicates to the
/// security package that a reauthentication is wanted.
///
///
/// Kernel mode callers have the following differences: the target name is a Unicode string that must be allocated in virtual memory
/// by using VirtualAlloc; it must not be allocated from the pool. Buffers passed and supplied in pInput and pOutput must be in
/// virtual memory, not in the pool.
///
///
/// When using the Schannel SSP, if the function returns SEC_I_INCOMPLETE_CREDENTIALS, check that you specified a valid and trusted
/// certificate in your credentials. The certificate is specified when calling the AcquireCredentialsHandle (General) function. The
/// certificate must be a client authentication certificate issued by a certification authority (CA) trusted by the server. To obtain
/// a list of the CAs trusted by the server, call the QueryContextAttributes (General) function and specify the
/// SECPKG_ATTR_ISSUER_LIST_EX attribute.
///
///
/// When using the Schannel SSP, after a client application receives an authentication certificate from a CA that is trusted by the
/// server, the application creates a new credential by calling the AcquireCredentialsHandle (General) function and then calling
/// InitializeSecurityContext (General) again, specifying the new credential in the phCredential parameter.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-initializesecuritycontexta SECURITY_STATUS SEC_ENTRY
// InitializeSecurityContextA( PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, unsigned long fContextReq,
// unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext,
// PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "21d965d4-3c03-4e29-a70d-4538c5c366b0")]
public static extern HRESULT InitializeSecurityContext(in CredHandle phCredential, [In, Optional] IntPtr phContext, string pszTargetName, [In] ASC_REQ fContextReq, [Optional] int Reserved1, [In] DREP TargetDataRep,
[In, Optional] IntPtr pInput, [Optional] int Reserved2, ref CtxtHandle phNewContext, ref SecBufferDesc pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsExpiry);
///
///
/// The InitializeSecurityContext (General) function initiates the client side, outbound security context from a credential
/// handle. The function is used to build a security context between the client application and a remote peer.
/// InitializeSecurityContext (General) returns a token that the client must pass to the remote peer, which the peer in turn
/// submits to the local security implementation through the AcceptSecurityContext (General) call. The token generated should be
/// considered opaque by all callers.
///
///
/// Typically, the InitializeSecurityContext (General) function is called in a loop until a sufficient security context is established.
///
/// For information about using this function with a specific security support provider (SSP), see the following topics.
///
///
/// Topic
/// Description
///
/// -
/// InitializeSecurityContext (CredSSP)
///
/// Initiates the client side, outbound security context from a credential handle by using the Credential Security Support Provider (CredSSP).
///
///
/// -
/// InitializeSecurityContext (Digest)
/// Initiates the client side, outbound security context from a credential handle by using the Digest security package.
///
/// -
/// InitializeSecurityContext (Kerberos)
/// Initiates the client side, outbound security context from a credential handle by using the Kerberos security package.
///
/// -
/// InitializeSecurityContext (Negotiate)
/// Initiates the client side, outbound security context from a credential handle by using the Negotiate security package.
///
/// -
/// InitializeSecurityContext (NTLM)
/// Initiates the client side, outbound security context from a credential handle by using the NTLM security package.
///
/// -
/// InitializeSecurityContext (Schannel)
/// Initiates the client side, outbound security context from a credential handle by using the Schannel security package.
///
///
///
/// A handle to the credentials returned by AcquireCredentialsHandle (General). This handle is used to build the security context.
/// The InitializeSecurityContext (General) function requires at least OUTBOUND credentials.
///
/// A pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext (General), this pointer is
/// NULL. On the second call, this parameter is a pointer to the handle to the partially formed context returned in the
/// phNewContext parameter by the first call.
///
/// This parameter is optional with the Microsoft Digest SSP and can be set to NULL.
///
/// When using the Schannel SSP, on the first call to InitializeSecurityContext (General), specify NULL. On future
/// calls, specify the token received in the phNewContext parameter after the first call to this function.
///
/// TBD
///
/// Bit flags that indicate requests for the context. Not all packages can support all requirements. Flags used for this parameter
/// are prefixed with ISC_REQ_, for example, ISC_REQ_DELEGATE. This parameter can be one or more of the following attributes flags.
///
///
///
/// Value
/// Meaning
///
/// -
/// ISC_REQ_ALLOCATE_MEMORY
///
/// The security package allocates output buffers for you. When you have finished using the output buffers, free them by calling the
/// FreeContextBuffer function.
///
///
/// -
/// ISC_REQ_CONFIDENTIALITY
/// Encrypt messages by using the EncryptMessage function.
///
/// -
/// ISC_REQ_CONNECTION
///
/// The security context will not handle formatting messages. This value is the default for the Kerberos, Negotiate, and NTLM
/// security packages.
///
///
/// -
/// ISC_REQ_DELEGATE
///
/// The server can use the context to authenticate to other servers as the client. The ISC_REQ_MUTUAL_AUTH flag must be set for this
/// flag to work. Valid for Kerberos. Ignore this flag for constrained delegation.
///
///
/// -
/// ISC_REQ_EXTENDED_ERROR
/// When errors occur, the remote party will be notified.
///
/// -
/// ISC_REQ_HTTP
/// Use Digest for HTTP. Omit this flag to use Digest as a SASL mechanism.
///
/// -
/// ISC_REQ_INTEGRITY
/// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions.
///
/// -
/// ISC_REQ_MANUAL_CRED_VALIDATION
/// Schannel must not authenticate the server automatically.
///
/// -
/// ISC_REQ_MUTUAL_AUTH
/// The mutual authentication policy of the service will be satisfied.
///
/// -
/// ISC_REQ_NO_INTEGRITY
///
/// If this flag is set, the ISC_REQ_INTEGRITY flag is ignored. This value is supported only by the Negotiate and Kerberos security packages.
///
///
/// -
/// ISC_REQ_REPLAY_DETECT
/// Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature functions.
///
/// -
/// ISC_REQ_SEQUENCE_DETECT
/// Detect messages received out of sequence.
///
/// -
/// ISC_REQ_STREAM
/// Support a stream-oriented connection.
///
/// -
/// ISC_REQ_USE_SESSION_KEY
/// A new session key must be negotiated. This value is supported only by the Kerberos security package.
///
/// -
/// ISC_REQ_USE_SUPPLIED_CREDS
/// Schannel must not attempt to supply credentials for the client automatically.
///
///
/// The requested attributes may not be supported by the client. For more information, see the pfContextAttr parameter.
/// For further descriptions of the various attributes, see Context Requirements.
/// The data representation, such as byte ordering, on the target. This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
/// This parameter is not used with Digest or Schannel. Set it to zero.
/// A pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. Unless the client
/// context was initiated by the server, the value of this parameter must be NULL on the first call to the function. On
/// subsequent calls to the function or when the client context was initiated by the server, the value of this parameter is a pointer
/// to a buffer allocated with enough memory to hold the token returned by the remote computer.
/// Type of the output.
///
/// A pointer to a SecBufferDesc structure that contains pointers to the SecBuffer structure that receives the output data. If a
/// buffer was typed as SEC_READWRITE in the input, it will be there on output. The system will allocate a buffer for the security
/// token if requested (through ISC_REQ_ALLOCATE_MEMORY) and fill in the address in the buffer descriptor for the security token.
///
/// When using the Microsoft Digest SSP, this parameter receives the challenge response that must be sent to the server.
///
/// When using the Schannel SSP, if the ISC_REQ_ALLOCATE_MEMORY flag is specified, the Schannel SSP will allocate memory for the
/// buffer and put the appropriate information in the SecBufferDesc. In addition, the caller must pass in a buffer of type
/// SECBUFFER_ALERT. On output, if an alert is generated, this buffer contains information about that alert, and the function fails.
///
///
/// A pointer to a variable to receive a set of bit flags that indicate the attributes of the established context. For a description
/// of the various attributes, see Context Requirements.
///
/// Flags used for this parameter are prefixed with ISC_RET, such as ISC_RET_DELEGATE.
/// For a list of valid values, see the fContextReq parameter.
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags that are not
/// related to security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
///
/// Note Particular context attributes can change during negotiation with a remote peer.
///
/// A pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security package
/// always return this value in local time. This parameter is optional and NULL should be passed for short-lived clients.
///
/// There is no expiration time for Microsoft Digest SSP security contexts or credentials.
///
/// If the function succeeds, the function returns one of the following success codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_I_COMPLETE_AND_CONTINUE
///
/// The client must call CompleteAuthToken and then pass the output to the server. The client then waits for a returned token and
/// passes it, in another call, to InitializeSecurityContext (General).
///
///
/// -
/// SEC_I_COMPLETE_NEEDED
/// The client must finish building the message and then call the CompleteAuthToken function.
///
/// -
/// SEC_I_CONTINUE_NEEDED
///
/// The client must send the output token to the server and wait for a return token. The returned token is then passed in another
/// call to InitializeSecurityContext (General). The output token can be empty.
///
///
/// -
/// SEC_I_INCOMPLETE_CREDENTIALS
///
/// Use with Schannel. The server has requested client authentication, and the supplied credentials either do not include a
/// certificate or the certificate was not issued by a certification authority that is trusted by the server. For more information,
/// see Remarks.
///
///
/// -
/// SEC_E_INCOMPLETE_MESSAGE
///
/// Use with Schannel. Data for the whole message was not read from the wire. When this value is returned, the pInput buffer contains
/// a SecBuffer structure with a BufferType member of SECBUFFER_MISSING. The cbBuffer member of SecBuffer contains a value that
/// indicates the number of additional bytes that the function must read from the client before this function succeeds. While this
/// number is not always accurate, using it can help improve performance by avoiding multiple calls to this function.
///
///
/// -
/// SEC_E_OK
///
/// The security context was successfully initialized. There is no need for another InitializeSecurityContext (General) call. If the
/// function returns an output token, that is, if the SECBUFFER_TOKEN in pOutput is of nonzero length, that token must be sent to the server.
///
///
///
/// If the function fails, the function returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
///
/// The error is due to a malformed input token, such as a token corrupted in transit, a token of incorrect size, or a token passed
/// into the wrong security package. Passing a token to the wrong package can happen if the client and server did not negotiate the
/// proper security package.
///
///
/// -
/// SEC_E_LOGON_DENIED
/// The logon failed.
///
/// -
/// SEC_E_NO_AUTHENTICATING_AUTHORITY
///
/// No authority could be contacted for authentication. The domain name of the authenticating party could be wrong, the domain could
/// be unreachable, or there might have been a trust relationship failure.
///
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_TARGET_UNKNOWN
/// The target was not recognized.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// A context attribute flag that is not valid (ISC_REQ_DELEGATE or ISC_REQ_PROMPT_FOR_CREDS) was specified in the fContextReq parameter.
///
///
/// -
/// SEC_E_WRONG_PRINCIPAL
///
/// The principal that received the authentication request is not the same as the one passed into the pszTargetName parameter. This
/// indicates a failure in mutual authentication.
///
///
///
///
///
///
/// The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality
/// was requested, but could not be established, some applications may choose to shut down the connection immediately.
///
///
/// If attributes of the security context are not sufficient, the client must free the partially created context by calling the
/// DeleteSecurityContext function.
///
/// The InitializeSecurityContext (General) function is used by a client to initialize an outbound context.
/// For a two-leg security context, the calling sequence is as follows:
///
/// -
/// The client calls the function with phContext set to NULL and fills in the buffer descriptor with the input message.
///
/// -
///
/// The security package examines the parameters and constructs an opaque token, placing it in the TOKEN element in the buffer array.
/// If the fContextReq parameter includes the ISC_REQ_ALLOCATE_MEMORY flag, the security package allocates the memory and returns the
/// pointer in the TOKEN element.
///
///
/// -
///
/// The client sends the token returned in the pOutput buffer to the target server. The server then passes the token as an input
/// argument in a call to the AcceptSecurityContext (General) function.
///
///
/// -
///
/// AcceptSecurityContext (General) may return a token, which the server sends to the client for a second call to
/// InitializeSecurityContext (General) if the first call returned SEC_I_CONTINUE_NEEDED.
///
///
///
/// For multiple-leg security contexts, such as mutual authentication, the calling sequence is as follows:
///
/// -
/// The client calls the function as described earlier, but the package returns the SEC_I_CONTINUE_NEEDED success code.
///
/// -
/// The client sends the output token to the server and waits for the server's reply.
///
/// -
///
/// Upon receipt of the server's response, the client calls InitializeSecurityContext (General) again, with phContext set to
/// the handle that was returned from the last call. The token received from the server is supplied in the pInput parameter.
///
///
///
/// If the server has successfully responded, the security package returns SEC_E_OK and a secure session is established.
/// If the function returns one of the error responses, the server's response is not accepted, and the session is not established.
///
/// If the function returns SEC_I_CONTINUE_NEEDED, SEC_I_COMPLETE_NEEDED, or SEC_I_COMPLETE_AND_CONTINUE, steps 2 and 3 are repeated.
///
///
/// To initialize a security context, more than one call to this function may be required, depending on the underlying authentication
/// mechanism as well as the choices specified in the fContextReq parameter.
///
///
/// The fContextReq and pfContextAttributes parameters are bitmasks that represent various context attributes. For a description of
/// the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only
/// on the final successful return should you examine the flags that pertain to security aspects of the context. Intermediate returns
/// can set, for example, the ISC_RET_ALLOCATED_MEMORY flag.
///
///
/// If the ISC_REQ_USE_SUPPLIED_CREDS flag is set, the security package must look for a SECBUFFER_PKG_PARAMS buffer type in the
/// pInput input buffer. This is not a generic solution, but it allows for a strong pairing of security package and application when appropriate.
///
/// If ISC_REQ_ALLOCATE_MEMORY was specified, the caller must free the memory by calling the FreeContextBuffer function.
///
/// For example, the input token could be the challenge from a LAN Manager. In this case, the output token would be the
/// NTLM-encrypted response to the challenge.
///
///
/// The action the client takes depends on the return code from this function. If the return code is SEC_E_OK, there will be no
/// second InitializeSecurityContext (General) call, and no response from the server is expected. If the return code is
/// SEC_I_CONTINUE_NEEDED, the client expects a token in response from the server and passes it in a second call to
/// InitializeSecurityContext (General). The SEC_I_COMPLETE_NEEDED return code indicates that the client must finish building
/// the message and call the CompleteAuthToken function. The SEC_I_COMPLETE_AND_CONTINUE code incorporates both of these actions.
///
///
/// If InitializeSecurityContext (General) returns success on the first (or only) call, then the caller must eventually call
/// the DeleteSecurityContext function on the returned handle, even if the call fails on a later leg of the authentication exchange.
///
///
/// The client may call InitializeSecurityContext (General) again after it has completed successfully. This indicates to the
/// security package that a reauthentication is wanted.
///
///
/// Kernel mode callers have the following differences: the target name is a Unicode string that must be allocated in virtual memory
/// by using VirtualAlloc; it must not be allocated from the pool. Buffers passed and supplied in pInput and pOutput must be in
/// virtual memory, not in the pool.
///
///
/// When using the Schannel SSP, if the function returns SEC_I_INCOMPLETE_CREDENTIALS, check that you specified a valid and trusted
/// certificate in your credentials. The certificate is specified when calling the AcquireCredentialsHandle (General) function. The
/// certificate must be a client authentication certificate issued by a certification authority (CA) trusted by the server. To obtain
/// a list of the CAs trusted by the server, call the QueryContextAttributes (General) function and specify the
/// SECPKG_ATTR_ISSUER_LIST_EX attribute.
///
///
/// When using the Schannel SSP, after a client application receives an authentication certificate from a CA that is trusted by the
/// server, the application creates a new credential by calling the AcquireCredentialsHandle (General) function and then calling
/// InitializeSecurityContext (General) again, specifying the new credential in the phCredential parameter.
///
///
public static HRESULT InitializeSecurityContext(in CredHandle phCredential, [In, Out] SafeCtxtHandle phContext, string pszTargetName, ASC_REQ fContextReq, DREP TargetDataRep,
[In, Optional] SecBufferDesc? pInput, SecBufferType outputType, out SafeSecBufferDesc pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsExpiry)
{
pOutput = new SafeSecBufferDesc(outputType);
return InitializeSecurityContext(phCredential, phContext, pszTargetName, fContextReq, TargetDataRep, pInput, pOutput, out pfContextAttr, out ptsExpiry);
}
///
///
/// The InitializeSecurityContext (General) function initiates the client side, outbound security context from a credential
/// handle. The function is used to build a security context between the client application and a remote peer.
/// InitializeSecurityContext (General) returns a token that the client must pass to the remote peer, which the peer in turn
/// submits to the local security implementation through the AcceptSecurityContext (General) call. The token generated should be
/// considered opaque by all callers.
///
///
/// Typically, the InitializeSecurityContext (General) function is called in a loop until a sufficient security context is established.
///
/// For information about using this function with a specific security support provider (SSP), see the following topics.
///
///
/// Topic
/// Description
///
/// -
/// InitializeSecurityContext (CredSSP)
///
/// Initiates the client side, outbound security context from a credential handle by using the Credential Security Support Provider (CredSSP).
///
///
/// -
/// InitializeSecurityContext (Digest)
/// Initiates the client side, outbound security context from a credential handle by using the Digest security package.
///
/// -
/// InitializeSecurityContext (Kerberos)
/// Initiates the client side, outbound security context from a credential handle by using the Kerberos security package.
///
/// -
/// InitializeSecurityContext (Negotiate)
/// Initiates the client side, outbound security context from a credential handle by using the Negotiate security package.
///
/// -
/// InitializeSecurityContext (NTLM)
/// Initiates the client side, outbound security context from a credential handle by using the NTLM security package.
///
/// -
/// InitializeSecurityContext (Schannel)
/// Initiates the client side, outbound security context from a credential handle by using the Schannel security package.
///
///
///
/// A handle to the credentials returned by AcquireCredentialsHandle (General). This handle is used to build the security context.
/// The InitializeSecurityContext (General) function requires at least OUTBOUND credentials.
///
/// A pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext (General), this pointer is
/// NULL. On the second call, this parameter is a pointer to the handle to the partially formed context returned in the
/// phNewContext parameter by the first call.
///
/// This parameter is optional with the Microsoft Digest SSP and can be set to NULL.
///
/// When using the Schannel SSP, on the first call to InitializeSecurityContext (General), specify NULL. On future
/// calls, specify the token received in the phNewContext parameter after the first call to this function.
///
/// TBD
///
/// Bit flags that indicate requests for the context. Not all packages can support all requirements. Flags used for this parameter
/// are prefixed with ISC_REQ_, for example, ISC_REQ_DELEGATE. This parameter can be one or more of the following attributes flags.
///
///
///
/// Value
/// Meaning
///
/// -
/// ISC_REQ_ALLOCATE_MEMORY
///
/// The security package allocates output buffers for you. When you have finished using the output buffers, free them by calling the
/// FreeContextBuffer function.
///
///
/// -
/// ISC_REQ_CONFIDENTIALITY
/// Encrypt messages by using the EncryptMessage function.
///
/// -
/// ISC_REQ_CONNECTION
///
/// The security context will not handle formatting messages. This value is the default for the Kerberos, Negotiate, and NTLM
/// security packages.
///
///
/// -
/// ISC_REQ_DELEGATE
///
/// The server can use the context to authenticate to other servers as the client. The ISC_REQ_MUTUAL_AUTH flag must be set for this
/// flag to work. Valid for Kerberos. Ignore this flag for constrained delegation.
///
///
/// -
/// ISC_REQ_EXTENDED_ERROR
/// When errors occur, the remote party will be notified.
///
/// -
/// ISC_REQ_HTTP
/// Use Digest for HTTP. Omit this flag to use Digest as a SASL mechanism.
///
/// -
/// ISC_REQ_INTEGRITY
/// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions.
///
/// -
/// ISC_REQ_MANUAL_CRED_VALIDATION
/// Schannel must not authenticate the server automatically.
///
/// -
/// ISC_REQ_MUTUAL_AUTH
/// The mutual authentication policy of the service will be satisfied.
///
/// -
/// ISC_REQ_NO_INTEGRITY
///
/// If this flag is set, the ISC_REQ_INTEGRITY flag is ignored. This value is supported only by the Negotiate and Kerberos security packages.
///
///
/// -
/// ISC_REQ_REPLAY_DETECT
/// Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature functions.
///
/// -
/// ISC_REQ_SEQUENCE_DETECT
/// Detect messages received out of sequence.
///
/// -
/// ISC_REQ_STREAM
/// Support a stream-oriented connection.
///
/// -
/// ISC_REQ_USE_SESSION_KEY
/// A new session key must be negotiated. This value is supported only by the Kerberos security package.
///
/// -
/// ISC_REQ_USE_SUPPLIED_CREDS
/// Schannel must not attempt to supply credentials for the client automatically.
///
///
/// The requested attributes may not be supported by the client. For more information, see the pfContextAttr parameter.
/// For further descriptions of the various attributes, see Context Requirements.
/// The data representation, such as byte ordering, on the target. This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
/// This parameter is not used with Digest or Schannel. Set it to zero.
/// A pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. Unless the client
/// context was initiated by the server, the value of this parameter must be NULL on the first call to the function. On
/// subsequent calls to the function or when the client context was initiated by the server, the value of this parameter is a pointer
/// to a buffer allocated with enough memory to hold the token returned by the remote computer.
///
/// A pointer to a SecBufferDesc structure that contains pointers to the SecBuffer structure that receives the output data. If a
/// buffer was typed as SEC_READWRITE in the input, it will be there on output. The system will allocate a buffer for the security
/// token if requested (through ISC_REQ_ALLOCATE_MEMORY) and fill in the address in the buffer descriptor for the security token.
///
/// When using the Microsoft Digest SSP, this parameter receives the challenge response that must be sent to the server.
///
/// When using the Schannel SSP, if the ISC_REQ_ALLOCATE_MEMORY flag is specified, the Schannel SSP will allocate memory for the
/// buffer and put the appropriate information in the SecBufferDesc. In addition, the caller must pass in a buffer of type
/// SECBUFFER_ALERT. On output, if an alert is generated, this buffer contains information about that alert, and the function fails.
///
///
/// A pointer to a variable to receive a set of bit flags that indicate the attributes of the established context. For a description
/// of the various attributes, see Context Requirements.
///
/// Flags used for this parameter are prefixed with ISC_RET, such as ISC_RET_DELEGATE.
/// For a list of valid values, see the fContextReq parameter.
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags that are not
/// related to security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
///
/// Note Particular context attributes can change during negotiation with a remote peer.
///
/// A pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security package
/// always return this value in local time. This parameter is optional and NULL should be passed for short-lived clients.
///
/// There is no expiration time for Microsoft Digest SSP security contexts or credentials.
///
/// If the function succeeds, the function returns one of the following success codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_I_COMPLETE_AND_CONTINUE
///
/// The client must call CompleteAuthToken and then pass the output to the server. The client then waits for a returned token and
/// passes it, in another call, to InitializeSecurityContext (General).
///
///
/// -
/// SEC_I_COMPLETE_NEEDED
/// The client must finish building the message and then call the CompleteAuthToken function.
///
/// -
/// SEC_I_CONTINUE_NEEDED
///
/// The client must send the output token to the server and wait for a return token. The returned token is then passed in another
/// call to InitializeSecurityContext (General). The output token can be empty.
///
///
/// -
/// SEC_I_INCOMPLETE_CREDENTIALS
///
/// Use with Schannel. The server has requested client authentication, and the supplied credentials either do not include a
/// certificate or the certificate was not issued by a certification authority that is trusted by the server. For more information,
/// see Remarks.
///
///
/// -
/// SEC_E_INCOMPLETE_MESSAGE
///
/// Use with Schannel. Data for the whole message was not read from the wire. When this value is returned, the pInput buffer contains
/// a SecBuffer structure with a BufferType member of SECBUFFER_MISSING. The cbBuffer member of SecBuffer contains a value that
/// indicates the number of additional bytes that the function must read from the client before this function succeeds. While this
/// number is not always accurate, using it can help improve performance by avoiding multiple calls to this function.
///
///
/// -
/// SEC_E_OK
///
/// The security context was successfully initialized. There is no need for another InitializeSecurityContext (General) call. If the
/// function returns an output token, that is, if the SECBUFFER_TOKEN in pOutput is of nonzero length, that token must be sent to the server.
///
///
///
/// If the function fails, the function returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// There is not enough memory available to complete the requested action.
///
/// -
/// SEC_E_INTERNAL_ERROR
/// An error occurred that did not map to an SSPI error code.
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
///
/// The error is due to a malformed input token, such as a token corrupted in transit, a token of incorrect size, or a token passed
/// into the wrong security package. Passing a token to the wrong package can happen if the client and server did not negotiate the
/// proper security package.
///
///
/// -
/// SEC_E_LOGON_DENIED
/// The logon failed.
///
/// -
/// SEC_E_NO_AUTHENTICATING_AUTHORITY
///
/// No authority could be contacted for authentication. The domain name of the authenticating party could be wrong, the domain could
/// be unreachable, or there might have been a trust relationship failure.
///
///
/// -
/// SEC_E_NO_CREDENTIALS
/// No credentials are available in the security package.
///
/// -
/// SEC_E_TARGET_UNKNOWN
/// The target was not recognized.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// A context attribute flag that is not valid (ISC_REQ_DELEGATE or ISC_REQ_PROMPT_FOR_CREDS) was specified in the fContextReq parameter.
///
///
/// -
/// SEC_E_WRONG_PRINCIPAL
///
/// The principal that received the authentication request is not the same as the one passed into the pszTargetName parameter. This
/// indicates a failure in mutual authentication.
///
///
///
///
/// phContext
///
///
/// The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality
/// was requested, but could not be established, some applications may choose to shut down the connection immediately.
///
///
/// If attributes of the security context are not sufficient, the client must free the partially created context by calling the
/// DeleteSecurityContext function.
///
/// The InitializeSecurityContext (General) function is used by a client to initialize an outbound context.
/// For a two-leg security context, the calling sequence is as follows:
///
/// -
/// The client calls the function with phContext set to NULL and fills in the buffer descriptor with the input message.
///
/// -
///
/// The security package examines the parameters and constructs an opaque token, placing it in the TOKEN element in the buffer array.
/// If the fContextReq parameter includes the ISC_REQ_ALLOCATE_MEMORY flag, the security package allocates the memory and returns the
/// pointer in the TOKEN element.
///
///
/// -
///
/// The client sends the token returned in the pOutput buffer to the target server. The server then passes the token as an input
/// argument in a call to the AcceptSecurityContext (General) function.
///
///
/// -
///
/// AcceptSecurityContext (General) may return a token, which the server sends to the client for a second call to
/// InitializeSecurityContext (General) if the first call returned SEC_I_CONTINUE_NEEDED.
///
///
///
/// For multiple-leg security contexts, such as mutual authentication, the calling sequence is as follows:
///
/// -
/// The client calls the function as described earlier, but the package returns the SEC_I_CONTINUE_NEEDED success code.
///
/// -
/// The client sends the output token to the server and waits for the server's reply.
///
/// -
///
/// Upon receipt of the server's response, the client calls InitializeSecurityContext (General) again, with phContext set to
/// the handle that was returned from the last call. The token received from the server is supplied in the pInput parameter.
///
///
///
/// If the server has successfully responded, the security package returns SEC_E_OK and a secure session is established.
/// If the function returns one of the error responses, the server's response is not accepted, and the session is not established.
///
/// If the function returns SEC_I_CONTINUE_NEEDED, SEC_I_COMPLETE_NEEDED, or SEC_I_COMPLETE_AND_CONTINUE, steps 2 and 3 are repeated.
///
///
/// To initialize a security context, more than one call to this function may be required, depending on the underlying authentication
/// mechanism as well as the choices specified in the fContextReq parameter.
///
///
/// The fContextReq and pfContextAttributes parameters are bitmasks that represent various context attributes. For a description of
/// the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only
/// on the final successful return should you examine the flags that pertain to security aspects of the context. Intermediate returns
/// can set, for example, the ISC_RET_ALLOCATED_MEMORY flag.
///
///
/// If the ISC_REQ_USE_SUPPLIED_CREDS flag is set, the security package must look for a SECBUFFER_PKG_PARAMS buffer type in the
/// pInput input buffer. This is not a generic solution, but it allows for a strong pairing of security package and application when appropriate.
///
/// If ISC_REQ_ALLOCATE_MEMORY was specified, the caller must free the memory by calling the FreeContextBuffer function.
///
/// For example, the input token could be the challenge from a LAN Manager. In this case, the output token would be the
/// NTLM-encrypted response to the challenge.
///
///
/// The action the client takes depends on the return code from this function. If the return code is SEC_E_OK, there will be no
/// second InitializeSecurityContext (General) call, and no response from the server is expected. If the return code is
/// SEC_I_CONTINUE_NEEDED, the client expects a token in response from the server and passes it in a second call to
/// InitializeSecurityContext (General). The SEC_I_COMPLETE_NEEDED return code indicates that the client must finish building
/// the message and call the CompleteAuthToken function. The SEC_I_COMPLETE_AND_CONTINUE code incorporates both of these actions.
///
///
/// If InitializeSecurityContext (General) returns success on the first (or only) call, then the caller must eventually call
/// the DeleteSecurityContext function on the returned handle, even if the call fails on a later leg of the authentication exchange.
///
///
/// The client may call InitializeSecurityContext (General) again after it has completed successfully. This indicates to the
/// security package that a reauthentication is wanted.
///
///
/// Kernel mode callers have the following differences: the target name is a Unicode string that must be allocated in virtual memory
/// by using VirtualAlloc; it must not be allocated from the pool. Buffers passed and supplied in pInput and pOutput must be in
/// virtual memory, not in the pool.
///
///
/// When using the Schannel SSP, if the function returns SEC_I_INCOMPLETE_CREDENTIALS, check that you specified a valid and trusted
/// certificate in your credentials. The certificate is specified when calling the AcquireCredentialsHandle (General) function. The
/// certificate must be a client authentication certificate issued by a certification authority (CA) trusted by the server. To obtain
/// a list of the CAs trusted by the server, call the QueryContextAttributes (General) function and specify the
/// SECPKG_ATTR_ISSUER_LIST_EX attribute.
///
///
/// When using the Schannel SSP, after a client application receives an authentication certificate from a CA that is trusted by the
/// server, the application creates a new credential by calling the AcquireCredentialsHandle (General) function and then calling
/// InitializeSecurityContext (General) again, specifying the new credential in the phCredential parameter.
///
///
public static HRESULT InitializeSecurityContext(in CredHandle phCredential, [In, Out] SafeCtxtHandle phContext, string pszTargetName, ASC_REQ fContextReq, DREP TargetDataRep,
SecBufferDesc? pInput, [In, Out] SafeSecBufferDesc pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsExpiry)
{
if (phContext is null) throw new ArgumentNullException(nameof(phContext));
unsafe
{
using (var pinnedInput = PinnedObject.FromNullable(pInput))
{
var hCtxt = CtxtHandle.Null;
HRESULT hr = 0;
fixed (CredHandle* pphCred = &phCredential)
hr = InitializeSecurityContext(pphCred, phContext, pszTargetName, fContextReq | ASC_REQ.ASC_REQ_ALLOCATE_MEMORY, 0, TargetDataRep, (SecBufferDesc*)(IntPtr)pinnedInput, 0, ref hCtxt, pOutput, out pfContextAttr, out ptsExpiry);
if (hr.Succeeded)
{
if (phContext.DangerousGetHandle().IsNull)
phContext.SetHandle(hCtxt);
}
return hr;
}
}
}
///
/// The InitSecurityInterface function returns a pointer to an SSPI dispatch table. This function enables clients to use SSPI
/// without binding directly to an implementation of the interface.
///
///
/// If the function succeeds, the return value is a pointer to a SecurityFunctionTable structure.
/// If the function fails, the return value is NULL.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-initsecurityinterfacea PSecurityFunctionTableA SEC_ENTRY
// InitSecurityInterfaceA( );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "1026eeab-e2d6-45f2-9677-82d6cfbf4e12")]
public static unsafe extern SecurityFunctionTable* InitSecurityInterface();
///
///
/// The MakeSignature function generates a cryptographic checksum of the message, and also includes sequencing information to
/// prevent message loss or insertion. MakeSignature allows the application to choose between several cryptographic
/// algorithms, if supported by the chosen mechanism. The MakeSignature function uses the security context referenced by the
/// context handle.
///
/// This function is not supported by the Schannel security support provider (SSP).
///
/// A handle to the security context to use to sign the message.
///
///
/// Package-specific flags that indicate the quality of protection. A security package can use this parameter to enable the selection
/// of cryptographic algorithms.
///
/// When using the Digest SSP, this parameter must be set to zero.
///
///
///
/// A pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures that contain the
/// message to be signed. The function does not process buffers with the SECBUFFER_READONLY_WITH_CHECKSUM attribute.
///
/// The SecBufferDesc structure also references a SecBuffer structure of type SECBUFFER_TOKEN that receives the signature.
/// When the Digest SSP is used as an HTTP authentication protocol, the buffers should be configured as follows.
///
///
/// Buffer #/buffer type
/// Meaning
///
/// -
/// 0 SECBUFFER_TOKEN
/// Empty.
///
/// -
/// 1 SECBUFFER_PKG_PARAMS
/// Method.
///
/// -
/// 2 SECBUFFER_PKG_PARAMS
/// URL.
///
/// -
/// 3 SECBUFFER_PKG_PARAMS
/// HEntity. For more information, see Input Buffers for the Digest Challenge Response.
///
/// -
/// 4 SECBUFFER_PADDING
/// Empty. Receives the signature.
///
///
/// When the Digest SSP is used as an SASL mechanism, the buffers should be configured as follows.
///
///
/// Buffer #/buffer type
/// Meaning
///
/// -
/// 0 SECBUFFER_TOKEN
///
/// Empty. Receives the signature. This buffer must be large enough to hold the largest possible signature. Determine the size
/// required by calling the QueryContextAttributes (General) function and specifying SECPKG_ATTR_SIZES. Check the returned
/// SecPkgContext_Sizes structure member cbMaxSignature.
///
///
/// -
/// 1 SECBUFFER_DATA
/// Message to be signed.
///
/// -
/// 2 SECBUFFER_PADDING
/// Empty.
///
///
///
///
///
/// The sequence number that the transport application assigned to the message. If the transport application does not maintain
/// sequence numbers, this parameter is zero.
///
/// When using the Digest SSP, this parameter must be set to zero. The Digest SSP manages sequence numbering internally.
///
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_I_RENEGOTIATE
///
/// The remote party requires a new handshake sequence or the application has just initiated a shutdown. Return to the negotiation
/// loop and call AcceptSecurityContext (General) or InitializeSecurityContext (General) again. An empty input buffer is passed in
/// the first call.
///
///
/// -
/// SEC_E_INVALID_HANDLE
/// The context handle specified by phContext is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
/// pMessage did not contain a valid SECBUFFER_TOKEN buffer or contained too few buffers.
///
/// -
/// SEC_E_OUT_OF_SEQUENCE
/// The nonce count is out of sequence.
///
/// -
/// SEC_E_NO_AUTHENTICATING_AUTHORITY
/// The security context (phContext) must be revalidated.
///
/// -
/// STATUS_INVALID_PARAMETER
/// The nonce count is not numeric.
///
/// -
/// SEC_E_QOP_NOT_SUPPORTED
/// The quality of protection negotiated between the client and server did not include integrity checking.
///
///
///
///
/// The MakeSignature function generates a signature that is based on the message and the session key for the context.
/// The VerifySignature function verifies the messages signed by the MakeSignature function.
///
/// If the transport application created the security context to support sequence detection and the caller provides a sequence
/// number, the function includes this information in the signature. This protects against reply, insertion, and suppression of
/// messages. The security package incorporates the sequence number passed down from the transport application.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-makesignature KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// MakeSignature( PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "d17824b0-6121-48a3-b19b-d4fae3e1348e")]
public static extern HRESULT MakeSignature(in CtxtHandle phContext, SECQOP fQOP, ref SecBufferDesc pMessage, uint MessageSeqNo);
///
/// The QueryContextAttributes (CredSSP) function lets a transport application query the Credential Security Support Provider
/// (CredSSP) security package for certain attributes of a security context.
///
/// A handle to the security context to be queried.
///
///
/// The attribute of the context to be returned. This parameter can be one of the following values. Unless otherwise specified, the
/// attributes are applicable to both client and server.
///
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_ATTR_C_ACCESS_TOKEN 0x80000012
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure that specifies the access token for the current
/// security context. This attribute is supported only on the server.
///
///
/// -
/// SECPKG_ATTR_C_FULL_ACCESS_TOKEN 0x80000082
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure that specifies the access token for the current
/// security context. This attribute is supported only on the server.
///
///
/// -
/// SECPKG_ATTR_CERT_TRUST_STATUS 0x80000084
///
/// The pBuffer parameter contains a pointer to a CERT_TRUST_STATUS structure that specifies trust information about the certificate.
/// This attribute is supported only on the client.
///
///
/// -
/// SECPKG_ATTR_CREDS 0x80000080
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials. The client
/// credentials can be either user name and password or user name and smart card PIN. This attribute is supported only on the server.
///
///
/// -
/// SECPKG_ATTR_CREDS_2 0x80000086
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials. If the
/// client credential is user name and password, the buffer is a packed KERB_INTERACTIVE_LOGON structure. If the client credential is
/// user name and smart card PIN, the buffer is a packed KERB_CERTIFICATE_LOGON structure. If the client credential is an online
/// identity credential, the buffer is a marshaled SEC_WINNT_AUTH_IDENTITY_EX2 structure. This attribute is supported only on the
/// CredSSP server. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This
/// value is not supported.
///
///
/// -
/// SECPKG_ATTR_NEGOTIATION_PACKAGE 0x80000081
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfo structure that specifies the name of the authentication
/// package negotiated by the Microsoft Negotiate provider.
///
///
/// -
/// SECPKG_ATTR_PACKAGE_INFO 10
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfostructure. Returns information on the SSP in use.
///
/// -
/// SECPKG_ATTR_SERVER_AUTH_FLAGS 0x80000083
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Flags structure that specifies information about the flags in the
/// current security context. This attribute is supported only on the client.
///
///
/// -
/// SECPKG_ATTR_SIZES 0x0
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Sizes structure. Queries the sizes of the structures used in the
/// per-message functions and authentication exchanges.
///
///
/// -
/// SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES 124
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SubjectAttributes structure. This value returns information about the
/// security attributes for the connection. This value is supported only on the CredSSP server. Windows Server 2008, Windows Vista,
/// Windows Server 2003 and Windows XP: This value is not supported.
///
///
///
///
///
/// A pointer to a structure that receives the attributes. The structure type depends on the value of the ulAttribute parameter.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it can return the following error codes.
///
///
/// Return code/value
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE 0x80100003
/// The function failed. The phContext parameter specifies a handle to an incomplete context.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION 0x80090302
/// The function failed. The value of the ulAttribute parameter is not valid.
///
///
///
///
/// The structure pointed to by the pBuffer parameter varies depending on the attribute being queried.
///
/// While the caller must allocate the pBuffer structure itself, the SSP allocates any memory required to hold variable-sized members
/// of the pBuffer structure. Memory allocated by the SSP must be freed by calling the FreeContextBuffer function.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-querycontextattributesw KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// QueryContextAttributesW( PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "4956c4ab-b71e-4960-b750-f3a79b87baac")]
public static extern HRESULT QueryContextAttributes(in CtxtHandle phContext, SECPKG_ATTR ulAttribute, IntPtr pBuffer);
///
/// The QueryContextAttributes (CredSSP) function lets a transport application query the Credential Security Support Provider
/// (CredSSP) security package for certain attributes of a security context.
///
/// A handle to the security context to be queried.
///
///
/// The attribute of the context to be returned. This parameter can be one of the following values. Unless otherwise specified, the
/// attributes are applicable to both client and server.
///
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_ATTR_C_ACCESS_TOKEN 0x80000012
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure that specifies the access token for the current
/// security context. This attribute is supported only on the server.
///
///
/// -
/// SECPKG_ATTR_C_FULL_ACCESS_TOKEN 0x80000082
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure that specifies the access token for the current
/// security context. This attribute is supported only on the server.
///
///
/// -
/// SECPKG_ATTR_CERT_TRUST_STATUS 0x80000084
///
/// The pBuffer parameter contains a pointer to a CERT_TRUST_STATUS structure that specifies trust information about the certificate.
/// This attribute is supported only on the client.
///
///
/// -
/// SECPKG_ATTR_CREDS 0x80000080
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials. The client
/// credentials can be either user name and password or user name and smart card PIN. This attribute is supported only on the server.
///
///
/// -
/// SECPKG_ATTR_CREDS_2 0x80000086
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials. If the
/// client credential is user name and password, the buffer is a packed KERB_INTERACTIVE_LOGON structure. If the client credential is
/// user name and smart card PIN, the buffer is a packed KERB_CERTIFICATE_LOGON structure. If the client credential is an online
/// identity credential, the buffer is a marshaled SEC_WINNT_AUTH_IDENTITY_EX2 structure. This attribute is supported only on the
/// CredSSP server. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This
/// value is not supported.
///
///
/// -
/// SECPKG_ATTR_NEGOTIATION_PACKAGE 0x80000081
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfo structure that specifies the name of the authentication
/// package negotiated by the Microsoft Negotiate provider.
///
///
/// -
/// SECPKG_ATTR_PACKAGE_INFO 10
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfostructure. Returns information on the SSP in use.
///
/// -
/// SECPKG_ATTR_SERVER_AUTH_FLAGS 0x80000083
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Flags structure that specifies information about the flags in the
/// current security context. This attribute is supported only on the client.
///
///
/// -
/// SECPKG_ATTR_SIZES 0x0
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Sizes structure. Queries the sizes of the structures used in the
/// per-message functions and authentication exchanges.
///
///
/// -
/// SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES 124
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SubjectAttributes structure. This value returns information about the
/// security attributes for the connection. This value is supported only on the CredSSP server. Windows Server 2008, Windows Vista,
/// Windows Server 2003 and Windows XP: This value is not supported.
///
///
///
///
/// A structure that receives the attributes. The structure type depends on the value of the ulAttribute parameter.
///
/// The structure pointed to by the pBuffer parameter varies depending on the attribute being queried.
///
/// While the caller must allocate the pBuffer structure itself, the SSP allocates any memory required to hold variable-sized members
/// of the pBuffer structure. Memory allocated by the SSP must be freed by calling the FreeContextBuffer function.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-querycontextattributesw KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// QueryContextAttributesW( PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer );
[PInvokeData("sspi.h", MSDNShortId = "4956c4ab-b71e-4960-b750-f3a79b87baac")]
public static T QueryContextAttributes(in CtxtHandle phContext, SECPKG_ATTR ulAttribute) where T : struct
{
if (!CorrespondingTypeAttribute.CanGet(ulAttribute, typeof(T))) throw new ArgumentException($"{typeof(T).GetType().Name} cannot be retrieved using {ulAttribute}.");
using (var mem = SafeHGlobalHandle.CreateFromStructure())
{
if (Environment.OSVersion.Version > new Version(6, 0))
QueryContextAttributesEx(phContext, ulAttribute, (IntPtr)mem, (uint)mem.Size).ThrowIfFailed();
else
QueryContextAttributes(phContext, ulAttribute, (IntPtr)mem).ThrowIfFailed();
return mem.ToStructure();
}
}
/// Enables a transport application to query a security package for certain attributes of a security context.
/// A handle to the security context to be queried.
///
/// Specifies the attribute of the context to be returned. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_ATTR_ACCESS_TOKEN 18
/// The pBuffer parameter contains a pointer to a SecPkgContext_AccessToken structure. Returns a handle to the access token.
///
/// -
/// SECPKG_ATTR_APP_DATA 0x5e
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionAppData structure. Returns or specifies application data for
/// the session. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_AUTHORITY 6
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Authority structure. Queries the name of the authenticating authority.
///
///
/// -
/// SECPKG_ATTR_CLIENT_SPECIFIED_TARGET 27
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientSpecifiedTarget structure that represents the service principal
/// name (SPN) of the initial target supplied by the client. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:
/// This value is not supported.
///
///
/// -
/// SECPKG_ATTR_CONNECTION_INFO 0x5a
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ConnectionInfo structure. Returns detailed information on the
/// established connection. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_CREDS_2 0x80000086
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_ClientCreds structure that specifies client credentials. If the
/// client credential is user name and password, the buffer is a packed KERB_INTERACTIVE_LOGON structure. If the client credential is
/// user name and smart card PIN, the buffer is a packed KERB_CERTIFICATE_LOGON structure. If the client credential is an online
/// identity credential, the buffer is a marshaled SEC_WINNT_AUTH_IDENTITY_EX2 structure. This attribute is supported only on the
/// CredSSP server. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This
/// value is not supported.
///
///
/// -
/// SECPKG_ATTR_DCE_INFO 3
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_DceInfo structure. Queries for authorization data used by DCE services.
///
///
/// -
/// SECPKG_ATTR_ENDPOINT_BINDINGS 26
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Bindings structure that specifies channel binding information. This
/// attribute is supported only by the Schannel security package. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows
/// XP: This value is not supported.
///
///
/// -
/// SECPKG_ATTR_EAP_KEY_BLOCK 0x5b
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_EapKeyBlock structure. Queries for key data used by the EAP TLS
/// protocol. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_FLAGS 14
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Flags structure. Returns information about the negotiated context flags.
///
///
/// -
/// SECPKG_ATTR_ISSUER_LIST_EX 0x59
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_IssuerListInfoEx structure. Returns a list of certificate issuers
/// that are accepted by the server. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_KEY_INFO 5
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_KeyInfo structure. Queries information about the keys used in a
/// security context.
///
///
/// -
/// SECPKG_ATTR_LAST_CLIENT_TOKEN_STATUS 30
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_LastClientTokenStatus structure that specifies whether the token from
/// the most recent call to the InitializeSecurityContext function is the last token from the client. This value is supported only by
/// the Negotiate, Kerberos, and NTLM security packages. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This
/// value is not supported.
///
///
/// -
/// SECPKG_ATTR_LIFESPAN 2
/// The pBuffer parameter contains a pointer to a SecPkgContext_Lifespan structure. Queries the life span of the context.
///
/// -
/// SECPKG_ATTR_LOCAL_CERT_CONTEXT 0x54
///
/// The pBuffer parameter contains a pointer to a PCCERT_CONTEXTstructure. Finds a certificate context that contains a local end
/// certificate. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_LOCAL_CRED
/// The pBuffer parameter contains a pointer to a SecPkgContext_LocalCredentialInfo structure. (obsolete) Superseded by SECPKG_ATTR_LOCAL_CERT_CONTEXT.
///
/// -
/// SECPKG_ATTR_NAMES 1
/// The pBuffer parameter contains a pointer to a SecPkgContext_Names structure. Queries the name associated with the context.
///
/// -
/// SECPKG_ATTR_NATIVE_NAMES 13
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_NativeNames structure. Returns the principal name (CNAME) from the
/// outbound ticket.
///
///
/// -
/// SECPKG_ATTR_NEGOTIATION_INFO 12
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_NegotiationInfo structure. Returns information about the security
/// package to be used with the negotiation process and the current state of the negotiation for the use of that package.
///
///
/// -
/// SECPKG_ATTR_PACKAGE_INFO 10
/// The pBuffer parameter contains a pointer to a SecPkgContext_PackageInfostructure. Returns information on the SSP in use.
///
/// -
/// SECPKG_ATTR_PASSWORD_EXPIRY 8
/// The pBuffer parameter contains a pointer to a SecPkgContext_PasswordExpiry structure. Returns password expiration information.
///
/// -
/// SECPKG_ATTR_REMOTE_CERT_CONTEXT 0x53
///
/// The pBuffer parameter contains a pointer to a PCCERT_CONTEXTstructure. Finds a certificate context that contains the end
/// certificate supplied by the server. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_ROOT_STORE 0x55
///
/// The pBuffer parameter contains a pointer to a HCERTCONTEXT. Finds a certificate context that contains a certificate supplied by
/// the Root store.
///
///
/// -
/// SECPKG_ATTR_SESSION_KEY 9
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionKey structure. Returns information about the session keys.
///
///
/// -
/// SECPKG_ATTR_SESSION_INFO 0x5d
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionInfo structure. Returns information about the session. Windows
/// Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported. This attribute is supported only by
/// the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_SIZES 0
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Sizes structure. Queries the sizes of the structures used in the
/// per-message functions.
///
///
/// -
/// SECPKG_ATTR_STREAM_SIZES 4
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_StreamSizes structure. Queries the sizes of the various parts of a
/// stream used in the per-message functions. This attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES 124
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SubjectAttributes structure. This value returns information about the
/// security attributes for the connection. This value is supported only on the CredSSP server. Windows Server 2008, Windows Vista,
/// Windows Server 2003 and Windows XP: This value is not supported.
///
///
/// -
/// SECPKG_ATTR_SUPPORTED_SIGNATURES 0x66
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SupportedSignatures structure. This value returns information about
/// the signature types that are supported for the connection. This value is supported only by the Schannel security package. Windows
/// Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not supported.
///
///
/// -
/// SECPKG_ATTR_TARGET_INFORMATION 17
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_TargetInformation structure. Returns information about the name of
/// the remote server.
///
///
/// -
/// SECPKG_ATTR_UNIQUE_BINDINGS 25
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_Bindings structure that specifies channel binding information. This
/// value is supported only by the Schannel security package. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:
/// This value is not supported.
///
///
///
///
///
/// A pointer to a structure that receives the attributes. The type of structure pointed to depends on the value specified in the
/// ulAttribute parameter.
///
/// The size, in bytes, of the pBuffer parameter.
///
/// If the function succeeds, the return value is SEC_E_OK.
/// If the function fails, the return value is a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-querycontextattributesexw SECURITY_STATUS SEC_ENTRY
// QueryContextAttributesExW( PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer, unsigned long cbBuffer );
[DllImport(Lib.SspiCli, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "FD91EE99-F94E-44CE-9331-933D0CAA5F75", MinClient = PInvokeClient.Windows7)]
public static extern HRESULT QueryContextAttributesEx(in CtxtHandle phContext, SECPKG_ATTR ulAttribute, IntPtr pBuffer, uint cbBuffer);
///
/// Retrieves the attributes of a credential, such as the name associated with the credential. The information is valid for any
/// security context created with the specified credential.
///
/// A handle of the credentials to be queried.
///
/// Specifies the attribute to query. This parameter can be any of the following attributes.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_CRED_ATTR_CERT
///
/// Returns the certificate thumbprint in a pbuffer of type SecPkgCredentials_Cert. This attribute is only supported by Kerberos.
/// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This attribute is not available.
///
///
/// -
/// SECPKG_CRED_ATTR_NAMES
///
/// Returns the name of a credential in a pbuffer of type SecPkgCredentials_Names. This attribute is not supported by Schannel in
/// WOW64 mode.
///
///
/// -
/// SECPKG_ATTR_SUPPORTED_ALGS
///
/// Returns the supported algorithms in a pbuffer of type SecPkgCred_SupportedAlgs. All supported algorithms are included, regardless
/// of whether they are supported by the provided certificate or enabled on the local computer. This attribute is supported only by Schannel.
///
///
/// -
/// SECPKG_ATTR_CIPHER_STRENGTHS
/// Returns the cipher strengths in a pbuffer of type SecPkgCred_CipherStrengths. This attribute is supported only by Schannel.
///
/// -
/// SECPKG_ATTR_SUPPORTED_PROTOCOLS
///
/// Returns the supported algorithms in a pbuffer of type SecPkgCred_SupportedProtocols. All supported protocols are included,
/// regardless of whether they are supported by the provided certificate or enabled on the local computer. This attribute is
/// supported only by Schannel.
///
///
///
///
///
/// A pointer to a buffer that receives the requested attribute. The type of structure returned depends on the value of ulAttribute.
///
///
/// If the function succeeds, the return value is SEC_E_OK.
/// If the function fails, the return value may be one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// The specified attribute is not supported by Schannel. This return value will only be returned when the Schannel SSP is being used.
///
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// The memory that is available is not sufficient to complete the request.
///
///
///
///
///
/// The QueryCredentialsAttributes function allows an application to determine several characteristics of a credential,
/// including the name associated with the specified credentials.
///
///
/// Querying the SECPKG_ATTR_CIPHER_STRENGTHS attribute returns a SecPkgCred_CipherStrengths structure. The cipher strength in this
/// structure is the same as the cipher strength in the SCHANNEL_CRED structure used when a credential was created.
///
///
/// Note An application can find the system default cipher strength by querying this attribute with a default credential. A
/// default credential is created by calling AcquireCredentialsHandle with a NULL pAuthData parameter.
///
///
/// Querying the SECPKG_ATTR_SUPPORTED_ALGS attribute returns a SecPkgCred_SupportedAlgs structure. The algorithms in this structure
/// are compatible with those indicated in the SCHANNEL_CRED structure used when a credential was created.
///
///
/// Querying the SECPKG_ATTR_SUPPORTED_PROTOCOLS attribute returns a SecPkgCred_SupportedProtocols structure that contains a bit
/// array compatible with the grbitEnabledProtocols field of the SCHANNEL_CRED structure.
///
///
/// The caller must allocate the structure pointed to by the pBuffer parameter. The security package allocates the buffer for any
/// pointer returned in the pBuffer structure. The caller can call the FreeContextBuffer function to free any pointers allocated by
/// the security package.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-querycredentialsattributesa SECURITY_STATUS SEC_ENTRY
// QueryCredentialsAttributesA( PCredHandle phCredential, unsigned long ulAttribute, void *pBuffer );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "a8ba6f73-8469-431b-b185-183b45b2c533")]
public static extern HRESULT QueryCredentialsAttributes(in CredHandle phCredential, SECPKG_CRED_ATTR ulAttribute, IntPtr pBuffer);
///
/// Retrieves the attributes of a credential, such as the name associated with the credential. The information is valid for any
/// security context created with the specified credential.
///
/// A handle of the credentials to be queried.
///
/// Specifies the attribute to query. This parameter can be any of the following attributes.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_CRED_ATTR_CERT
///
/// Returns the certificate thumbprint in a pbuffer of type SecPkgCredentials_Cert. This attribute is only supported by Kerberos.
/// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This attribute is not available.
///
///
/// -
/// SECPKG_CRED_ATTR_NAMES
///
/// Returns the name of a credential in a pbuffer of type SecPkgCredentials_Names. This attribute is not supported by Schannel in
/// WOW64 mode.
///
///
/// -
/// SECPKG_ATTR_SUPPORTED_ALGS
///
/// Returns the supported algorithms in a pbuffer of type SecPkgCred_SupportedAlgs. All supported algorithms are included, regardless
/// of whether they are supported by the provided certificate or enabled on the local computer. This attribute is supported only by Schannel.
///
///
/// -
/// SECPKG_ATTR_CIPHER_STRENGTHS
/// Returns the cipher strengths in a pbuffer of type SecPkgCred_CipherStrengths. This attribute is supported only by Schannel.
///
/// -
/// SECPKG_ATTR_SUPPORTED_PROTOCOLS
///
/// Returns the supported algorithms in a pbuffer of type SecPkgCred_SupportedProtocols. All supported protocols are included,
/// regardless of whether they are supported by the provided certificate or enabled on the local computer. This attribute is
/// supported only by Schannel.
///
///
///
///
///
/// A pointer to a buffer that receives the requested attribute. The type of structure returned depends on the value of ulAttribute.
///
/// The size, in bytes, of the pBuffer parameter.
///
/// If the function succeeds, the return value is SEC_E_OK.
/// If the function fails, the return value may be one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// The specified attribute is not supported by Schannel. This return value will only be returned when the Schannel SSP is being used.
///
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// The memory that is available is not sufficient to complete the request.
///
///
///
///
///
/// The QueryCredentialsAttributes function allows an application to determine several characteristics of a credential,
/// including the name associated with the specified credentials.
///
///
/// Querying the SECPKG_ATTR_CIPHER_STRENGTHS attribute returns a SecPkgCred_CipherStrengths structure. The cipher strength in this
/// structure is the same as the cipher strength in the SCHANNEL_CRED structure used when a credential was created.
///
///
/// Note An application can find the system default cipher strength by querying this attribute with a default credential. A
/// default credential is created by calling AcquireCredentialsHandle with a NULL pAuthData parameter.
///
///
/// Querying the SECPKG_ATTR_SUPPORTED_ALGS attribute returns a SecPkgCred_SupportedAlgs structure. The algorithms in this structure
/// are compatible with those indicated in the SCHANNEL_CRED structure used when a credential was created.
///
///
/// Querying the SECPKG_ATTR_SUPPORTED_PROTOCOLS attribute returns a SecPkgCred_SupportedProtocols structure that contains a bit
/// array compatible with the grbitEnabledProtocols field of the SCHANNEL_CRED structure.
///
///
/// The caller must allocate the structure pointed to by the pBuffer parameter. The security package allocates the buffer for any
/// pointer returned in the pBuffer structure. The caller can call the FreeContextBuffer function to free any pointers allocated by
/// the security package.
///
///
[DllImport(Lib.SspiCli, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MinClient = PInvokeClient.Windows7)]
public static extern HRESULT QueryCredentialsAttributesEx(in CredHandle phCredential, SECPKG_CRED_ATTR ulAttribute, IntPtr pBuffer, uint cbBuffer);
/// Obtains the access token for a client security context and uses it directly.
/// Handle of the context to query.
/// Returned handle to the access token.
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code. One possible error code return is SEC_E_INVALID_HANDLE.
///
///
/// This function is called by a server application to control impersonation outside the SSPI layer, such as when launching a child
/// process. The handle returned must be closed with CloseHandle when the handle is no longer needed.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-querysecuritycontexttoken KSECDDDECLSPEC SECURITY_STATUS
// SEC_ENTRY QuerySecurityContextToken( PCtxtHandle phContext, void **Token );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "5dc23608-9ce3-4fee-8161-2e409cef4063")]
public static extern HRESULT QuerySecurityContextToken(in CtxtHandle phContext, out SafeHTOKEN Token);
///
/// Retrieves information about a specified security package. This information includes the bounds on sizes of authentication
/// information, credentials, and contexts.
///
/// Pointer to a null-terminated string that specifies the name of the security package.
///
/// Pointer to a variable that receives a pointer to a SecPkgInfo structure containing information about the specified security package.
///
///
/// If the function succeeds, the return value is SEC_E_OK.
/// If the function fails, the return value is a nonzero error code.
///
/// The caller must call the FreeContextBuffer function to free the buffer returned in ppPackageInfo.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-querysecuritypackageinfoa SECURITY_STATUS SEC_ENTRY
// QuerySecurityPackageInfoA( LPSTR pszPackageName, PSecPkgInfoA *ppPackageInfo );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "130ef0fe-bb13-4a65-b476-cd25ed234da1")]
public static extern HRESULT QuerySecurityPackageInfo(string pszPackageName, out SafeContextBuffer ppPackageInfo);
/// Allows a security package to discontinue the impersonation of the caller and restore its own security context.
///
/// Handle of the security context being impersonated. This handle must have been obtained in the call to the AcceptSecurityContext
/// (General) function and used in the call to the ImpersonateSecurityContext function.
///
///
/// If the function succeeds, the return value is SEC_E_OK.
/// If the function fails, the return value can be one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
///
///
///
/// RevertSecurityContext is not available with all security packages on all platforms. Typically, it is implemented only on
/// platforms and with security packages for which a call to the QuerySecurityPackageInfo function indicates impersonation support.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-revertsecuritycontext KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// RevertSecurityContext( PCtxtHandle phContext );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "d4ed1fe9-2e0a-4648-a010-1eae49ba03ee")]
public static extern HRESULT RevertSecurityContext(in CtxtHandle phContext);
///
/// The SaslAcceptSecurityContext function wraps a standard call to the Security Support Provider Interface
/// AcceptSecurityContext (General) function and includes creation of SASL server cookies.
///
///
/// A handle to the server's credentials. The server calls the AcquireCredentialsHandle function with the INBOUND flag set to
/// retrieve this handle.
///
///
/// Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext (General), this pointer is NULL. On
/// subsequent calls, phContext is the handle to the partially formed context that was returned in the phNewContext parameter by the
/// first call.
///
///
///
/// Pointer to a SecBufferDesc structure generated by a client call to the InitializeSecurityContext (General) function that contains
/// the input buffer descriptor.
///
///
/// SASL requires a single buffer of type SECBUFFER_TOKEN. The buffer is empty for the first call to the AcceptSecurityContext
/// (General) function and contains the challenge response received from the client for the second call.
///
///
///
///
/// Bit flags that specify the attributes required by the server to establish the context. Bit flags can be combined using bitwise-
/// OR operations. The following table shows the possible values.
///
///
///
/// Value
/// Meaning
///
/// -
/// ASC_REQ_CONFIDENTIALITY
/// Encrypt and decrypt messages. Valid with the Digest SSP for SASL only.
///
/// -
/// ASC_REQ_HTTP
/// Use Digest for HTTP. Omit this flag to use Digest as an SASL mechanism.
///
///
///
///
/// Indicates the data representation, such as byte ordering, on the target. This value can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
///
///
/// Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext (General), this pointer receives the new context
/// handle. On subsequent calls, phNewContext can be the same as the handle specified in the phContext parameter.
///
///
/// Pointer to a SecBufferDesc structure that contains the output buffer descriptor. This buffer is sent to the client for input into
/// additional calls to InitializeSecurityContext (General). An output buffer may be generated even if the function returns SEC_E_OK.
/// Any buffer generated must be sent back to the client application.
///
///
///
/// Pointer to a variable that receives a set of bit flags indicating the attributes of the established context. For a description of
/// the various attributes, see Context Requirements. Flags used for this parameter are prefixed with ASC_RET, such as ASC_RET_DELEGATE.
///
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags not related to
/// security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
///
///
///
/// Pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security
/// package always return this value in local time.
///
///
/// Note Until the last call of the authentication process, the expiration time for the context can be incorrect because more
/// information will be provided during later stages of the negotiation. Therefore, ptsTimeStamp must be NULL until the last
/// call to the function.
///
///
///
///
/// If the call is completed successfully, this function returns SEC_E_OK. The following table shows some possible failure return values.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_ALGORITHM_MISMATCH
/// Authz processing is not permitted.
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// Not enough memory is available to complete the request.
///
/// -
/// SEC_E_INVALID_TOKEN
/// No Token buffer is located in the pOutput parameter, or the message failed to decrypt.
///
///
///
///
/// The final call of the AcceptSecurityContext (General) function that returns SEC_E_OK is identified. If a return token is
/// produced, SASL processing is suspended for one round trip back to the client to allow the final token to be processed. After the
/// exchange is completed, SEC_E_CONTINUE_NEEDED is returned to the application with an additional SASL server cookie encrypted with
/// SSPI message functions. The initial server cookie indicates if INTEGRITY and PRIVACY are supported. This initial server cookie is
/// processed by the client, and the client returns a client cookie to indicate which services the client requests. The client cookie
/// is then decrypted by the server and the final services are determined for the following message traffic.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslacceptsecuritycontext SECURITY_STATUS SEC_ENTRY
// SaslAcceptSecurityContext( PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, unsigned long fContextReq,
// unsigned long TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "39ef6522-ff70-4066-a34d-f2af2174f6ee")]
public static unsafe extern HRESULT SaslAcceptSecurityContext([In, Optional] CredHandle* phCredential, [In, Optional] CtxtHandle* phContext, [In, Optional] SecBufferDesc* pInput, ASC_REQ fContextReq, DREP TargetDataRep,
out CtxtHandle phNewContext, [Optional] SecBufferDesc* pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsExpiry);
/// The SaslEnumerateProfiles function lists the packages that provide a SASL interface.
///
/// Pointer to a list of Unicode or ANSI strings that contain the names of the packages with SASL wrapper support.
///
///
/// Pointer to an unsigned LONG value that contains the number of packages with SASL wrapper support.
///
///
/// If the call is completed successfully, this function returns SEC_E_OK.
/// If the function fails, the return value is a nonzero error code.
///
///
/// The current list is maintained in the registry under
/// A terminating NULL character is appended to the end of the list.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslenumerateprofilesa SECURITY_STATUS SEC_ENTRY
// SaslEnumerateProfilesA( LPSTR *ProfileList, ULONG *ProfileCount );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "0c11e0e3-2538-4703-bc32-31c73d65a498")]
public static extern HRESULT SaslEnumerateProfiles([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] out string[] ProfileList, out uint ProfileCount);
/// The SaslGetContextOption function retrieves the specified property of the specified SASL context.
/// Handle of the SASL context.
///
/// Property to return from the SASL context. The following table lists the possible values.
///
///
/// Value
/// Meaning
///
/// -
/// SASL_OPTION_AUTHZ_PROCESSING
///
/// Data type of buffer: ULONG State of SASL processing of the Authz value provided by the SASL application. The valid states for
/// processing are Sasl_AuthZIDForbidden and Sasl_AuthZIDProcessed.
///
///
/// -
/// SASL_OPTION_AUTHZ_STRING
///
/// Data type of buffer: Array of binary characters String of characters passed from the SASL client to the server. If the
/// AuthZ_Processing state is Sasl_AuthZIDForbidden, the return value SEC_E_UNSUPPORTED_FUNCTION is returned.
///
///
/// -
/// SASL_OPTION_RECV_SIZE
/// Data type of buffer: ULONG Maximum size of the receiving buffer on the local computer.
///
/// -
/// SASL_OPTION_SEND_SIZE
///
/// Data type of buffer: ULONG Maximum message data size that can be transmitted. This value is the maximum buffer size that can be
/// transmitted to the remote SASL process minus the block size, the trailer size, and the maximum signature size.
///
///
///
///
///
/// A pointer to a buffer that receives the requested property. For the data type of the buffer for each value of the Option
/// parameter, see the Option parameter.
///
/// The size, in bytes, of the buffer specified by the Value parameter.
///
/// A pointer to an unsigned LONG value that returns the value if the buffer specified by the Value parameter is not large
/// enough to contain the data value of the property specified by the Option parameter.
///
///
///
/// If the call is completed successfully, this function returns SEC_E_OK. The following table shows some possible error return values.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_BUFFER_TOO_SMALL
///
/// The buffer specified by the Value parameter is not large enough to contain the data value of the property specified by the Option parameter.
///
///
/// -
/// SEC_E_INVALID_HANDLE
/// The SASL context handle specified by the ContextHandle parameter was not found in the SASL list.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
/// The option specified in the Option parameter is not valid.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslgetcontextoption SECURITY_STATUS SEC_ENTRY
// SaslGetContextOption( PCtxtHandle ContextHandle, ULONG Option, PVOID Value, ULONG Size, PULONG Needed );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "c9c424d3-07e6-4ed0-9189-c932af0475d9")]
public static extern HRESULT SaslGetContextOption(in CtxtHandle ContextHandle, SASL_OPTION Option, [Out] IntPtr Value, uint Size, out uint Needed);
/// The SaslGetProfilePackage function returns the package information for the specified package.
/// Unicode or ANSI string that contains the name of the SASL package.
///
/// Pointer to a pointer to a SecPkgInfo structure that returns the package information for the package specified by the ProfileName parameter.
///
///
///
/// If the call is completed successfully, this function returns SEC_E_OK. The following table shows some possible failure return values.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_SECPKG_NOT_FOUND
/// The SASL profile specified by the ProfileName parameter could not be found.
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// Memory could not be allocated for the SecPkgInfo structure.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslgetprofilepackagew SECURITY_STATUS SEC_ENTRY
// SaslGetProfilePackageW( LPWSTR ProfileName, PSecPkgInfoW *PackageInfo );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "b7cecc5f-775f-40ba-abfc-27d51b3f5395")]
public static extern HRESULT SaslGetProfilePackage(string ProfileName, out SafeContextBuffer PackageInfo);
///
/// The SaslIdentifyPackage function returns the negotiate prefix that matches the specified SASL negotiation buffer.
///
///
/// Pointer to a SecBufferDesc structure that specifies the SASL negotiation buffer for which to find the negotiate prefix.
///
///
/// Pointer to a pointer to a SecPkgInfo structure that returns the negotiate prefix for the negotiation buffer specified by the
/// pInput parameter.
///
///
/// If the call is completed successfully, this function returns SEC_E_OK.
/// If the function fails, the return value is a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslidentifypackagea SECURITY_STATUS SEC_ENTRY
// SaslIdentifyPackageA( PSecBufferDesc pInput, PSecPkgInfoA *PackageInfo );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "df6f4749-8f28-4ee5-8165-f7aeb3bea7ab")]
public static extern HRESULT SaslIdentifyPackage(ref SecBufferDesc pInput, out SafeContextBuffer PackageInfo);
///
/// The SaslInitializeSecurityContext function wraps a standard call to the Security Support Provider Interface
/// InitializeSecurityContext (General) function and processes SASL server cookies from the server.
///
///
/// A handle to the credentials returned by the AcquireCredentialsHandle function used to build the security context. Using the
/// SaslInitializeSecurityContext function requires at least OUTBOUND credentials.
///
///
/// Pointer to a CtxtHandle structure. On the first call to the SaslInitializeSecurityContext function, this pointer is
/// NULL. On the second call, this parameter is a pointer to the handle to the partially formed context returned in the
/// phNewContext parameter by the first call.
///
/// Pointer to a Unicode or ANSI string that indicates the target of the context.
///
///
/// Bit flags that indicate the requirements of the context. Flags used for this parameter are prefixed with ISC_REQ_; for example:
/// ISC_REQ_DELEGATE. Specify combinations of the following attributes flags.
///
///
///
/// Value
/// Meaning
///
/// -
/// ISC_REQ_REPLAY_DETECT
/// Detect replayed packets.
///
/// -
/// ISC_REQ_SEQUENCE_DETECT
/// Detect messages received out of sequence.
///
/// -
/// ISC_REQ_CONFIDENTIALITY
/// Encrypt messages.
///
/// -
/// ISC_REQ_STREAM
/// Support a stream-oriented connection.
///
/// -
/// ISC_REQ_EXTENDED_ERROR
/// When errors occur, the remote party will be notified.
///
/// -
/// ISC_REQ_CONNECTION
/// The security context will not handle formatting messages.
///
/// -
/// ISC_REQ_MUTUAL_AUTH
/// Client and server will be authenticated.
///
/// -
/// ISC_REQ_INTEGRITY
/// Sign messages and verify signatures.
///
///
/// For further descriptions of the various attributes, see Context Requirements.
///
/// Reserved value; must be zero.
///
/// Indicates the data representation, such as byte ordering, on the target. Can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
///
///
///
/// Pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. The pointer must be
/// NULL on the first call to the function. On subsequent calls to the function, it is a pointer to a buffer allocated with
/// enough memory to hold the token returned by the remote peer.
///
/// SASL requires a single buffer of type SECBUFFER_TOKEN that contains the challenge received from the server.
///
/// Reserved value; must be zero.
///
/// Pointer to a CtxtHandle structure. On the first call to the SaslInitializeSecurityContext function, this pointer receives
/// the new context handle. On the second call, phNewContext can be the same as the handle specified in the phContext parameter.
///
///
/// Pointer to a SecBufferDesc structure that contains pointers to the SecBuffer structure that receives the output data. If a buffer
/// was typed as SEC_READWRITE in the input, it will be there on output. The system will allocate a buffer for the security token if
/// requested (through ISC_REQ_ALLOCATE_MEMORY) and fill in the address in the buffer descriptor for the security token.
///
///
///
/// Pointer to a variable to receive a set of bit flags that indicate the attributes of the established context. For a description of
/// the various attributes, see Context Requirements.
///
/// Flags used for this parameter are prefixed with ISC_RET_, such as ISC_RET_DELEGATE.
/// For a list of valid values, see the fContextReq parameter.
///
/// Do not check for security-related attributes until the final function call returns successfully. Attribute flags not related to
/// security, such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
///
/// Note Particular context attributes can change during a negotiation with a remote peer.
///
///
/// Pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security
/// package always return this value in local time. This parameter is optional and NULL should be passed for short-lived clients.
///
///
///
/// If the call is completed successfully, this function returns SEC_E_OK. The following table shows some possible failure return values.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_ALGORITHM_MISMATCH
/// Authz processing is not permitted.
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// Not enough memory is available to complete the request.
///
/// -
/// SEC_E_INVALID_TOKEN
/// No Token buffer is located in the pOutput parameter, or the message failed to decrypt.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslinitializesecuritycontextw SECURITY_STATUS SEC_ENTRY
// SaslInitializeSecurityContextW( PCredHandle phCredential, PCtxtHandle phContext, LPWSTR pszTargetName, unsigned long fContextReq,
// unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext,
// PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "9cc661b7-f1b0-4fb1-b799-5b318d87fd4d")]
public static unsafe extern HRESULT SaslInitializeSecurityContext([In, Optional] CredHandle* phCredential, [In, Optional] CtxtHandle* phContext, [Optional] string pszTargetName, ASC_REQ fContextReq, [Optional] uint Reserved1, DREP TargetDataRep,
[In, Optional] SecBufferDesc* pInput, [Optional] uint Reserved2, out SafeCtxtHandle phNewContext, [Optional] SecBufferDesc* pOutput, out ASC_RET pfContextAttr, out TimeStamp ptsExpiry);
/// The SaslSetContextOption function sets the value of the specified property for the specified SASL context.
/// Handle of the SASL context.
///
/// Property to set for the SASL context. The following table lists the possible values.
///
///
/// Value
/// Meaning
///
/// -
/// SASL_OPTION_AUTHZ_PROCESSING
///
/// Data type of buffer: ULONG State of SASL processing of the Authz value provided by the SASL application. The valid states for
/// processing are Sasl_AuthZIDForbidden and Sasl_AuthZIDProcessed. The default value is Sasl_AuthZIDProcessed.
///
///
/// -
/// SASL_OPTION_AUTHZ_STRING
///
/// Data type of buffer: Array of binary characters String of characters passed from the SASL client to the server. If the
/// AuthZ_Processing state is Sasl_AuthZIDForbidden, the return value SEC_E_UNSUPPORTED_FUNCTION is returned.
///
///
/// -
/// SASL_OPTION_RECV_SIZE
/// Data type of buffer: ULONG Maximum size of the receiving buffer on the local computer. The default value is 0x0FFFF bytes.
///
/// -
/// SASL_OPTION_SEND_SIZE
///
/// Data type of buffer: ULONG Maximum message data size that can be transmitted. This value is the maximum buffer size that can be
/// transmitted to the remote SASL process minus the block size, the trailer size, and the maximum signature size. The default value
/// is 0x0FFFF bytes.
///
///
///
///
///
/// A pointer to a buffer that contains the value to set to the requested property. For the data type of the buffer for each value of
/// the Option parameter, see the Option parameter.
///
/// The size, in bytes, of the buffer specified by the Value parameter.
///
///
/// If the call is completed successfully, this function returns SEC_E_OK. The following table shows some possible error return values.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_BUFFER_TOO_SMALL
///
/// The buffer specified by the Value parameter is not large enough to contain the data value of the property specified by the Option parameter.
///
///
/// -
/// SEC_E_INVALID_HANDLE
/// The SASL context handle specified by the ContextHandle parameter was not found in the SASL list.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
/// The option specified in the Option parameter is not valid.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslsetcontextoption SECURITY_STATUS SEC_ENTRY
// SaslSetContextOption( PCtxtHandle ContextHandle, ULONG Option, PVOID Value, ULONG Size );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "3c3b1209-b0de-4100-8dfe-53ea314b790b")]
public static extern HRESULT SaslSetContextOption(in CtxtHandle ContextHandle, SASL_OPTION Option, [MarshalAs(UnmanagedType.LPWStr)] string Value, uint Size);
/// The SaslSetContextOption function sets the value of the specified property for the specified SASL context.
/// Handle of the SASL context.
///
/// Property to set for the SASL context. The following table lists the possible values.
///
///
/// Value
/// Meaning
///
/// -
/// SASL_OPTION_AUTHZ_PROCESSING
///
/// Data type of buffer: ULONG State of SASL processing of the Authz value provided by the SASL application. The valid states for
/// processing are Sasl_AuthZIDForbidden and Sasl_AuthZIDProcessed. The default value is Sasl_AuthZIDProcessed.
///
///
/// -
/// SASL_OPTION_AUTHZ_STRING
///
/// Data type of buffer: Array of binary characters String of characters passed from the SASL client to the server. If the
/// AuthZ_Processing state is Sasl_AuthZIDForbidden, the return value SEC_E_UNSUPPORTED_FUNCTION is returned.
///
///
/// -
/// SASL_OPTION_RECV_SIZE
/// Data type of buffer: ULONG Maximum size of the receiving buffer on the local computer. The default value is 0x0FFFF bytes.
///
/// -
/// SASL_OPTION_SEND_SIZE
///
/// Data type of buffer: ULONG Maximum message data size that can be transmitted. This value is the maximum buffer size that can be
/// transmitted to the remote SASL process minus the block size, the trailer size, and the maximum signature size. The default value
/// is 0x0FFFF bytes.
///
///
///
///
///
/// A pointer to a buffer that contains the value to set to the requested property. For the data type of the buffer for each value of
/// the Option parameter, see the Option parameter.
///
/// The size, in bytes, of the buffer specified by the Value parameter.
///
///
/// If the call is completed successfully, this function returns SEC_E_OK. The following table shows some possible error return values.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_BUFFER_TOO_SMALL
///
/// The buffer specified by the Value parameter is not large enough to contain the data value of the property specified by the Option parameter.
///
///
/// -
/// SEC_E_INVALID_HANDLE
/// The SASL context handle specified by the ContextHandle parameter was not found in the SASL list.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
/// The option specified in the Option parameter is not valid.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-saslsetcontextoption SECURITY_STATUS SEC_ENTRY
// SaslSetContextOption( PCtxtHandle ContextHandle, ULONG Option, PVOID Value, ULONG Size );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "3c3b1209-b0de-4100-8dfe-53ea314b790b")]
public static extern HRESULT SaslSetContextOption(in CtxtHandle ContextHandle, SASL_OPTION Option, in uint Value, uint Size = 4);
///
/// Enables a transport application to set attributes of a security context for a security package. This function is supported only
/// by the Schannel security package.
///
/// A handle to the security context to be set.
///
/// The attribute of the context to be set. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_ATTR_APP_DATA 94
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_SessionAppData structure. Sets application data for the session. This
/// attribute is supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_EAP_PRF_INFO 101
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_EapPrfInfo structure. Sets the pseudo-random function (PRF) used by
/// the Extensible Authentication Protocol (EAP). This is the value that is returned by a call to the QueryContextAttributes
/// (Schannel) function when SECPKG_ATTR_EAP_KEY_BLOCK is passed as the value of the ulAttribute parameter. This attribute is
/// supported only by the Schannel security package.
///
///
/// -
/// SECPKG_ATTR_EARLY_START 105
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_EarlyStart structure. Sets the False Start feature. See the Building
/// a faster and more secure web blog post for information on this feature.
///
///
/// -
/// SECPKG_ATTR_DTLS_MTU 34
///
/// Sets and retrieves the MTU (maximum transmission unit) value for use with DTLS. If DTLS is not enabled in a security context,
/// this attribute is not supported. Valid values are between 200 bytes and 64 kilobytes. The default DTLS MTU value in Schannel is
/// 1096 bytes.
///
///
/// -
/// SECPKG_ATTR_KEYING_MATERIAL_INFO 106
///
/// The pBuffer parameter contains a pointer to a SecPkgContext_KeyingMaterialInfo structure. The keying material export feature
/// follows the RFC 5705 standard. This attribute is supported only by the Schannel security package in Windows 10 and Windows Server
/// 2016 or later versions.
///
///
///
///
///
/// A pointer to a structure that contains values to set the attributes to. The type of structure pointed to depends on the value
/// specified in the ulAttribute parameter.
///
/// The size, in bytes, of the pBuffer parameter.
///
/// If the function succeeds, the function returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code. The following error code is one of the possible error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
/// This value is returned by Schannel kernel mode to indicate that this function is not supported.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-setcontextattributesa SECURITY_STATUS SEC_ENTRY
// SetContextAttributesA( PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer, unsigned long cbBuffer );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "e3246c3e-3e8c-49fe-99d8-dfff1a10ab83")]
public static extern HRESULT SetContextAttributes(in CtxtHandle phContext, SECPKG_ATTR ulAttribute, IntPtr pBuffer, uint cbBuffer);
///
/// Sets the attributes of a credential, such as the name associated with the credential. The information is valid for any security
/// context created with the specified credential.
///
/// A handle of the credentials to be set.
///
/// Specifies the attribute to set. This parameter can be any of the following attributes.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_CRED_ATTR_NAMES
///
/// Sets the name of a credential in a pBuffer parameter of type SecPkgCredentials_Names. This attribute is not supported by Schannel
/// in WOW64 mode.
///
///
/// -
/// SECPKG_CRED_ATTR_KDC_PROXY_SETTINGS
///
/// Sets the Kerberos proxy setting in a pBuffer parameter of type SecPkgCredentials_KdcProxySettings. This attribute is only
/// supported by Kerberos.
///
///
/// -
/// SECPKG_ATTR_SUPPORTED_ALGS
///
/// Sets the supported algorithms in a pBuffer parameter of type SecPkgCred_SupportedAlgs. All supported algorithms are included,
/// regardless of whether they are supported by the provided certificate or enabled on the local computer. This attribute is
/// supported only by Schannel.
///
///
/// -
/// SECPKG_ATTR_CIPHER_STRENGTHS
///
/// Sets the cipher strengths in a pBuffer parameter of type SecPkgCred_CipherStrengths. This attribute is supported only by Schannel.
///
///
/// -
/// SECPKG_ATTR_SUPPORTED_PROTOCOLS
///
/// Sets the supported algorithms in a pBuffer parameter of type SecPkgCred_SupportedProtocols. All supported protocols are included,
/// regardless of whether they are supported by the provided certificate or enabled on the local computer. This attribute is
/// supported only by Schannel.
///
///
///
///
///
/// A pointer to a buffer that contains the new attribute value. The type of structure returned depends on the value of ulAttribute.
///
/// The size, in bytes, of the pBuffer buffer.
///
/// If the function succeeds, the return value is SEC_E_OK.
/// If the function fails, the return value may be one of the following error codes.
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_INVALID_HANDLE
/// The handle passed to the function is not valid.
///
/// -
/// SEC_E_UNSUPPORTED_FUNCTION
///
/// The specified attribute is not supported by Schannel. This return value will only be returned when the Schannel SSP is being used.
///
///
/// -
/// SEC_E_INSUFFICIENT_MEMORY
/// Not enough memory is available to complete the request.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-setcredentialsattributesa SECURITY_STATUS SEC_ENTRY
// SetCredentialsAttributesA( PCredHandle phCredential, unsigned long ulAttribute, void *pBuffer, unsigned long cbBuffer );
[DllImport(Lib.Secur32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("sspi.h", MSDNShortId = "419fb4f0-3dd1-4473-aeb2-8024355e0c1c")]
public static extern HRESULT SetCredentialsAttributes(in CredHandle phCredential, SECPKG_CRED_ATTR ulAttribute, IntPtr pBuffer, uint cbBuffer);
///
/// Compares the two specified credentials.
///
///
/// A pointer to an opaque structure that specifies the first credential to compare.
///
///
/// A pointer to an opaque structure that specifies the second credential to compare.
///
///
///
/// TRUE if the user account specified by the AuthIdentity1 parameter is the same as the user account specified by the
/// AuthIdentity2 parameter; otherwise, FALSE.
///
///
///
///
/// TRUE if the identity specified by the AuthIdentity1 parameter is the same as the identity specified by the AuthIdentity2
/// parameter; otherwise, FALSE.
///
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspicompareauthidentities SECURITY_STATUS SEC_ENTRY
// SspiCompareAuthIdentities( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity2, PBOOLEAN
// SameSuppliedUser, PBOOLEAN SameSuppliedIdentity );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "d2c4f363-3d86-48f0-bae1-4f9240d68bab")]
public static extern Win32Error SspiCompareAuthIdentities(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity2,
[MarshalAs(UnmanagedType.U1)] out bool SameSuppliedUser, [MarshalAs(UnmanagedType.U1)] out bool SameSuppliedIdentity);
///
/// Creates a copy of the specified opaque credential structure.
///
///
/// The credential structure to be copied.
///
///
/// The structure that receives the copy of the structure specified by the AuthData parameter.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspicopyauthidentity SECURITY_STATUS SEC_ENTRY
// SspiCopyAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData, PSEC_WINNT_AUTH_IDENTITY_OPAQUE *AuthDataCopy );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "e53807bf-b5a1-4479-a73b-dd85c5da173e")]
public static extern Win32Error SspiCopyAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData, out SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthDataCopy);
///
/// Decrypts the specified encrypted credential.
///
///
///
/// On input, a pointer to the encrypted credential structure to be decrypted. On output, a pointer to the decrypted credential structure.
///
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspidecryptauthidentity SECURITY_STATUS SEC_ENTRY
// SspiDecryptAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "aef0206c-c376-4877-b1a6-5e86d2e35dea")]
public static extern Win32Error SspiDecryptAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData);
/// Decrypts a SEC_WINNT_AUTH_IDENTITY_OPAQUE structure.
///
///
/// Decryption options. This parameter should be the same value as the value passed to the SspiEncryptAuthIdentityEx function, which
/// can be one of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON
///
/// The encrypted structure can only be decrypted by a security context in the same logon session. This option is used to protect an
/// identity buffer that is being sent over a local RPC.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_PROCESS
///
/// The encrypted structure can only be decrypted by the same process. Calling the function with this option is equivalent to calling
/// SspiEncryptAuthIdentity. This option is used to protect an identity buffer that is being persisted in a process's private memory
/// for an extended period.
///
///
///
///
/// This buffer is the output of the SspiEncryptAuthIdentityEx function.
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspidecryptauthidentityex SECURITY_STATUS SEC_ENTRY
// SspiDecryptAuthIdentityEx( ULONG Options, PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData );
[DllImport(Lib.SspiCli, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "86598BAA-0E87-46A9-AA1A-BF04BF0CDAFA")]
public static extern HRESULT SspiDecryptAuthIdentityEx(SEC_WINNT_AUTH_IDENTITY_ENCRYPT Options, PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData);
///
/// Encodes the specified authentication identity as three strings.
///
///
/// The credential structure to be encoded.
///
///
/// The marshaled user name of the identity specified by the pAuthIdentity parameter.
/// When you have finished using this string, free it by calling the SspiFreeAuthIdentity function.
///
///
/// The marshaled domain name of the identity specified by the pAuthIdentity parameter.
/// When you have finished using this string, free it by calling the SspiFreeAuthIdentity function.
///
///
/// An encoded string version of a SEC_WINNT_AUTH_IDENTITY_EX2 structure that specifies the users credentials.
/// When you have finished using this string, free it by calling the SspiFreeAuthIdentity function.
///
///
/// If the function succeeds, it returns SEC_E_OK.
///
/// If the function fails, it returns a nonzero error code. Possible values include, but are not limited to, those in the following table.
///
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_INVALID_PARAMETER 0xC000000D
///
/// The SEC_WINNT_AUTH_IDENTITY_FLAGS_PROCESS_ENCRYPTED flag is set in the identity structure specified by the pAuthIdentity parameter.
///
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiencodeauthidentityasstrings SECURITY_STATUS SEC_ENTRY
// SspiEncodeAuthIdentityAsStrings( PSEC_WINNT_AUTH_IDENTITY_OPAQUE pAuthIdentity, PCWSTR *ppszUserName, PCWSTR *ppszDomainName,
// PCWSTR *ppszPackedCredentialsString );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "0610a7b8-67e9-4c01-893f-da579eeea2f8")]
public static extern Win32Error SspiEncodeAuthIdentityAsStrings([In] PSEC_WINNT_AUTH_IDENTITY_OPAQUE pAuthIdentity,
[Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SspiStringMarshaler))] out string ppszUserName,
[Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SspiStringMarshaler))] out string ppszDomainName,
[Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SspiStringMarshaler))] out string ppszPackedCredentialsString);
///
/// Encodes a set of three credential strings as an authentication identity structure.
///
///
/// The user name associated with the identity to encode.
///
///
/// The domain name associated with the identity to encode.
///
///
/// An encoded string version of a SEC_WINNT_AUTH_IDENTITY_EX2 structure that specifies the user's credentials.
///
///
/// A pointer to the encoded identity structure.
/// When you have finished using this structure, free it by calling the SspiFreeAuthIdentity function.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiencodestringsasauthidentity SECURITY_STATUS SEC_ENTRY
// SspiEncodeStringsAsAuthIdentity( PCWSTR pszUserName, PCWSTR pszDomainName, PCWSTR pszPackedCredentialsString,
// PSEC_WINNT_AUTH_IDENTITY_OPAQUE *ppAuthIdentity );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "0aea2f00-fcf1-4c4e-a22f-a669dd4fb294")]
public static extern Win32Error SspiEncodeStringsAsAuthIdentity([MarshalAs(UnmanagedType.LPWStr)] string pszUserName, [MarshalAs(UnmanagedType.LPWStr)] string pszDomainName,
[MarshalAs(UnmanagedType.LPWStr)] string pszPackedCredentialsString, out SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE ppAuthIdentity);
///
/// Encrypts the specified identity structure.
///
///
/// On input, the identity structure to encrypt. On output, the encrypted identity structure.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiencryptauthidentity SECURITY_STATUS SEC_ENTRY
// SspiEncryptAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "4460f7ec-35fd-4ad1-8c20-dda9f4d3477a")]
public static extern Win32Error SspiEncryptAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData);
/// Encrypts a SEC_WINNT_AUTH_IDENTITY_OPAQUE structure.
///
/// Encryption options. This can be one or more of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON
///
/// The encrypted structure can only be decrypted by a security context in the same logon session. This option is used to protect an
/// identity buffer that is being sent over a local RPC.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_PROCESS
///
/// The encrypted structure can only be decrypted by the same process. Calling the function with this option is equivalent to calling
/// SspiEncryptAuthIdentity. This option is used to protect an identity buffer that is being persisted in a process's private memory
/// for an extended period.
///
///
///
///
///
/// On input, a pointer to an identity buffer to encrypt. This buffer must be prepared for encryption prior to the call to this
/// function. This can be done by calling the function SspiEncryptAuthIdentity. On output, the encrypted identity buffer.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
///
/// To transfer credentials securely across processes, applications typically call this function with the
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON option, followed by SspiMarshalAuthIdentity to obtain a marshaled authentication
/// buffer and its length. For example, Online Identity Credential Provider does this to return the authentication buffer from their
/// ICredentialProviderCredential::GetSerialization method.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiencryptauthidentityex SECURITY_STATUS SEC_ENTRY
// SspiEncryptAuthIdentityEx( ULONG Options, PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData );
[DllImport(Lib.SspiCli, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "9290BEF8-24C9-47F0-B258-56ED7D67620B")]
public static extern HRESULT SspiEncryptAuthIdentityEx(SEC_WINNT_AUTH_IDENTITY_ENCRYPT Options, PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData);
///
///
/// Creates a new identity structure that is a copy of the specified identity structure modified to exclude the specified security
/// support provider (SSP).
///
///
///
/// The identity structure to modify.
///
///
/// The SSP to exclude.
///
///
/// The modified identity structure.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiexcludepackage SECURITY_STATUS SEC_ENTRY SspiExcludePackage(
// PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, PCWSTR pszPackageName, PSEC_WINNT_AUTH_IDENTITY_OPAQUE *ppNewAuthIdentity );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "2f85bb13-b72a-4c26-a328-9424a33a63b8")]
public static extern Win32Error SspiExcludePackage(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, [MarshalAs(UnmanagedType.LPWStr)] string pszPackageName, out SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE ppNewAuthIdentity);
///
/// Frees the memory allocated for the specified identity structure.
///
///
/// The identity structure to free.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspifreeauthidentity VOID SEC_ENTRY SspiFreeAuthIdentity(
// PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "6199f66e-7adb-4bb9-8e77-a735e31dd5f6")]
public static extern void SspiFreeAuthIdentity(IntPtr AuthData);
///
/// Gets the host name associated with the specified target.
///
///
/// The target for which to get the host name.
///
///
/// The name of the host associated with the target specified by the pszTargetName parameter.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspigettargethostname SECURITY_STATUS SEC_ENTRY
// SspiGetTargetHostName( PCWSTR pszTargetName, PWSTR *pszHostName );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "84570dfc-1890-4b82-b411-1f9eaa75537b")]
public static extern Win32Error SspiGetTargetHostName([MarshalAs(UnmanagedType.LPWStr)] string pszTargetName, [MarshalAs(UnmanagedType.LPWStr)] out string pszHostName);
///
/// Indicates whether the specified identity structure is encrypted.
///
///
/// The identity structure to test.
///
///
/// TRUE if the identity structure specified by the EncryptedAuthData parameter is encrypted; otherwise, FALSE.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiisauthidentityencrypted BOOLEAN SEC_ENTRY
// SspiIsAuthIdentityEncrypted( PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "b85095f5-0ca5-4d75-866d-9b756404c1d9")]
[return: MarshalAs(UnmanagedType.U1)]
public static extern bool SspiIsAuthIdentityEncrypted(PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData);
///
/// Frees the memory associated with the specified buffer.
///
///
/// The buffer to free.
///
///
/// This function does not return a value.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspilocalfree VOID SEC_ENTRY SspiLocalFree( PVOID DataBuffer );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "afb890a8-a2c3-4c35-ba76-758b047ababb")]
public static extern void SspiLocalFree(IntPtr DataBuffer);
///
/// Serializes the specified identity structure into a byte array.
///
///
/// The identity structure to serialize.
///
///
/// The length, in bytes, of the AuthIdentityByteArray array.
///
///
/// A pointer to an array of byte values that represents the identity specified by the AuthIdentity parameter.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspimarshalauthidentity SECURITY_STATUS SEC_ENTRY
// SspiMarshalAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, unsigned long *AuthIdentityLength, char
// **AuthIdentityByteArray );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "e43135ad-7fcd-4da6-a4e4-c91c41eeb865")]
public static extern Win32Error SspiMarshalAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, out uint AuthIdentityLength, out SafeSspiLocalMem AuthIdentityByteArray);
///
/// Generates a target name and credential type from the specified identity structure.
///
/// The values that this function generates can be passed as the values of the TargetName and Type parameters in a call to the
/// CredRead function.
///
///
///
/// The identity structure from which to generate the credentials to be passed to the CredRead function.
///
///
/// A target name that can be modified by this function depending on the value of the AuthIdentity parameter.
///
///
/// The credential type to pass to the CredRead function.
///
///
/// The target name to pass to the CredRead function.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiprepareforcredread SECURITY_STATUS SEC_ENTRY
// SspiPrepareForCredRead( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, PCWSTR pszTargetName, PULONG pCredmanCredentialType, PCWSTR
// *ppszCredmanTargetName );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("sspi.h", MSDNShortId = "f473fd7a-5c0f-4a77-829b-28a82ad0d28d")]
public static extern Win32Error SspiPrepareForCredRead(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, string pszTargetName, out CRED_TYPE pCredmanCredentialType, out string ppszCredmanTargetName);
///
///
/// Generates values from an identity structure that can be passed as the values of parameters in a call to the CredWrite function.
///
///
///
/// The identity structure from which to generate the credentials to be passed to the CredWrite function.
///
///
/// A target name that can be modified by this function depending on the value of the AuthIdentity parameter.
/// Set the value of this parameter to NULL to use the user name as the target.
///
///
/// The credential type to pass to the CredWrite function.
///
///
/// The target name to pass to the CredWrite function.
///
///
/// The user name to pass to the CredWrite function.
///
///
/// The credential BLOB to send to the CredWrite function.
///
///
/// The size, in bytes, of the ppCredentialBlob buffer.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiprepareforcredwrite SECURITY_STATUS SEC_ENTRY
// SspiPrepareForCredWrite( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, PCWSTR pszTargetName, PULONG pCredmanCredentialType, PCWSTR
// *ppszCredmanTargetName, PCWSTR *ppszCredmanUserName, PUCHAR *ppCredentialBlob, PULONG pCredentialBlobSize );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("sspi.h", MSDNShortId = "4db92042-38f2-42c2-9c94-b24e0eaafdf9")]
public static extern Win32Error SspiPrepareForCredWrite(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, string pszTargetName, out CRED_TYPE pCredmanCredentialType, out string ppszCredmanTargetName, out string ppszCredmanUserName,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 6)] out byte[] ppCredentialBlob, out uint pCredentialBlobSize);
///
/// Deserializes the specified array of byte values into an identity structure.
///
///
/// The size, in bytes, of the AuthIdentityByteArray array.
///
///
/// The array of byte values to deserialize.
///
///
/// The deserialized identity structure.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspiunmarshalauthidentity SECURITY_STATUS SEC_ENTRY
// SspiUnmarshalAuthIdentity( unsigned long AuthIdentityLength, char *AuthIdentityByteArray, PSEC_WINNT_AUTH_IDENTITY_OPAQUE
// *ppAuthIdentity );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "89798b37-808a-4174-8362-a2dc4ee1b460")]
public static extern Win32Error SspiUnmarshalAuthIdentity(uint AuthIdentityLength, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] AuthIdentityByteArray, out SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE ppAuthIdentity);
///
/// Indicates whether the specified identity structure is valid.
///
///
/// The identity structure to test.
///
///
///
/// If the function succeeds, it returns SEC_E_OK, which indicates that the identity structure specified by the AuthData
/// parameter is valid.
///
///
/// If the function fails, it returns a nonzero error code that indicates that the identity structure specified by the AuthData
/// parameter is not valid.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspivalidateauthidentity SECURITY_STATUS SEC_ENTRY
// SspiValidateAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "82733abd-d984-4902-b6e4-c3809171ad51")]
public static extern Win32Error SspiValidateAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData);
///
/// Fills the block of memory associated with the specified identity structure with zeros.
///
///
/// The identity structure to fill with zeros.
///
///
/// If the function succeeds, it returns SEC_E_OK.
/// If the function fails, it returns a nonzero error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-sspizeroauthidentity VOID SEC_ENTRY SspiZeroAuthIdentity(
// PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "50b1f24a-c802-4691-a450-316cb31bf44d")]
public static extern void SspiZeroAuthIdentity(PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData);
///
/// Verifies that a message signed by using the MakeSignature function was received in the correct sequence and has not been modified.
///
/// A handle to the security context to use for the message.
///
/// Pointer to a SecBufferDesc structure that references a set of SecBuffer structures that contain the message and signature to
/// verify. The signature is in a SecBuffer structure of type SECBUFFER_TOKEN.
///
///
/// Specifies the sequence number expected by the transport application, if any. If the transport application does not maintain
/// sequence numbers, this parameter is zero.
///
///
/// Pointer to a ULONG variable that receives package-specific flags that indicate the quality of protection.
/// Some security packages ignore this parameter.
///
///
///
/// If the function verifies that the message was received in the correct sequence and has not been modified, the return value is SEC_E_OK.
///
///
/// If the function determines that the message is not correct according to the information in the signature, the return value can be
/// one of the following error codes.
///
///
///
/// Return code
/// Description
///
/// -
/// SEC_E_OUT_OF_SEQUENCE
/// The message was not received in the correct sequence.
///
/// -
/// SEC_E_MESSAGE_ALTERED
/// The message has been altered.
///
/// -
/// SEC_E_INVALID_HANDLE
/// The context handle specified by phContext is not valid.
///
/// -
/// SEC_E_INVALID_TOKEN
/// pMessage did not contain a valid SECBUFFER_TOKEN buffer, or contained too few buffers.
///
/// -
/// SEC_E_QOP_NOT_SUPPORTED
/// The quality of protection negotiated between the client and server did not include integrity checking.
///
///
///
///
/// Warning The VerifySignature function will fail if the message was signed using the RsaSignPssSha512 algorithm on a
/// different version of Windows. For example, a message that was signed by calling the MakeSignature function on Windows 8 will
/// cause the VerifySignature function on Windows 8.1 to fail.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-verifysignature KSECDDDECLSPEC SECURITY_STATUS SEC_ENTRY
// VerifySignature( PCtxtHandle phContext, PSecBufferDesc pMessage, unsigned long MessageSeqNo, unsigned long *pfQOP );
[DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("sspi.h", MSDNShortId = "bebeef92-1d6e-4879-846f-12d706db0653")]
public static extern HRESULT VerifySignature(in CtxtHandle phContext, in SecBufferDesc pMessage, uint MessageSeqNo, out SECQOP pfQOP);
/// Provides a handle to a auth identity.
[StructLayout(LayoutKind.Sequential)]
public struct PSEC_WINNT_AUTH_IDENTITY_OPAQUE : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static PSEC_WINNT_AUTH_IDENTITY_OPAQUE NULL => new PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(PSEC_WINNT_AUTH_IDENTITY_OPAQUE h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator PSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr h) => new PSEC_WINNT_AUTH_IDENTITY_OPAQUE(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(PSEC_WINNT_AUTH_IDENTITY_OPAQUE h1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(PSEC_WINNT_AUTH_IDENTITY_OPAQUE h1, PSEC_WINNT_AUTH_IDENTITY_OPAQUE h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is PSEC_WINNT_AUTH_IDENTITY_OPAQUE h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Allows you to pass a particular user name and password to the run-time library for the purpose of authentication.
///
/// When this structure is used with RPC, the structure must remain valid for the lifetime of the binding handle.
/// The strings may be ANSI or Unicode, depending on the value you assign to the Flags member.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_sec_winnt_auth_identity_a typedef struct
// _SEC_WINNT_AUTH_IDENTITY_A { unsigned char *User; unsigned long UserLength; unsigned char *Domain; unsigned long DomainLength;
// unsigned char *Password; unsigned long PasswordLength; unsigned long Flags; } SEC_WINNT_AUTH_IDENTITY_A, *PSEC_WINNT_AUTH_IDENTITY_A;
[PInvokeData("sspi.h", MSDNShortId = "a9c9471b-2134-4173-af86-18b277627d2a")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SEC_WINNT_AUTH_IDENTITY
{
/// A string that contains the user name.
[MarshalAs(UnmanagedType.LPTStr)]
public string User;
/// The length, in characters, of the user string, not including the terminating null character.
public int UserLength;
/// A string that contains the domain name or the workgroup name.
[MarshalAs(UnmanagedType.LPTStr)]
public string Domain;
/// The length, in characters, of the domain string, not including the terminating null character.
public int DomainLength;
///
/// A string that contains the password of the user in the domain or workgroup. When you have finished using the password, remove
/// the sensitive information from memory by calling SecureZeroMemory. For more information about protecting the password, see
/// Handling Passwords.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string Password;
/// The length, in characters, of the password string, not including the terminating null character.
public int PasswordLength;
///
/// This member can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ANSI
/// The strings in this structure are in ANSI format.
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_UNICODE
/// The strings in this structure are in Unicode format.
///
///
///
public int Flags;
/// Initializes a new instance of the struct.
/// The user name.
/// The domain name or the workgroup name.
/// The password of the user in the domain or workgroup.
public SEC_WINNT_AUTH_IDENTITY(string user, string domain, string password)
{
User = user;
UserLength = user?.Length ?? 0;
Domain = domain;
DomainLength = domain?.Length ?? 0;
Password = password;
PasswordLength = password?.Length ?? 0;
Flags = StringHelper.GetCharSize();
}
}
///
/// The SEC_WINNT_AUTH_IDENTITY_EX structure contains information about a user. Both an ANSI and Unicode form of this
/// structure are provided.
///
///
/// Note that when this structure is used with RPC, the structure must remain valid for the lifetime of the binding handle.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_sec_winnt_auth_identity_exa typedef struct
// _SEC_WINNT_AUTH_IDENTITY_EXA { unsigned long Version; unsigned long Length; unsigned char *User; unsigned long UserLength;
// unsigned char *Domain; unsigned long DomainLength; unsigned char *Password; unsigned long PasswordLength; unsigned long Flags;
// unsigned char *PackageList; unsigned long PackageListLength; } SEC_WINNT_AUTH_IDENTITY_EXA, *PSEC_WINNT_AUTH_IDENTITY_EXA;
[PInvokeData("sspi.h", MSDNShortId = "6b95bce8-5613-4403-9bda-16262596bb1b")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SEC_WINNT_AUTH_IDENTITY_EX
{
/// An unsigned long that indicates the version number of the structure.
public uint Version;
/// An unsigned long that indicates the length, in bytes, of the structure.
public uint Length;
/// A Unicode or ANSI string that contains the name of the user account.
[MarshalAs(UnmanagedType.LPTStr)]
public string User;
/// The length, in characters, of the User string.
public uint UserLength;
/// A Unicode or ANSI string that contains the name of the domain for the user account.
[MarshalAs(UnmanagedType.LPTStr)]
public string Domain;
/// The length, in characters, of the Domain string.
public uint DomainLength;
///
/// A Unicode or ANSI string that contains the user password in plaintext. When you have finished using the password, remove the
/// sensitive information from memory by calling the SecureZeroMemory function. For more information about protecting the
/// password, see Handling Passwords.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string Password;
/// The length, in characters, of the Password string.
public uint PasswordLength;
///
/// An unsigned long flag that indicates the type used by negotiable security packages.
///
///
/// Value
/// Meaning
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_MARSHALLED
/// All data is in one buffer.
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ONLY
///
/// Used with the Kerberos security support provider (SSP). Credentials are for identity only. The Kerberos package is directed
/// to not include authorization data in the ticket.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ANSI
/// Credentials are in ANSI form.
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_UNICODE
/// Credentials are in Unicode form.
///
///
///
public SEC_WINNT_AUTH_IDENTITY_FLAGS Flags;
///
///
/// A Unicode or ANSI string that contains a comma-separated list of names of security packages that are available when using the
/// Microsoft Negotiate provider.
///
/// Set this to "!ntlm" to specify that the NTLM package is not to be used.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string PackageList;
/// The length, in characters, of the PackageList string.
public uint PackageListLength;
}
///
/// Contains information about an authentication identity. The SEC_WINNT_AUTH_IDENTITY_EX2 structure contains authentication
/// data that is provided to the AcquireCredentialsHandle function.
///
///
///
/// This authentication identity buffer can be returned from several credential APIs, for example, the GetSerialization method and
/// the CredUIPromptForWindowsCredential and SspiPromptForCredentials functions.
///
///
/// The structure describes a header of the authentication identity buffer and the data is appended at the end of the structure.
/// Although the buffer size is specified by the cbStructureLength member, the actual buffer size can be larger or smaller
/// than cbStructureLength. Some functions, such as SspiValidateAuthIdentity, take a pointer, but not the buffer size, to the
/// identity structure as input. As a result, those functions can validate the internal buffer data but cannot verify the buffer
/// size. This can result in reading or writing data outside of the buffer range. To avoid buffer overruns when handling an untrusted
/// identity buffer, applications should call SspiUnmarshalAuthIdentity to obtain a pointer to an identity structure with a validated
/// size and then pass that pointer to the functions.
///
///
/// The SEC_WINNT_AUTH_IDENTITY_EX2 structure can be returned by QueryContextAttributes(CredSSP) and consumed by
/// AcquireCredentialsHandle(CredSSP), LsaLogonUser, and other identity provider interfaces.
///
///
/// SEC_WINNT_AUTH_PACKED_CREDENTIALS can contain a password credential type, defined as SEC_WINNT_AUTH_DATA_TYPE_PASSWORD. This
/// credential type describes password credentials of a domain user as well as other online identities. Applications must define
/// _SEC_WINNT_AUTH_TYPES to compile code that references this credential type as well as other definitions of the
/// SEC_WINNT_AUTH_PACKED_CREDENTIALS structure.
///
///
/// Applications should not query or set the Flags member directly. Use the SspiIsAuthIdentityEncrypted,
/// SspiEncryptAuthIdentityEx, and SspiDecryptAuthIdentityEx functions to manage the encryption and decryption of the
/// SEC_WINNT_AUTH_IDENTITY_EX2 structure.
///
///
/// Identity providers must explicitly check or set SEC_WINNT_AUTH_IDENTITY_FLAGS_ID_PROVIDER and the domain name fields to
/// differentiate their password credential from a domain password and another identity provider's password.
///
///
/// The CredPackAuthenticationBuffer function can be called with the CRED_PACK_ID_PROVIDER_CREDENTIALS option to create a
/// SEC_WINNT_AUTH_IDENTITY_EX2 structure with the authentication data of SEC_WINNT_AUTH_DATA_TYPE_PASSWORD credential type, a
/// Flags member that contains the SEC_WINNT_AUTH_IDENTITY_FLAGS_ID_PROVIDER value, and a DomainOffset member set to
/// the provider name.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-sec_winnt_auth_identity_ex2 typedef struct
// _SEC_WINNT_AUTH_IDENTITY_EX2 { unsigned long Version; unsigned short cbHeaderLength; unsigned long cbStructureLength; unsigned
// long UserOffset; unsigned short UserLength; unsigned long DomainOffset; unsigned short DomainLength; unsigned long
// PackedCredentialsOffset; unsigned short PackedCredentialsLength; unsigned long Flags; unsigned long PackageListOffset; unsigned
// short PackageListLength; } SEC_WINNT_AUTH_IDENTITY_EX2, *PSEC_WINNT_AUTH_IDENTITY_EX2;
[PInvokeData("sspi.h", MSDNShortId = "a6083d76-1774-428c-85ca-fea817827d6a")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SEC_WINNT_AUTH_IDENTITY_EX2
{
/// The version number of the structure. This must be SEC_WINNT_AUTH_IDENTITY_VERSION_2.
public uint Version;
/// The size, in bytes, of the structure header.
public ushort cbHeaderLength;
/// The size, in bytes, of the structure.
public uint cbStructureLength;
/// The offset from the beginning of the structure to the beginning of the user name string.
public uint UserOffset;
/// The size, in bytes, of the user name string.
public ushort UserLength;
///
/// The offset from the beginning of the structure to the beginning of the domain name string.
/// An identity credential should contain the identity provider name instead of the domain name.
///
public uint DomainOffset;
/// The size, in bytes, of the domain name string.
public ushort DomainLength;
///
/// The offset from the beginning of the structure to the beginning of the packed credentials.
///
/// The packed credential is a SEC_WINNT_AUTH_PACKED_CREDENTIALS structure that contains a credential type that uniquely
/// specifies the credential type.
///
///
public uint PackedCredentialsOffset;
/// The size, in bytes, of the packed credentials string.
public ushort PackedCredentialsLength;
///
/// An unsigned long flag that indicates the type used by negotiable security packages.
///
///
/// Value
/// Meaning
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_MARSHALLED 4 (0x4)
/// All data is in one buffer.
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ONLY 8 (0x8)
///
/// Used with the Kerberos security support provider (SSP). Credentials are for identity only. The Kerberos package is directed
/// to not include authorization data in the ticket.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_ANSI 1 (0x1)
/// Credentials are in ANSI form.
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_UNICODE 2 (0x2)
/// Credentials are in Unicode form.
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_FLAGS_ID_PROVIDER 524288 (0x80000)
///
/// When the credential type is password, the presence of this flag specifies that the structure is an online ID credential. The
/// DomainOffset and DomainLength members correspond to the online ID provider name. Windows Server 2008 R2 and Windows 7: This
/// flag is not supported.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_FLAGS_PROCESS_ENCRYPTED 16 (0x10)
///
/// The structure is encrypted by the SspiEncryptAuthIdentity function or by the SspiEncryptAuthIdentityEx function with the
/// SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_PROCESS option. It can only be decrypted by the same process. Windows Server 2008 R2 and
/// Windows 7: This flag is not supported.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_FLAGS_SYSTEM_PROTECTED 32 (0x20)
///
/// The structure is encrypted by the SspiEncryptAuthIdentityEx function with the SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON
/// option under the SYSTEM security context. It can only be decrypted by a thread running as SYSTEM. Windows Server 2008 R2 and
/// Windows 7: This flag is not supported.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_FLAGS_USER_PROTECTED 64 (0x40)
///
/// The structure is encrypted by the SspiEncryptAuthIdentityEx function with the SEC_WINNT_AUTH_IDENTITY_ENCRYPT_SAME_LOGON
/// option under a non-SYSTEM security context. It can only be decrypted by a thread running in the same logon session in which
/// it was encrypted. Windows Server 2008 R2 and Windows 7: This flag is not supported.
///
///
/// -
/// SEC_WINNT_AUTH_IDENTITY_FLAGS_RESERVED 65536 (0x10000)
///
/// The authentication identity buffer is cbStructureLength + 8 padding bytes that are necessary for in-place encryption or
/// decryption of the identity.
///
///
///
///
public SEC_WINNT_AUTH_IDENTITY_FLAGS Flags;
/// The offset from the beginning of the structure to the beginning of the list of supported packages.
public uint PackageListOffset;
/// The size, in bytes, of the supported package list.
public ushort PackageListLength;
}
/// The SecBuffer structure describes a buffer allocated by a transport application to pass to a security package.
[StructLayout(LayoutKind.Sequential)]
public struct SecBuffer
{
/// Specifies the size, in bytes, of the buffer pointed to by the pvBuffer member.
public int cbBuffer;
/// Bit flags that indicate the type of buffer. Must be one of the values of the SecBufferType enumeration.
public SecBufferType BufferType;
/// A pointer to a buffer.
public IntPtr pvBuffer;
/// Initializes a new instance of the struct.
/// The type of buffer.
/// A pointer to an allocated buffer.
/// Size of the allocated buffer.
public SecBuffer(SecBufferType type, IntPtr buffer = default, int bufferSize = 0)
{
cbBuffer = bufferSize;
BufferType = type;
pvBuffer = buffer;
}
}
///
/// The SecBufferDesc structure describes an array of SecBuffer structures to pass from a transport application to a security package.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secbufferdesc typedef struct _SecBufferDesc { unsigned long
// ulVersion; unsigned long cBuffers; PSecBuffer pBuffers; } SecBufferDesc, *PSecBufferDesc;
[PInvokeData("sspi.h", MSDNShortId = "fc6ef09c-3ba9-4bcb-a3c2-07422af8eaa9")]
[StructLayout(LayoutKind.Sequential)]
public struct SecBufferDesc
{
/// Current structure version.
public const uint SECBUFFER_VERSION = 0;
///
/// Specifies the version number of this structure. This member must be SECBUFFER_VERSION.
///
public uint ulVersion;
///
/// Indicates the number of SecBuffer structures in the pBuffers array.
///
public uint cBuffers;
///
/// Pointer to an array of SecBuffer structures.
///
public IntPtr pBuffers;
/// The default structure with the ulVersion field set correctly.
public static readonly SecBufferDesc Default = new SecBufferDesc { ulVersion = SECBUFFER_VERSION };
}
/// A security handle.
[PInvokeData("sspi.h")]
[StructLayout(LayoutKind.Sequential)]
public struct CredHandle : IEquatable
{
/// Represents the invalid handle value.
public static readonly CredHandle Invalid = new CredHandle() { dwLower = UIntPtr.Zero, dwUpper = MaxValue };
/// Represents a NULL handle value.
public static readonly CredHandle Null = new CredHandle();
/// Lower value.
public UIntPtr dwLower;
/// Upper value.
public UIntPtr dwUpper;
private static readonly UIntPtr MaxValue = UIntPtr.Size == 4 ? new UIntPtr(uint.MaxValue) : new UIntPtr(ulong.MaxValue);
/// Gets a value indicating whether this instance is invalid.
/// true if this instance is invalid; otherwise, false.
public bool IsInvalid => dwLower == MaxValue || dwUpper == MaxValue;
/// Gets a value indicating whether this instance is NULL.
/// true if this instance is NULL; otherwise, false.
public bool IsNull => dwLower == UIntPtr.Zero && dwUpper == UIntPtr.Zero;
/// Implements the operator !=.
/// The left value.
/// The right value.
/// The result of the operator.
public static bool operator !=(CredHandle value1, CredHandle value2) => !value1.Equals(value2);
/// Implements the operator ==.
/// The left value.
/// The right value.
/// The result of the operator.
public static bool operator ==(CredHandle value1, CredHandle value2) => value1.Equals(value2);
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(CredHandle other) => other.dwUpper == dwUpper && other.dwLower == dwLower;
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// true if the specified is equal to this instance; otherwise, false.
public override bool Equals(object obj) => obj is CredHandle h ? Equals(h) : base.Equals(obj);
/// Returns a hash code for this instance.
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
public override int GetHashCode() => base.GetHashCode();
/// Invalidates this instance.
public void Invalidate() { dwLower = UIntPtr.Zero; dwUpper = MaxValue; }
}
/// A security handle.
[PInvokeData("sspi.h")]
[StructLayout(LayoutKind.Sequential)]
public struct CtxtHandle : IEquatable
{
/// Represents the invalid handle value.
public static readonly CtxtHandle Invalid = new CtxtHandle() { dwLower = UIntPtr.Zero, dwUpper = MaxValue };
/// Represents a NULL handle value.
public static readonly CtxtHandle Null = new CtxtHandle();
/// Lower value.`
public UIntPtr dwLower;
/// Upper value.
public UIntPtr dwUpper;
private static readonly UIntPtr MaxValue = UIntPtr.Size == 4 ? new UIntPtr(uint.MaxValue) : new UIntPtr(ulong.MaxValue);
/// Gets a value indicating whether this instance is invalid.
/// true if this instance is invalid; otherwise, false.
public bool IsInvalid => dwLower == MaxValue || dwUpper == MaxValue;
/// Gets a value indicating whether this instance is NULL.
/// true if this instance is NULL; otherwise, false.
public bool IsNull => dwLower == UIntPtr.Zero && dwUpper == UIntPtr.Zero;
/// Implements the operator !=.
/// The left value.
/// The right value.
/// The result of the operator.
public static bool operator !=(CtxtHandle value1, CtxtHandle value2) => !value1.Equals(value2);
/// Implements the operator ==.
/// The left value.
/// The right value.
/// The result of the operator.
public static bool operator ==(CtxtHandle value1, CtxtHandle value2) => value1.Equals(value2);
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(CtxtHandle other) => other.dwUpper == dwUpper && other.dwLower == dwLower;
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// true if the specified is equal to this instance; otherwise, false.
public override bool Equals(object obj) => obj is CtxtHandle h ? Equals(h) : base.Equals(obj);
/// Returns a hash code for this instance.
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
public override int GetHashCode() => base.GetHashCode();
/// Invalidates this instance.
public void Invalidate() { dwLower = UIntPtr.Zero; dwUpper = MaxValue; }
}
///
/// The SecPkgContext_AccessToken structure returns a handle to the access token for the current security context. The
/// returned handle can be used by the ImpersonateLoggedOnUser and GetTokenInformation functions. This structure is returned by the
/// QueryContextAttributes (General) function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_accesstoken typedef struct
// _SecPkgContext_AccessToken { void *AccessToken; } SecPkgContext_AccessToken, *PSecPkgContext_AccessToken;
[PInvokeData("sspi.h", MSDNShortId = "4dc11cbd-7f28-4cb9-aaea-6e5a89ac91f0")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_AccessToken
{
///
/// Pointer to a void that receives the handle to the access token that represents the authenticated user.
/// The returned handle is not duplicated, so the calling process must not call CloseHandle on the returned handle.
///
/// If the security context is for a server or is incomplete, the returned handle may be NULL. Depending on the security
/// package, QueryContextAttributes (General) may return SEC_E_NO_IMPERSONATION for these cases.
///
///
public IntPtr AccessToken;
}
///
/// The SecPkgContext_Authority structure contains the name of the authenticating authority if one is available. It can be a
/// certification authority (CA) or the name of a server or domain that authenticated the connection. The QueryContextAttributes
/// (General) function uses this structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_authoritya typedef struct
// _SecPkgContext_AuthorityA { SEC_CHAR *sAuthorityName; } SecPkgContext_AuthorityA, *PSecPkgContext_AuthorityA;
[PInvokeData("sspi.h", MSDNShortId = "619bf16b-c439-48e7-b013-3622e2f3bbc4")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_Authority
{
/// Pointer to a null-terminated string containing the name of the authenticating authority, if available.
[MarshalAs(UnmanagedType.LPTStr)]
public string sAuthorityName;
}
/// Specifies a structure that contains channel binding information for a security context.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_bindings typedef struct _SecPkgContext_Bindings {
// unsigned long BindingsLength; SEC_CHANNEL_BINDINGS *Bindings; } SecPkgContext_Bindings, *PSecPkgContext_Bindings;
[PInvokeData("sspi.h", MSDNShortId = "6823cc31-acd3-4d67-92c6-65ff4d1c6aed")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_Bindings
{
/// The size, in bytes, of the structure specified by the Bindings member
public uint BindingsLength;
/// A pointer to a SEC_CHANNEL_BINDINGS structure that specifies channel binding information.
public IntPtr Bindings;
}
///
/// The SecPkgContext_ClientSpecifiedTarget structure specifies the service principal name (SPN) of the initial target when
/// calling the QueryContextAttributes (Digest) function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_clientspecifiedtarget typedef struct
// _SecPkgContext_ClientSpecifiedTarget { SEC_WCHAR *sTargetName; } SecPkgContext_ClientSpecifiedTarget, *PSecPkgContext_ClientSpecifiedTarget;
[PInvokeData("sspi.h", MSDNShortId = "67536f69-a1fc-4f26-84dc-872635bafa3b")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_ClientSpecifiedTarget
{
/// The SPN of the initial target.
[MarshalAs(UnmanagedType.LPWStr)]
public string sTargetName;
}
/// Specifies the type of credentials used to create a client context.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_credinfo typedef struct _SecPkgContext_CredInfo {
// SECPKG_CRED_CLASS CredClass; unsigned long IsPromptingNeeded; } SecPkgContext_CredInfo, *PSecPkgContext_CredInfo;
[PInvokeData("sspi.h", MSDNShortId = "5c2c6d01-5de3-4dd1-9fa2-cce9eadd6902")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_CredInfo
{
/// A value of the SECPKG_CRED_CLASS enumeration that indicates the type of credentials.
public SECPKG_CRED_CLASS CredClass;
///
/// A nonzero value indicates that the application must prompt the user for credentials. All other values indicate that the
/// application does not need to prompt the user.
///
[MarshalAs(UnmanagedType.Bool)]
public bool IsPromptingNeeded;
}
///
/// The SecPkgContext_DceInfo structure contains authorization data used by DCE services. The QueryContextAttributes (General)
/// function uses this structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_dceinfo typedef struct _SecPkgContext_DceInfo {
// unsigned long AuthzSvc; void *pPac; } SecPkgContext_DceInfo, *PSecPkgContext_DceInfo;
[PInvokeData("sspi.h", MSDNShortId = "490688d0-efdd-4a40-88b9-eb53ff592d2a")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_DceInfo
{
/// Specifies the authorization service used. For DCE use only.
public uint AuthzSvc;
/// Pointer to package-specific authorization data.
public IntPtr pPac;
}
///
/// The SecPkgContext_Flags structure contains information about the flags in the current security context. This structure is
/// returned by QueryContextAttributes (General).
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-secpkgcontext_flags typedef struct _SecPkgContext_Flags {
// unsigned long Flags; } SecPkgContext_Flags, *PSecPkgContext_Flags;
[PInvokeData("sspi.h", MSDNShortId = "0be0e945-4048-4748-a9fd-15d08fb7ff3e")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_Flags
{
///
/// Flag values for the current security context. These values correspond to the flags negotiated by the
/// InitializeSecurityContext (General) and AcceptSecurityContext (General) functions.
///
public uint Flags;
}
///
///
/// The SecPkgContext_KeyInfo structure contains information about the session keys used in a security context. The
/// QueryContextAttributes (General) function uses this structure.
///
///
/// Applications using the Schannel security support provider (SSP) should not use the SecPkgContext_KeyInfo structure.
/// Instead, use the SecPkgContext_ConnectionInfo structure.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_keyinfoa typedef struct _SecPkgContext_KeyInfoA {
// SEC_CHAR *sSignatureAlgorithmName; SEC_CHAR *sEncryptAlgorithmName; unsigned long KeySize; unsigned long SignatureAlgorithm;
// unsigned long EncryptAlgorithm; } SecPkgContext_KeyInfoA, *PSecPkgContext_KeyInfoA;
[PInvokeData("sspi.h", MSDNShortId = "ec146329-6789-460c-ae62-629a1765a4c1")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_KeyInfo
{
///
/// Pointer to a null-terminated string that contains the name, if available, of the algorithm used for generating signatures,
/// for example "MD5" or "SHA-2".
///
[MarshalAs(UnmanagedType.LPTStr)]
public string sSignatureAlgorithmName;
///
/// Pointer to a null-terminated string that contains the name, if available, of the algorithm used for encrypting messages.
/// Reserved for future use.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string sEncryptAlgorithmName;
/// Specifies the effective key length, in bits, for the session key. This is typically 40, 56, or 128 bits.
public uint KeySize;
/// Specifies the algorithm identifier (ALG_ID) used for generating signatures, if available.
public ALG_ID SignatureAlgorithm;
/// Specifies the algorithm identifier (ALG_ID) used for encrypting messages. Reserved for future use.
public ALG_ID EncryptAlgorithm;
}
///
/// Specifies whether the token from the most recent call to the InitializeSecurityContext function is the last token from the client.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_lastclienttokenstatus typedef struct
// _SecPkgContext_LastClientTokenStatus { SECPKG_ATTR_LCT_STATUS LastClientTokenStatus; } SecPkgContext_LastClientTokenStatus, *PSecPkgContext_LastClientTokenStatus;
[PInvokeData("sspi.h", MSDNShortId = "ccb2bb4e-3c65-4305-95ad-b9111f3936b5")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_LastClientTokenStatus
{
///
/// A value of the SECPKG_ATTR_LCT_STATUS enumeration that indicates the status of the token returned by the most recent call to InitializeSecurityContext.
///
public SECPKG_ATTR_LCT_STATUS LastClientTokenStatus;
}
///
/// The SecPkgContext_Lifespan structure indicates the life span of a security context. The QueryContextAttributes (General)
/// function uses this structure.
///
/// It is recommended that the security package always return these values in local time.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_lifespan typedef struct _SecPkgContext_Lifespan {
// TimeStamp tsStart; TimeStamp tsExpiry; } SecPkgContext_Lifespan, *PSecPkgContext_Lifespan;
[PInvokeData("sspi.h", MSDNShortId = "7ef45795-f6af-4dac-a498-c6f8c915a168")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_Lifespan
{
/// Time at which the context was established.
public TimeStamp tsStart;
/// Time at which the context will expire.
public TimeStamp tsExpiry;
}
///
/// The SecPkgContext_Names structure indicates the name of the user associated with a security context. The
/// QueryContextAttributes (General) function uses this structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_namesa typedef struct _SecPkgContext_NamesA {
// SEC_CHAR *sUserName; } SecPkgContext_NamesA, *PSecPkgContext_NamesA;
[PInvokeData("sspi.h", MSDNShortId = "9df0bf7c-ad5f-4cb8-8934-76062789735f")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_Names
{
///
/// Pointer to a null-terminated string containing the name of the user represented by the context. If the security package has
/// set the SECPKG_FLAG_ACCEPT_WIN32_NAME flag, this name can be used in other Windows calls.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string sUserName;
}
///
/// The SecPkgContext_NativeNames structure returns the client and server principal names from the outbound ticket. This
/// structure is valid only for client outbound tickets. This structure is returned by QueryContextAttributes (General).
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_nativenamesa typedef struct
// _SecPkgContext_NativeNamesA { SEC_CHAR *sClientName; SEC_CHAR *sServerName; } SecPkgContext_NativeNamesA, *PSecPkgContext_NativeNamesA;
[PInvokeData("sspi.h", MSDNShortId = "f935093f-5661-4ced-94f1-c4b21c3b9f69")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_NativeNames
{
///
/// Pointer to a null-terminated string that represents the principal name for the client in the outbound ticket. This string
/// should never be NULL when querying a security context negotiated with Kerberos.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string sClientName;
///
/// Pointer to a null-terminated string that represents the principal name for the server in the outbound ticket. This string
/// should never be NULL when querying a security context negotiated with Kerberos.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string sServerName;
}
/// Specifies the error status of the last attempt to create a client context.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_negostatus typedef struct
// _SecPkgContext_NegoStatus { unsigned long LastStatus; } SecPkgContext_NegoStatus, *PSecPkgContext_NegoStatus;
[PInvokeData("sspi.h", MSDNShortId = "09201338-4743-44a2-b84f-35b26116976d")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_NegoStatus
{
/// The error status of the last attempt to create a client context.
public uint LastStatus;
}
///
/// The SecPkgContext_NegotiationInfo structure contains information on the security package that is being set up or has been
/// set up, and also gives the status on the negotiation to set up the security package.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_negotiationinfoa typedef struct
// _SecPkgContext_NegotiationInfoA { PSecPkgInfoA PackageInfo; unsigned long NegotiationState; } SecPkgContext_NegotiationInfoA, *PSecPkgContext_NegotiationInfoA;
[PInvokeData("sspi.h", MSDNShortId = "3af724b8-fbe5-4a75-b128-9efe65381f2f")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_NegotiationInfo
{
///
/// Pointer to a SecPkgInfo structure that provides general information about the security package chosen in the negotiate
/// process, such as the name and capabilities of the package.
///
public IntPtr PackageInfo;
///
///
/// Indicator of the state of the negotiation for the security package identified in the PackageInfo member. This
/// attribute can be queried from the context handle before the setup is complete, such as when ISC returns SEC_I_CONTINUE_NEEDED.
///
/// The following table shows values returned in this member.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_NEGOTIATION_COMPLETE
/// Negotiation has been completed.
///
/// -
/// SECPKG_NEGOTIATION_OPTIMISTIC
/// Negotiations not yet completed.
///
/// -
/// SECPKG_NEGOTIATION_IN_PROGRESS
/// Negotiations in progress.
///
///
///
public uint NegotiationState;
}
///
/// The SecPkgContext_PackageInfo structure contains the name of a security support provider (SSP). This structure is returned
/// by the QueryContextAttributes (General) function. It would most often be used when the SSP in use was established using the
/// Negotiate security package.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_packageinfoa typedef struct
// _SecPkgContext_PackageInfoA { PSecPkgInfoA PackageInfo; } SecPkgContext_PackageInfoA, *PSecPkgContext_PackageInfoA;
[PInvokeData("sspi.h", MSDNShortId = "94c21f22-d974-4ae5-beef-d4567e6ea7e1")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_PackageInfo
{
/// Pointer to a SecPkgInfo structure containing the name of the SSP in use.
public IntPtr PackageInfo;
}
///
/// The SecPkgContext_PasswordExpiry structure contains information about the expiration of a password or other credential
/// used for the security context. This structure is returned by QueryContextAttributes (General).
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-secpkgcontext_passwordexpiry typedef struct
// _SecPkgContext_PasswordExpiry { TimeStamp tsPasswordExpires; } SecPkgContext_PasswordExpiry, *PSecPkgContext_PasswordExpiry;
[PInvokeData("sspi.h", MSDNShortId = "f45dde88-1520-4e65-8fae-8407dfaa0850")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_PasswordExpiry
{
///
/// A TimeStamp variable that indicates when the credentials for the security context expire. For password-based packages, this
/// variable indicates when the password expires. For Kerberos, this variable indicates when the ticket expires.
///
public TimeStamp tsPasswordExpires;
}
///
///
/// [The SecPkgContext_ProtoInfo structure is available for use in the operating systems specified in the Requirements
/// section. It may be altered or unavailable in subsequent versions. Instead, use the SecPkgContext_ConnectionInfo structure.]
///
/// The SecPkgContext_ProtoInfo structure holds information about the protocol in use.
/// This attribute is supported only by the Schannel security support provider (SSP).
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-secpkgcontext_protoinfoa typedef struct
// _SecPkgContext_ProtoInfoA { SEC_CHAR *sProtocolName; unsigned long majorVersion; unsigned long minorVersion; }
// SecPkgContext_ProtoInfoA, *PSecPkgContext_ProtoInfoA;
[PInvokeData("sspi.h", MSDNShortId = "c10eb1fc-b957-4853-86c1-070749488bb9")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgContext_ProtoInfo
{
/// Pointer to a string containing the name of the protocol.
[MarshalAs(UnmanagedType.LPTStr)]
public string sProtocolName;
/// Major version number.
public uint majorVersion;
/// Minor version number.
public uint minorVersion;
}
///
/// The SecPkgContext_SessionKey structure contains information about the session key used for the security context. This
/// structure is returned by the QueryContextAttributes (General) function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_sessionkey typedef struct
// _SecPkgContext_SessionKey { unsigned long SessionKeyLength; unsigned char *SessionKey; } SecPkgContext_SessionKey, *PSecPkgContext_SessionKey;
[PInvokeData("sspi.h", MSDNShortId = "88cf437e-3be0-4f12-9058-ad078deed6a1")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_SessionKey
{
/// Size, in bytes, of the session key.
public uint SessionKeyLength;
/// The session key for the security context.
public IntPtr SessionKey;
}
///
/// The SecPkgContext_Sizes structure indicates the sizes of important structures used in the message support functions. The
/// QueryContextAttributes (General) function uses this structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_sizes typedef struct _SecPkgContext_Sizes {
// unsigned long cbMaxToken; unsigned long cbMaxSignature; unsigned long cbBlockSize; unsigned long cbSecurityTrailer; }
// SecPkgContext_Sizes, *PSecPkgContext_Sizes;
[PInvokeData("sspi.h", MSDNShortId = "46b6a155-8855-4aa0-a513-aa5b3760fcd4")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_Sizes
{
/// Specifies the maximum size of the security token used in the authentication exchanges.
public uint cbMaxToken;
///
/// Specifies the maximum size of the signature created by the MakeSignature function. This member must be zero if integrity
/// services are not requested or available.
///
public uint cbMaxSignature;
///
/// Specifies the preferred integral size of the messages. For example, eight indicates that messages should be of size zero mod
/// eight for optimal performance. Messages other than this block size can be padded.
///
public uint cbBlockSize;
///
/// Size of the security trailer to be appended to messages. This member should be zero if the relevant services are not
/// requested or available.
///
public uint cbSecurityTrailer;
}
///
/// The SecPkgContext_StreamSizes structure indicates the sizes of the various parts of a stream for use with the message
/// support functions. The QueryContextAttributes (General) function uses this structure.
///
///
/// Applications calling EncryptMessage (General) should check the values of the cbHeader, cbTrailer, and
/// cbMaximumMessage members to determine the size of the encrypted packet.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_streamsizes typedef struct
// _SecPkgContext_StreamSizes { unsigned long cbHeader; unsigned long cbTrailer; unsigned long cbMaximumMessage; unsigned long
// cBuffers; unsigned long cbBlockSize; } SecPkgContext_StreamSizes, *PSecPkgContext_StreamSizes;
[PInvokeData("sspi.h", MSDNShortId = "75e5fc96-56cc-4713-a34f-fca687798ad6")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_StreamSizes
{
/// Specifies the size, in bytes, of the header portion. If zero, no header is used.
public uint cbHeader;
/// Specifies the maximum size, in bytes, of the trailer portion. If zero, no trailer is used.
public uint cbTrailer;
/// Specifies the size, in bytes, of the largest message that can be encapsulated.
public uint cbMaximumMessage;
/// Specifies the number of buffers to pass.
public uint cBuffers;
///
/// Specifies the preferred integral size of the messages. For example, eight indicates that messages should be of size zero mod
/// eight for optimal performance. Messages other than this block size can be padded.
///
public uint cbBlockSize;
}
/// The SecPkgContext_SubjectAttributes structure returns the security attribute information.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcontext_subjectattributes typedef struct
// _SecPkgContext_SubjectAttributes { void *AttributeInfo; } SecPkgContext_SubjectAttributes, *PSecPkgContext_SubjectAttributes;
[PInvokeData("sspi.h", MSDNShortId = "548E972F-EB94-4BBD-94F2-FA38184D179A")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_SubjectAttributes
{
///
/// Pointer to a void that receives the attribute information stored in a AUTHZ_SECURITY_ATTRIBUTES_INFORMATION structure.
///
public IntPtr AttributeInfo;
}
///
/// The SecPkgContext_TargetInformation structure returns information about the credential used for the security context. This
/// structure is returned by the QueryContextAttributes (General) function.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-secpkgcontext_targetinformation typedef struct
// _SecPkgContext_TargetInformation { unsigned long MarshalledTargetInfoLength; unsigned char *MarshalledTargetInfo; }
// SecPkgContext_TargetInformation, *PSecPkgContext_TargetInformation;
[PInvokeData("sspi.h", MSDNShortId = "8a5a6bd6-8678-4544-a631-5ee4347bc685")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgContext_TargetInformation
{
/// Size, in bytes, of MarshalledTargetInfo.
public uint MarshalledTargetInfoLength;
/// Array of bytes that represent the credential, if a credential is provided by a credential manager.
public IntPtr MarshalledTargetInfo;
}
/// Specifies the certificate credentials. The QueryCredentialsAttributes function uses this structure.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcredentials_cert typedef struct _SecPkgCredentials_Cert {
// unsigned long EncodedCertSize; unsigned char *EncodedCert; } SecPkgCredentials_Cert, *PSecPkgCredentials_Cert;
[PInvokeData("sspi.h", MSDNShortId = "9EEE6E98-D45C-4929-9C9C-F344972D186F")]
[StructLayout(LayoutKind.Sequential)]
public struct SecPkgCredentials_Cert
{
/// Size of the encoded certificate.
public uint EncodedCertSize;
/// The encoded certificate.
public IntPtr EncodedCert;
}
/// Specifies the Kerberos proxy settings for the credentials.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcredentials_kdcproxysettingsw typedef struct
// _SecPkgCredentials_KdcProxySettingsW { ULONG Version; ULONG Flags; USHORT ProxyServerOffset; USHORT ProxyServerLength; USHORT
// ClientTlsCredOffset; USHORT ClientTlsCredLength; } SecPkgCredentials_KdcProxySettingsW, *PSecPkgCredentials_KdcProxySettingsW;
[PInvokeData("sspi.h", MSDNShortId = "42BC75B8-6392-4FD4-95BC-266B3AFDDC62")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SecPkgCredentials_KdcProxySettingsW
{
/// Version for the Kerberos proxy settings where KDC_PROXY_SETTINGS_V1 is defined as 1.
public uint Version;
/// Flags for the Kerberos proxy settings.
public uint Flags;
/// The offset of the proxy server. This member is optional.
public ushort ProxyServerOffset;
/// Length of the proxy server.
public ushort ProxyServerLength;
/// The offset of the client credentials. This member is optional.
public ushort ClientTlsCredOffset;
/// Length of the client credentials.
public ushort ClientTlsCredLength;
}
///
/// The SecPkgCredentials_Names structure holds the name of the user associated with a context. The QueryCredentialsAttributes
/// function uses this structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkgcredentials_namesa typedef struct
// _SecPkgCredentials_NamesA { SEC_CHAR *sUserName; } SecPkgCredentials_NamesA, *PSecPkgCredentials_NamesA;
[PInvokeData("sspi.h", MSDNShortId = "38123a10-72a4-46eb-974b-3c01142dfc74")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgCredentials_Names
{
///
/// Pointer to a null-terminated string containing the name of the user represented by the credential. If the security package
/// sets the SECPKG_FLAG_ACCEPT_WIN32_NAME flag to indicate that it can process Windows names, this name can be used in other
/// Windows calls.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string sUserName;
}
///
/// The SecPkgCredentials_SSIProvider structure holds the SSI provider information associated with a context. The
/// QueryCredentialsAttributes function uses this structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-secpkgcredentials_ssiprovidera typedef struct
// _SecPkgCredentials_SSIProviderA { SEC_CHAR *sProviderName; unsigned long ProviderInfoLength; char *ProviderInfo; }
// SecPkgCredentials_SSIProviderA, *PSecPkgCredentials_SSIProviderA;
[PInvokeData("sspi.h", MSDNShortId = "0C6D6217-3A97-40B5-A7FB-B9D49C5FBC7C")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgCredentials_SSIProvider
{
/// Pointer to a null-terminated string that contains the name of the provider represented by the credential.
[MarshalAs(UnmanagedType.LPTStr)]
public string sProviderName;
/// Length of the provider information.
public uint ProviderInfoLength;
/// The provider information.
public IntPtr ProviderInfo;
}
/// The SecPkgInfo structure provides general information about a security package, such as its name and capabilities.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_secpkginfoa typedef struct _SecPkgInfoA { unsigned long
// fCapabilities; unsigned short wVersion; unsigned short wRPCID; unsigned long cbMaxToken; SEC_CHAR *Name; SEC_CHAR *Comment; }
// SecPkgInfoA, *PSecPkgInfoA;
[PInvokeData("sspi.h", MSDNShortId = "d0bff3d8-63f1-4a4e-851f-177040af6bd2")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecPkgInfo
{
///
///
/// Set of bit flags that describes the capabilities of the security package. This member can be a combination of the following flags.
///
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_FLAG_INTEGRITY 0x1
/// The security package supports the MakeSignature and VerifySignature functions.
///
/// -
/// SECPKG_FLAG_PRIVACY 0x2
/// The security package supports the EncryptMessage (General) and DecryptMessage (General) functions.
///
/// -
/// SECPKG_FLAG_TOKEN_ONLY 0x4
///
/// The package is interested only in the security-token portion of messages, and will ignore any other buffers. This is a
/// performance-related issue.
///
///
/// -
/// SECPKG_FLAG_DATAGRAM 0x8
/// Supports datagram-style authentication. For more information, see SSPI Context Semantics.
///
/// -
/// SECPKG_FLAG_CONNECTION 0x10
/// Supports connection-oriented style authentication. For more information, see SSPI Context Semantics.
///
/// -
/// SECPKG_FLAG_MULTI_REQUIRED 0x20
/// Multiple legs are required for authentication.
///
/// -
/// SECPKG_FLAG_CLIENT_ONLY 0x40
/// Server authentication support is not provided.
///
/// -
/// SECPKG_FLAG_EXTENDED_ERROR 0x80
/// Supports extended error handling. For more information, see Extended Error Information.
///
/// -
/// SECPKG_FLAG_IMPERSONATION 0x100
/// Supports Windows impersonation in server contexts.
///
/// -
/// SECPKG_FLAG_ACCEPT_WIN32_NAME 0x200
/// Understands Windows principal and target names.
///
/// -
/// SECPKG_FLAG_STREAM 0x400
/// Supports stream semantics. For more information, see SSPI Context Semantics.
///
/// -
/// SECPKG_FLAG_NEGOTIABLE 0X800
/// Can be used by the Microsoft Negotiate security package.
///
/// -
/// SECPKG_FLAG_GSS_COMPATIBLE 0x1000
/// Supports GSS compatibility.
///
/// -
/// SECPKG_FLAG_LOGON 0x2000
/// Supports LsaLogonUser.
///
/// -
/// SECPKG_FLAG_ASCII_BUFFERS 0x4000
/// Token buffers are in ASCII characters format.
///
/// -
/// SECPKG_FLAG_FRAGMENT 0x8000
///
/// Supports separating large tokens into smaller buffers so that applications can make repeated calls to
/// InitializeSecurityContext (General) and AcceptSecurityContext (General) with the smaller buffers to complete authentication.
///
///
/// -
/// SECPKG_FLAG_MUTUAL_AUTH 0x10000
/// Supports mutual authentication.
///
/// -
/// SECPKG_FLAG_DELEGATION 0x20000
/// Supports delegation.
///
/// -
/// SECPKG_FLAG_READONLY_WITH_CHECKSUM 0x40000
/// The security package supports using a checksum instead of in-place encryption when calling the EncryptMessage function.
///
/// -
/// SECPKG_FLAG_RESTRICTED_TOKENS 0x80000
/// Supports callers with restricted tokens.
///
/// -
/// SECPKG_FLAG_NEGO_EXTENDER 0x00100000
/// The security package extends the Microsoft Negotiate security package. There can be at most one package of this type.
///
/// -
/// SECPKG_FLAG_NEGOTIABLE2 0x00200000
/// This package is negotiated by the package of type SECPKG_FLAG_NEGO_EXTENDER.
///
/// -
/// SECPKG_FLAG_APPCONTAINER_PASSTHROUGH 0x00400000
/// This package receives all calls from app container apps.
///
/// -
/// SECPKG_FLAG_APPCONTAINER_CHECKS 0x00800000
/// This package receives calls from app container apps if one of the following checks succeeds.
///
/// -
/// SECPKG_CALLFLAGS_APPCONTAINER 0x00000001
/// The caller is an app container.
///
/// -
/// SECPKG_CALLFLAGS_AUTHCAPABLE 0x00000002
/// The caller can use default credentials.
///
/// -
/// SECPKG_CALLFLAGS_FORCE_SUPPLIED 0x00000004
/// The caller can only use supplied credentials.
///
///
///
public SECPKG_FLAG fCapabilities;
/// Specifies the version of the package protocol. Must be 1.
public ushort wVersion;
///
/// Specifies a DCE RPC identifier, if appropriate. If the package does not implement one of the DCE registered security systems,
/// the reserved value SECPKG_ID_NONE is used.
///
public ushort wRPCID;
/// Specifies the maximum size, in bytes, of the token.
public uint cbMaxToken;
/// Pointer to a null-terminated string that contains the name of the security package.
[MarshalAs(UnmanagedType.LPTStr)]
public string Name;
/// Pointer to a null-terminated string. This can be any additional string passed back by the package.
[MarshalAs(UnmanagedType.LPTStr)]
public string Comment;
}
/// Specifies information about a security package. This structure is used by the AddSecurityPackage function.
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-security_package_options typedef struct
// _SECURITY_PACKAGE_OPTIONS { unsigned long Size; unsigned long Type; unsigned long Flags; unsigned long SignatureSize; void
// *Signature; } SECURITY_PACKAGE_OPTIONS, *PSECURITY_PACKAGE_OPTIONS;
[PInvokeData("sspi.h", MSDNShortId = "2e9f65ec-72a5-4d6f-aa63-f83369f0dd07")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SECURITY_PACKAGE_OPTIONS
{
/// The size, in bytes, of this structure.
public uint Size;
///
/// The type of security package. This can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SECPKG_OPTIONS_TYPE_UNKNOWN 0
/// The package type is not known.
///
/// -
/// SECPKG_OPTIONS_TYPE_LSA 1
/// The security package is an LSA authentication package.
///
/// -
/// SECPKG_OPTIONS_TYPE_SSPI 2
/// The security package is a Security Support Provider Interface (SSPI) package.
///
///
///
public SECPKG_OPTIONS_TYPE Type;
/// This member is reserved. Do not use it.
public uint Flags;
/// The size, in bytes, of a digital signature for this security package.
public uint SignatureSize;
/// A digital signature for this security package.
public IntPtr Signature;
}
///
/// The SecurityFunctionTable structure is a dispatch table that contains pointers to the functions defined in SSPI.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/sspi/ns-sspi-_security_function_table_w typedef struct
// _SECURITY_FUNCTION_TABLE_W { unsigned long dwVersion; ENUMERATE_SECURITY_PACKAGES_FN_W EnumerateSecurityPackagesW;
// QUERY_CREDENTIALS_ATTRIBUTES_FN_W QueryCredentialsAttributesW; ACQUIRE_CREDENTIALS_HANDLE_FN_W AcquireCredentialsHandleW;
// FREE_CREDENTIALS_HANDLE_FN FreeCredentialsHandle; void *Reserved2; INITIALIZE_SECURITY_CONTEXT_FN_W InitializeSecurityContextW;
// ACCEPT_SECURITY_CONTEXT_FN AcceptSecurityContext; COMPLETE_AUTH_TOKEN_FN CompleteAuthToken; DELETE_SECURITY_CONTEXT_FN
// DeleteSecurityContext; APPLY_CONTROL_TOKEN_FN ApplyControlToken; QUERY_CONTEXT_ATTRIBUTES_FN_W QueryContextAttributesW;
// IMPERSONATE_SECURITY_CONTEXT_FN ImpersonateSecurityContext; REVERT_SECURITY_CONTEXT_FN RevertSecurityContext; MAKE_SIGNATURE_FN
// MakeSignature; VERIFY_SIGNATURE_FN VerifySignature; FREE_CONTEXT_BUFFER_FN FreeContextBuffer; QUERY_SECURITY_PACKAGE_INFO_FN_W
// QuerySecurityPackageInfoW; void *Reserved3; void *Reserved4; EXPORT_SECURITY_CONTEXT_FN ExportSecurityContext;
// IMPORT_SECURITY_CONTEXT_FN_W ImportSecurityContextW; ADD_CREDENTIALS_FN_W AddCredentialsW; void *Reserved8;
// QUERY_SECURITY_CONTEXT_TOKEN_FN QuerySecurityContextToken; ENCRYPT_MESSAGE_FN EncryptMessage; DECRYPT_MESSAGE_FN DecryptMessage;
// SET_CONTEXT_ATTRIBUTES_FN_W SetContextAttributesW; SET_CREDENTIALS_ATTRIBUTES_FN_W SetCredentialsAttributesW; CHANGE_PASSWORD_FN_W
// ChangeAccountPasswordW; void *Reserved9; QUERY_CONTEXT_ATTRIBUTES_EX_FN_W QueryContextAttributesExW;
// QUERY_CREDENTIALS_ATTRIBUTES_EX_FN_W QueryCredentialsAttributesExW; } SecurityFunctionTableW, *PSecurityFunctionTableW;
[PInvokeData("sspi.h", MSDNShortId = "6315e8d6-b40a-4dd6-b6a6-598a965f93dc")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SecurityFunctionTable
{
/// Version number of the table.
public uint dwVersion;
/// Pointer to the EnumerateSecurityPackages function.
public IntPtr EnumerateSecurityPackages;
/// Pointer to the QueryCredentialsAttributes function.
public IntPtr QueryCredentialsAttributes;
/// Pointer to the AcquireCredentialsHandle function.
public IntPtr AcquireCredentialsHandle;
/// Pointer to the FreeCredentialsHandle function.
public IntPtr FreeCredentialHandl;
/// Reserved for future use.
public IntPtr Reserved1;
/// Pointer to the InitializeSecurityContext (General) function.
public IntPtr InitializeSecurityContext;
/// Pointer to the AcceptSecurityContext (General) function.
public IntPtr AcceptSecurityContex;
/// Pointer to the CompleteAuthToken function.
public IntPtr CompleteAuthToke;
/// Pointer to the DeleteSecurityContext function.
public IntPtr DeleteSecurityContex;
/// Pointer to the ApplyControlToken function.
public IntPtr ApplyControlToke;
/// Pointer to the QueryContextAttributes (General) function.
public IntPtr QueryContextAttributes;
/// Pointer to the ImpersonateSecurityContext function.
public IntPtr ImpersonateSecurityContex;
/// Pointer to the RevertSecurityContext function.
public IntPtr RevertSecurityContex;
/// Pointer to the MakeSignature function.
public IntPtr MakeSignatur;
/// Pointer to the VerifySignature function.
public IntPtr VerifySignatur;
/// Pointer to the FreeContextBuffer function.
public IntPtr FreeContextBuffe;
/// Pointer to the QuerySecurityPackageInfo function.
public IntPtr QuerySecurityPackageInfo;
/// Reserved for future use.
public IntPtr Reserved2;
/// Reserved for future use.
public IntPtr Reserved3;
/// Pointer to the ExportSecurityContext function.
public IntPtr ExportSecurityContex;
/// Pointer to the ImportSecurityContext function.
public IntPtr ImportSecurityContext;
/// Pointer to the AddCredential function.
public IntPtr AddCredentials;
/// Reserved for future use.
public IntPtr Reserved4;
/// Pointer to the QuerySecurityContextToken function.
public IntPtr QuerySecurityContextToke;
/// Pointer to the EncryptMessage (General) function.
public IntPtr EncryptMessag;
/// Pointer to the DecryptMessage (General) function.
public IntPtr DecryptMessag;
/// Pointer to the SetContextAttributes function.
public IntPtr SetContextAttributes;
/// Pointer to the SetCredentialsAttributes function.
public IntPtr SetCredentialsAttributes;
/// Pointer to the ChangeAccountPassword function.
public IntPtr ChangeAccountPassword;
/// Pointer to the AddCredential function.
public IntPtr Reserved5;
/// Pointer to the QueryContextAttributesEx function.
public IntPtr QueryContextAttributesEx;
/// Pointer to the QueryCredentialsAttributesEx function.
public IntPtr QueryCredentialsAttributesEx;
}
/// Provides a for a context buffer that is disposed using .
public class SafeContextBuffer : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeContextBuffer(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeContextBuffer() : base() { }
///
/// Extracts an array of structures of containing items. This
/// call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
///
/// The type of the structures to retrieve.
/// The number of structures to retrieve.
/// The number of bytes to skip before reading the structures.
/// An array of structures of .
public T[] ToArray(int count, int prefixBytes = 0)
{
if (IsInvalid) return null;
//if (Size < Marshal.SizeOf(typeof(T)) * count + prefixBytes)
// throw new InsufficientMemoryException("Requested array is larger than the memory allocated.");
if (!typeof(T).IsBlittable()) throw new ArgumentException(@"Structure layout is not sequential or explicit.");
return handle.ToArray(count, prefixBytes);
}
///
/// Marshals data from this block of memory to a newly allocated managed object of the type specified by a generic type parameter.
///
/// The type of the object to which the data is to be copied. This must be a structure.
/// A managed object that contains the data that this holds.
public T ToStructure()
{
if (IsInvalid) return default;
return handle.ToStructure();
}
///
protected override bool InternalReleaseHandle() => FreeContextBuffer(handle).Succeeded;
}
/// Provides a safe version of that is disposed using .
[StructLayout(LayoutKind.Sequential)]
public sealed class SafeCredHandle : IDisposable
{
private CredHandle handle;
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
public SafeCredHandle(CredHandle preexistingHandle) => handle = preexistingHandle;
/// Initializes a new instance of the class.
private SafeCredHandle() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator CredHandle(SafeCredHandle h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle.
/// The result of the conversion.
public static unsafe implicit operator CredHandle* (SafeCredHandle h)
{
fixed (CredHandle* hp = &h.handle)
return hp;
}
/// Get a NULL reference to CredHandle.
public readonly static SafeCredHandle Null = new SafeCredHandle(CredHandle.Null);
///
///
/// The AcquireCredentialsHandle (CredSSP) function acquires a handle to preexisting credentials of a security principal.
/// This handle is required by the InitializeSecurityContext (CredSSP) and AcceptSecurityContext (CredSSP) functions. These can
/// be either preexisting credentials, which are established through a system logon that is not described here, or the caller
/// can provide alternative credentials.
///
/// This is not a "log on to the network" and does not imply gathering of credentials.
///
///
/// A string that specifies the name of the security package with which these credentials will be used. This is a security
/// package name returned in the Name member of a SecPkgInfo structure returned by the EnumerateSecurityPackages
/// function. After a context is established, QueryContextAttributes (CredSSP) can be called with ulAttribute set to
/// SECPKG_ATTR_PACKAGE_INFO to return information on the security package in use.
///
/// A flag that indicates how these credentials will be used.
/// On success, this function returns a credential handle.
///
///
/// The AcquireCredentialsHandle (CredSSP) function returns a handle to the credentials of a principal, such as a user or
/// client, as used by a specific security package. The function can return the handle to either preexisting credentials or
/// newly created credentials and return it. This handle can be used in subsequent calls to the AcceptSecurityContext (CredSSP)
/// and InitializeSecurityContext (CredSSP) functions.
///
///
/// In general, AcquireCredentialsHandle (CredSSP) does not provide the credentials of other users logged on to the same
/// computer. However, a caller with SE_TCB_NAME privilege can obtain the credentials of an existing logon session by specifying
/// the logon identifier (LUID) of that session. Typically, this is used by kernel-mode modules that must act on behalf of a
/// logged-on user.
///
///
public static SafeCredHandle Acquire(string pszPackage, SECPKG_CRED fCredentialUse) => Acquire(pszPackage, fCredentialUse, null, null, null, out _);
///
///
/// The AcquireCredentialsHandle (CredSSP) function acquires a handle to preexisting credentials of a security principal. This
/// handle is required by the InitializeSecurityContext (CredSSP) and AcceptSecurityContext (CredSSP) functions. These can be either
/// preexisting credentials, which are established through a system logon that is not described here, or the caller can provide
/// alternative credentials.
///
///
/// Note This is not a "log on to the network" and does not imply gathering of credentials.
///
/// The type of the authentication data structure.
/// A string that specifies the name of the security package with which these credentials will be used.
/// This is a security package name returned in the Name member of a SecPkgInfo structure returned by the
/// EnumerateSecurityPackages function. After a context is established, QueryContextAttributes (CredSSP) can be called with
/// ulAttribute set to SECPKG_ATTR_PACKAGE_INFO to return information on the security package in use.
/// A flag that indicates how these credentials will be used.
/// The optional authentication data structure.
///
/// On success, this function returns a credential handle.
///
///
///
/// The AcquireCredentialsHandle (CredSSP) function returns a handle to the credentials of a principal, such as a user or
/// client, as used by a specific security package. The function can return the handle to either preexisting credentials or newly
/// created credentials and return it. This handle can be used in subsequent calls to the AcceptSecurityContext (CredSSP) and
/// InitializeSecurityContext (CredSSP) functions.
///
///
/// In general, AcquireCredentialsHandle (CredSSP) does not provide the credentials of other users logged on to the same
/// computer. However, a caller with SE_TCB_NAME privilege can obtain the credentials of an existing logon session by specifying the
/// logon identifier (LUID) of that session. Typically, this is used by kernel-mode modules that must act on behalf of a logged-on user.
///
///
public static SafeCredHandle Acquire(string pszPackage, SECPKG_CRED fCredentialUse, TAuthData? pAuthData) where TAuthData : struct =>
Acquire(pszPackage, fCredentialUse, pAuthData, null, null, out _);
///
///
/// The AcquireCredentialsHandle (CredSSP) function acquires a handle to preexisting credentials of a security principal. This
/// handle is required by the InitializeSecurityContext (CredSSP) and AcceptSecurityContext (CredSSP) functions. These can be either
/// preexisting credentials, which are established through a system logon that is not described here, or the caller can provide
/// alternative credentials.
///
///
/// Note This is not a "log on to the network" and does not imply gathering of credentials.
///
/// The type of the authentication data.
/// A string that specifies the name of the security package with which these credentials will be used.
/// This is a security package name returned in the Name member of a SecPkgInfo structure returned by the
/// EnumerateSecurityPackages function. After a context is established, QueryContextAttributes (CredSSP) can be called with
/// ulAttribute set to SECPKG_ATTR_PACKAGE_INFO to return information on the security package in use.
/// A flag that indicates how these credentials will be used.
/// An optional structure that specifies authentication data. The structure allowed depends on the type of protocol.
/// An optional string that specifies the name of the principal whose credentials the handle will reference.
///
/// Note If the process that requests the handle does not have access to the credentials, the function returns an error. A
/// null string indicates that the process requires a handle to the credentials of the user under whose security context it is executing.
///
/// A locally unique identifier (LUID) that identifies the user. This parameter is provided for file-system processes
/// such as network redirectors. This parameter can be NULL.
/// A TimeStamp structure that receives the time at which the returned credentials expire. The structure value received
/// depends on the security package, which must specify the value in local time.
/// On success, this function returns a credential handle.
///
///
/// The AcquireCredentialsHandle (CredSSP) function returns a handle to the credentials of a principal, such as a user or
/// client, as used by a specific security package. The function can return the handle to either preexisting credentials or newly
/// created credentials and return it. This handle can be used in subsequent calls to the AcceptSecurityContext (CredSSP) and
/// InitializeSecurityContext (CredSSP) functions.
///
///
/// In general, AcquireCredentialsHandle (CredSSP) does not provide the credentials of other users logged on to the same
/// computer. However, a caller with SE_TCB_NAME privilege can obtain the credentials of an existing logon session by specifying the
/// logon identifier (LUID) of that session. Typically, this is used by kernel-mode modules that must act on behalf of a logged-on user.
///
///
public static SafeCredHandle Acquire(string pszPackage, SECPKG_CRED fCredentialUse, TAuthData? pAuthData, string pszPrincipal,
LUID? pvLogonId, out TimeStamp ptsExpiry) where TAuthData : struct
{
using (var pinnedLuid = new PinnedObject(pvLogonId))
using (var pinnedAuthData = pAuthData.HasValue ? SafeHGlobalHandle.CreateFromStructure(pAuthData) : SafeHGlobalHandle.Null)
{
AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse, pinnedLuid, (IntPtr)pinnedAuthData, IntPtr.Zero, IntPtr.Zero, out var hCred, out ptsExpiry).ThrowIfFailed();
return new SafeCredHandle(hCred);
}
}
///
/// Get a dangerous reference to the underlying CredHandle. This value is mutable and may be invalid after this
/// instance is disposed.
///
public CredHandle DangerousGetHandle() => handle;
void IDisposable.Dispose()
{
if (handle.IsInvalid || handle.IsNull) return;
FreeCredentialsHandle(ref handle);
handle = CredHandle.Null;
}
}
/// Provides a safe version of that is disposed using .
[StructLayout(LayoutKind.Sequential)]
public sealed class SafeCtxtHandle : IDisposable
{
private CtxtHandle handle;
/// Initializes a new instance of the class.
public SafeCtxtHandle() => handle = CtxtHandle.Null;
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
public SafeCtxtHandle(CtxtHandle preexistingHandle) => handle = preexistingHandle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator CtxtHandle(SafeCtxtHandle h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle.
/// The result of the conversion.
public static unsafe implicit operator CtxtHandle* (SafeCtxtHandle h)
{
if (h.handle.IsNull)
return null;
fixed (CtxtHandle* hp = &h.handle)
return hp;
}
/// Get a NULL reference to CredHandle.
public readonly static SafeCtxtHandle Null = new SafeCtxtHandle(CtxtHandle.Null);
///
/// Get a dangerous reference to the underlying CtxtHandle. This value is mutable and may be invalid after this
/// instance is disposed.
///
public CtxtHandle DangerousGetHandle() => handle;
void IDisposable.Dispose()
{
if (!handle.IsInvalid && !handle.IsNull) DeleteSecurityContext(handle);
}
internal void SetHandle(CtxtHandle h)
{
if (handle.IsNull) handle = h; else throw new InvalidOperationException();
}
}
/// Provides a for that is disposed using .
public class SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE : SafeHANDLE
{
///
/// Represents a null instance.
///
public static readonly SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE Null = new SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE();
///
/// Initializes a new instance of the class and assigns an existing handle.
///
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator PSEC_WINNT_AUTH_IDENTITY_OPAQUE(SafePSEC_WINNT_AUTH_IDENTITY_OPAQUE h) => h.handle;
///
protected override bool InternalReleaseHandle() { SspiZeroAuthIdentity(handle); SspiFreeAuthIdentity(handle); return true; }
}
///
/// The SafeSecBufferDesc structure describes an array of SecBuffer structures to pass from a transport application to a
/// security package. It handles cleaning up allocated memory.
///
///
/// This is a drop in replacement for anywhere a "SecBufferDesc*" or "ref SecBufferDesc" is required. This class will free all
/// allocated memory and will also free any memory created by Sspi methods that require a call to .
/// Sample code:using (var edesc = new SafeSecBufferDesc())
/// {
/// edesc.Add(SecBufferType.SECBUFFER_TOKEN); // Add SecBuffer with type, but no values
/// edesc.Add(SecBufferType.SECBUFFER_EMPTY); // Add SecBuffer with empty type
/// edesc.Add(SecBufferType.SECBUFFER_DATA, msgStruct); // Add SecBuffer with type set and buffer filled with value of 'msgStruct'
/// edesc.Add(blockSize, SecBufferType.SECBUFFER_PADDING); // Add SecBuffer with type and allocated memory of size 'blockSize'
///
/// // Call method with ref
/// EncryptMessage(hCtx, 0, ref edesc.GetRef(), 0); // Use GetRef() method to get a reference to the internal SecBufferDesc structure
///
/// // Call method with *
/// unsafe
/// {
/// AcceptSecurityContext(hCred, hCtxt2, edesc, ...); // An implicit operator will cast to a SecBufferDesc*
/// }
/// }
[PInvokeData("sspi.h", MSDNShortId = "fc6ef09c-3ba9-4bcb-a3c2-07422af8eaa9")]
public class SafeSecBufferDesc : SafeNativeArrayBase
{
private static readonly uint HdrSize = (uint)Marshal.SizeOf(typeof(SecBufferDesc));
private readonly List items = new List();
private SecBufferDesc desc = SecBufferDesc.Default;
/// Initializes a new instance of the class.
public SafeSecBufferDesc() : base(null, HdrSize) { }
/// Initializes a new instance of the class.
public SafeSecBufferDesc(SecBufferType type) : base(new[] { new SecBuffer(type) }, HdrSize) { }
/// Performs an implicit conversion from to .
/// The instance.
/// The result of the conversion.
public static unsafe implicit operator SecBufferDesc* (SafeSecBufferDesc sbd) => (SecBufferDesc*)sbd.handle;
/// Performs an implicit conversion from to .
/// The instance.
/// The result of the conversion.
public static implicit operator SecBufferDesc? (SafeSecBufferDesc sbd) => (SecBufferDesc)sbd.handle.ToNullableStructure();
/// Adds the specified type with an empty value as a new SecBuffer item.
/// The type of the SecBuffer.
public virtual void Add(SecBufferType type) => Add(new SecBuffer(type));
/// Adds the specified type and value as a new SecBuffer item.
/// The type of the value to add
/// The type of the SecBuffer.
/// The value to add.
public virtual void Add(SecBufferType type, T value = default) where T : struct
{
var mem = SafeHGlobalHandle.CreateFromStructure(value);
items.Add(mem);
Add(new SecBuffer(type, (IntPtr)mem, mem.Size));
}
/// Adds the specified type and value as a new SecBuffer item.
/// The type of the element to add
/// The type of the SecBuffer.
/// The list to add.
public virtual void Add(SecBufferType type, IEnumerable value) where T : struct
{
var mem = SafeHGlobalHandle.CreateFromList(value);
items.Add(mem);
Add(new SecBuffer(type, (IntPtr)mem, mem.Size));
}
/// Adds the specified type and value as a new SecBuffer item.
/// The type of the SecBuffer.
/// The list to add.
public virtual void Add(SecBufferType type, string value)
{
var mem = new SafeHGlobalHandle(value);
items.Add(mem);
Add(new SecBuffer(type, (IntPtr)mem, mem.Size));
}
/// Adds the specified type with an allocated buffer of the specified size as a new SecBuffer item.
/// Size of the buffer.
/// The type of the SecBuffer.
public virtual void Add(int bufferSize, SecBufferType type)
{
var mem = new SafeHGlobalHandle(bufferSize);
items.Add(mem);
Add(new SecBuffer(type, (IntPtr)mem, mem.Size));
}
/// Performs an implicit conversion from to .
/// A reference to a struct.
public ref SecBufferDesc GetRef() => ref desc;
///
protected override void OnCountChanged() => OnUpdateHeader();
///
protected override void OnUpdateHeader()
{
desc.cBuffers = (uint)Count;
desc.pBuffers = handle.Offset((int)HdrSize);
Marshal.StructureToPtr(desc, handle, false);
}
///
protected override bool ReleaseHandle()
{
var hash = new HashSet(items.Select(i => i.DangerousGetHandle()));
foreach (var buf in this.Where(b => !hash.Contains(b.pvBuffer)))
FreeContextBuffer(buf.pvBuffer);
Clear();
foreach (var i in items)
i.Dispose();
items.Clear();
desc = SecBufferDesc.Default;
return base.ReleaseHandle();
}
}
/// Provides a for Sspi allocated memory that is disposed using .
public class SafeSspiLocalMem : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
public SafeSspiLocalMem(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeSspiLocalMem() : base() { }
/// Gets the bytes associated with this memory.
/// The count of bytes to get.
/// A byte array.
public byte[] GetBytes(uint count) => handle.ToArray((int)count);
///
protected override bool InternalReleaseHandle() { SspiLocalFree(handle); return true; }
}
internal class SspiStringMarshaler : ICustomMarshaler
{
public static ICustomMarshaler GetInstance(string _) => new SspiStringMarshaler();
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero) return;
SspiFreeAuthIdentity(pNativeData);
}
public int GetNativeDataSize() => -1;
public IntPtr MarshalManagedToNative(object _) => IntPtr.Zero;
public object MarshalNativeToManaged(IntPtr pNativeData)
{
var ret = StringHelper.GetString(pNativeData, CharSet.Unicode);
System.Diagnostics.Debug.WriteLine($"SspiStringMarshaler: {ret ?? "null"}");
return ret.Clone();
}
}
}
}