diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 21082762d988..0f6658538638 100644 --- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -339,8 +339,10 @@ private static IntPtr GetSslMethod(SslProtocols protocols) { Debug.Assert(protocols != SslProtocols.None, "All protocols are disabled"); +#pragma warning disable 0618 // Ssl2, Ssl3 are deprecated. bool ssl2 = (protocols & SslProtocols.Ssl2) == SslProtocols.Ssl2; bool ssl3 = (protocols & SslProtocols.Ssl3) == SslProtocols.Ssl3; +#pragma warning restore bool tls10 = (protocols & SslProtocols.Tls) == SslProtocols.Tls; bool tls11 = (protocols & SslProtocols.Tls11) == SslProtocols.Tls11; bool tls12 = (protocols & SslProtocols.Tls12) == SslProtocols.Tls12; diff --git a/src/Common/src/Interop/Windows/SChannel/Interop.Alerts.cs b/src/Common/src/Interop/Windows/SChannel/Interop.Alerts.cs new file mode 100644 index 000000000000..f96108898def --- /dev/null +++ b/src/Common/src/Interop/Windows/SChannel/Interop.Alerts.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class SChannel + { + // schannel.h; + + // + // + // ApplyControlToken PkgParams types + // + // These identifiers are the DWORD types + // to be passed into ApplyControlToken + // through a PkgParams buffer. + + public const int SCHANNEL_RENEGOTIATE = 0; // renegotiate a connection + public const int SCHANNEL_SHUTDOWN = 1; // gracefully close down a connection + public const int SCHANNEL_ALERT = 2; // build an error message + public const int SCHANNEL_SESSION = 3; // session control + + + // Alert token structure. + [StructLayout(LayoutKind.Sequential)] + public struct SCHANNEL_ALERT_TOKEN + { + public uint dwTokenType; // SCHANNEL_ALERT + public uint dwAlertType; + public uint dwAlertNumber; + } + + // Alert types. + public const int TLS1_ALERT_WARNING = 1; + public const int TLS1_ALERT_FATAL = 2; + + // Alert messages. + public const int TLS1_ALERT_CLOSE_NOTIFY = 0; // warning + public const int TLS1_ALERT_UNEXPECTED_MESSAGE = 10; // error + public const int TLS1_ALERT_BAD_RECORD_MAC = 20; // error + public const int TLS1_ALERT_DECRYPTION_FAILED = 21; // reserved + public const int TLS1_ALERT_RECORD_OVERFLOW = 22; // error + public const int TLS1_ALERT_DECOMPRESSION_FAIL = 30; // error + public const int TLS1_ALERT_HANDSHAKE_FAILURE = 40; // error + public const int TLS1_ALERT_BAD_CERTIFICATE = 42; // warning or error + public const int TLS1_ALERT_UNSUPPORTED_CERT = 43; // warning or error + public const int TLS1_ALERT_CERTIFICATE_REVOKED = 44; // warning or error + public const int TLS1_ALERT_CERTIFICATE_EXPIRED = 45; // warning or error + public const int TLS1_ALERT_CERTIFICATE_UNKNOWN = 46; // warning or error + public const int TLS1_ALERT_ILLEGAL_PARAMETER = 47; // error + public const int TLS1_ALERT_UNKNOWN_CA = 48; // error + public const int TLS1_ALERT_ACCESS_DENIED = 49; // error + public const int TLS1_ALERT_DECODE_ERROR = 50; // error + public const int TLS1_ALERT_DECRYPT_ERROR = 51; // error + public const int TLS1_ALERT_EXPORT_RESTRICTION = 60; // reserved + public const int TLS1_ALERT_PROTOCOL_VERSION = 70; // error + public const int TLS1_ALERT_INSUFFIENT_SECURITY = 71; // error + public const int TLS1_ALERT_INTERNAL_ERROR = 80; // error + public const int TLS1_ALERT_USER_CANCELED = 90; // warning or error + public const int TLS1_ALERT_NO_RENEGOTIATION = 100; // warning + public const int TLS1_ALERT_UNSUPPORTED_EXT = 110; // error + } +} diff --git a/src/Common/src/Interop/Windows/SChannel/Interop.SecurityStatus.cs b/src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.cs similarity index 99% rename from src/Common/src/Interop/Windows/SChannel/Interop.SecurityStatus.cs rename to src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.cs index 8dc57764539c..7c5f99fe4a81 100644 --- a/src/Common/src/Interop/Windows/SChannel/Interop.SecurityStatus.cs +++ b/src/Common/src/Interop/Windows/SChannel/Interop.SECURITY_STATUS.cs @@ -4,7 +4,7 @@ internal static partial class Interop { - internal enum SecurityStatus + internal enum SECURITY_STATUS { // Success / Informational OK = 0x00000000, diff --git a/src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs b/src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.cs similarity index 89% rename from src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs rename to src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.cs index 4c2ada0550a5..e9510816fd3d 100644 --- a/src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs +++ b/src/Common/src/Interop/Windows/SChannel/SecPkgContext_ConnectionInfo.cs @@ -7,11 +7,10 @@ namespace System.Net { - // TODO (Issue #3114): Move to Interop. - // Investigate if this can be safely converted to a struct. + // TODO (Issue #3114): Investigate if this can be safely converted to a struct. // From Schannel.h [StructLayout(LayoutKind.Sequential)] - internal class SslConnectionInfo + internal class SecPkgContext_ConnectionInfo { public readonly int Protocol; public readonly int DataCipherAlg; @@ -21,7 +20,7 @@ internal class SslConnectionInfo public readonly int KeyExchangeAlg; public readonly int KeyExchKeySize; - internal unsafe SslConnectionInfo(byte[] nativeBuffer) + internal unsafe SecPkgContext_ConnectionInfo(byte[] nativeBuffer) { fixed (void* voidPtr = nativeBuffer) { diff --git a/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs b/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs index c6d6643355db..f3ebea9a8944 100644 --- a/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs +++ b/src/Common/src/Interop/Windows/sspicli/Interop.SSPI.cs @@ -10,7 +10,6 @@ internal static partial class Interop { internal static partial class SspiCli { - // TODO (Issue #3114): Throughout the entire file: replace with OS names from and internal const uint SECQOP_WRAP_NO_ENCRYPT = 0x80000001; internal const int SEC_I_RENEGOTIATE = 0x90321; @@ -19,138 +18,53 @@ internal static partial class SspiCli internal const int SECPKG_NEGOTIATION_OPTIMISTIC = 1; [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct SSPIHandle + internal struct CredHandle { - private IntPtr _handleHi; - private IntPtr _handleLo; + private IntPtr dwLower; + private IntPtr dwUpper; public bool IsZero { - get { return _handleHi == IntPtr.Zero && HandleLo1 == IntPtr.Zero; } - } - - public IntPtr HandleLo1 - { - get - { - return _handleLo; - } - - set - { - _handleLo = value; - } + get { return dwLower == IntPtr.Zero && dwUpper == IntPtr.Zero; } } internal void SetToInvalid() { - _handleHi = IntPtr.Zero; - HandleLo1 = IntPtr.Zero; + dwLower = IntPtr.Zero; + dwUpper = IntPtr.Zero; } public override string ToString() { - { return _handleHi.ToString("x") + ":" + HandleLo1.ToString("x"); } + { return dwLower.ToString("x") + ":" + dwUpper.ToString("x"); } } } internal enum ContextAttribute { - Sizes = 0x00, - Names = 0x01, - Lifespan = 0x02, - DceInfo = 0x03, - StreamSizes = 0x04, - //KeyInfo = 0x05, must not be used, see ConnectionInfo instead - Authority = 0x06, - // SECPKG_ATTR_PROTO_INFO = 7, - // SECPKG_ATTR_PASSWORD_EXPIRY = 8, - // SECPKG_ATTR_SESSION_KEY = 9, - PackageInfo = 0x0A, - // SECPKG_ATTR_USER_FLAGS = 11, - NegotiationInfo = 0x0C, - // SECPKG_ATTR_NATIVE_NAMES = 13, - // SECPKG_ATTR_FLAGS = 14, - // SECPKG_ATTR_USE_VALIDATED = 15, - // SECPKG_ATTR_CREDENTIAL_NAME = 16, - // SECPKG_ATTR_TARGET_INFORMATION = 17, - // SECPKG_ATTR_ACCESS_TOKEN = 18, - // SECPKG_ATTR_TARGET = 19, - // SECPKG_ATTR_AUTHENTICATION_ID = 20, - UniqueBindings = 0x19, - EndpointBindings = 0x1A, - ClientSpecifiedSpn = 0x1B, // SECPKG_ATTR_CLIENT_SPECIFIED_TARGET = 27 - RemoteCertificate = 0x53, - LocalCertificate = 0x54, - RootStore = 0x55, - IssuerListInfoEx = 0x59, - ConnectionInfo = 0x5A, - // SECPKG_ATTR_EAP_KEY_BLOCK 0x5b // returns SecPkgContext_EapKeyBlock - // SECPKG_ATTR_MAPPED_CRED_ATTR 0x5c // returns SecPkgContext_MappedCredAttr - // SECPKG_ATTR_SESSION_INFO 0x5d // returns SecPkgContext_SessionInfo - // SECPKG_ATTR_APP_DATA 0x5e // sets/returns SecPkgContext_SessionAppData - // SECPKG_ATTR_REMOTE_CERTIFICATES 0x5F // returns SecPkgContext_Certificates - // SECPKG_ATTR_CLIENT_CERT_POLICY 0x60 // sets SecPkgCred_ClientCertCtlPolicy - // SECPKG_ATTR_CC_POLICY_RESULT 0x61 // returns SecPkgContext_ClientCertPolicyResult - // SECPKG_ATTR_USE_NCRYPT 0x62 // Sets the CRED_FLAG_USE_NCRYPT_PROVIDER FLAG on cred group - // SECPKG_ATTR_LOCAL_CERT_INFO 0x63 // returns SecPkgContext_CertInfo - // SECPKG_ATTR_CIPHER_INFO 0x64 // returns new CNG SecPkgContext_CipherInfo - // SECPKG_ATTR_EAP_PRF_INFO 0x65 // sets SecPkgContext_EapPrfInfo - // SECPKG_ATTR_SUPPORTED_SIGNATURES 0x66 // returns SecPkgContext_SupportedSignatures - // SECPKG_ATTR_REMOTE_CERT_CHAIN 0x67 // returns PCCERT_CONTEXT - UiInfo = 0x68, // sets SEcPkgContext_UiInfo + // sspi.h + SECPKG_ATTR_SIZES = 0, + SECPKG_ATTR_NAMES = 1, + SECPKG_ATTR_LIFESPAN = 2, + SECPKG_ATTR_DCE_INFO = 3, + SECPKG_ATTR_STREAM_SIZES = 4, + SECPKG_ATTR_AUTHORITY = 6, + SECPKG_ATTR_PACKAGE_INFO = 10, + SECPKG_ATTR_NEGOTIATION_INFO = 12, + SECPKG_ATTR_UNIQUE_BINDINGS = 25, + SECPKG_ATTR_ENDPOINT_BINDINGS = 26, + SECPKG_ATTR_CLIENT_SPECIFIED_TARGET = 27, + + // minschannel.h + SECPKG_ATTR_REMOTE_CERT_CONTEXT = 0x53, // returns PCCERT_CONTEXT + SECPKG_ATTR_LOCAL_CERT_CONTEXT = 0x54, // returns PCCERT_CONTEXT + SECPKG_ATTR_ROOT_STORE = 0x55, // returns HCERTCONTEXT to the root store + SECPKG_ATTR_ISSUER_LIST_EX = 0x59, // returns SecPkgContext_IssuerListInfoEx + SECPKG_ATTR_CONNECTION_INFO = 0x5A, // returns SecPkgContext_ConnectionInfo + SECPKG_ATTR_UI_INFO = 0x68, // sets SEcPkgContext_UiInfo } - // #define ISC_REQ_DELEGATE 0x00000001 - // #define ISC_REQ_MUTUAL_AUTH 0x00000002 - // #define ISC_REQ_REPLAY_DETECT 0x00000004 - // #define ISC_REQ_SEQUENCE_DETECT 0x00000008 - // #define ISC_REQ_CONFIDENTIALITY 0x00000010 - // #define ISC_REQ_USE_SESSION_KEY 0x00000020 - // #define ISC_REQ_PROMPT_FOR_CREDS 0x00000040 - // #define ISC_REQ_USE_SUPPLIED_CREDS 0x00000080 - // #define ISC_REQ_ALLOCATE_MEMORY 0x00000100 - // #define ISC_REQ_USE_DCE_STYLE 0x00000200 - // #define ISC_REQ_DATAGRAM 0x00000400 - // #define ISC_REQ_CONNECTION 0x00000800 - // #define ISC_REQ_CALL_LEVEL 0x00001000 - // #define ISC_REQ_FRAGMENT_SUPPLIED 0x00002000 - // #define ISC_REQ_EXTENDED_ERROR 0x00004000 - // #define ISC_REQ_STREAM 0x00008000 - // #define ISC_REQ_INTEGRITY 0x00010000 - // #define ISC_REQ_IDENTIFY 0x00020000 - // #define ISC_REQ_NULL_SESSION 0x00040000 - // #define ISC_REQ_MANUAL_CRED_VALIDATION 0x00080000 - // #define ISC_REQ_RESERVED1 0x00100000 - // #define ISC_REQ_FRAGMENT_TO_FIT 0x00200000 - // #define ISC_REQ_HTTP 0x10000000 - // Win7 SP1 + - // #define ISC_REQ_UNVERIFIED_TARGET_NAME 0x20000000 - - // #define ASC_REQ_DELEGATE 0x00000001 - // #define ASC_REQ_MUTUAL_AUTH 0x00000002 - // #define ASC_REQ_REPLAY_DETECT 0x00000004 - // #define ASC_REQ_SEQUENCE_DETECT 0x00000008 - // #define ASC_REQ_CONFIDENTIALITY 0x00000010 - // #define ASC_REQ_USE_SESSION_KEY 0x00000020 - // #define ASC_REQ_ALLOCATE_MEMORY 0x00000100 - // #define ASC_REQ_USE_DCE_STYLE 0x00000200 - // #define ASC_REQ_DATAGRAM 0x00000400 - // #define ASC_REQ_CONNECTION 0x00000800 - // #define ASC_REQ_CALL_LEVEL 0x00001000 - // #define ASC_REQ_EXTENDED_ERROR 0x00008000 - // #define ASC_REQ_STREAM 0x00010000 - // #define ASC_REQ_INTEGRITY 0x00020000 - // #define ASC_REQ_LICENSING 0x00040000 - // #define ASC_REQ_IDENTIFY 0x00080000 - // #define ASC_REQ_ALLOW_NULL_SESSION 0x00100000 - // #define ASC_REQ_ALLOW_NON_USER_LOGONS 0x00200000 - // #define ASC_REQ_ALLOW_CONTEXT_REPLAY 0x00400000 - // #define ASC_REQ_FRAGMENT_TO_FIT 0x00800000 - // #define ASC_REQ_FRAGMENT_SUPPLIED 0x00002000 - // #define ASC_REQ_NO_TOKEN 0x01000000 - // #define ASC_REQ_HTTP 0x10000000 - + // These values are defined within sspi.h as ISC_REQ_*, ISC_RET_*, ASC_REQ_* and ASC_RET_*. [Flags] internal enum ContextFlags { @@ -217,19 +131,20 @@ internal enum ContextFlags internal enum Endianness { - Network = 0x00, - Native = 0x10, + SECURITY_NETWORK_DREP = 0x00, + SECURITY_NATIVE_DREP = 0x10, } internal enum CredentialUse { - Inbound = 0x1, - Outbound = 0x2, - Both = 0x3, + SECPKG_CRED_INBOUND = 0x1, + SECPKG_CRED_OUTBOUND = 0x2, + SECPKG_CRED_BOTH = 0x3, } + // wincrypt.h [StructLayout(LayoutKind.Sequential)] - internal struct _CERT_CHAIN_ELEMENT + internal struct CERT_CHAIN_ELEMENT { public uint cbSize; public IntPtr pCertContext; @@ -241,14 +156,14 @@ internal struct _CERT_CHAIN_ELEMENT // IntPtr pApplicationUsage; } - // SecPkgContext_IssuerListInfoEx + // schannel.h [StructLayout(LayoutKind.Sequential)] - internal unsafe struct IssuerListInfoEx + internal unsafe struct SecPkgContext_IssuerListInfoEx { public SafeHandle aIssuers; public uint cIssuers; - public unsafe IssuerListInfoEx(SafeHandle handle, byte[] nativeBuffer) + public unsafe SecPkgContext_IssuerListInfoEx(SafeHandle handle, byte[] nativeBuffer) { aIssuers = handle; fixed (byte* voidPtr = nativeBuffer) @@ -260,34 +175,11 @@ public unsafe IssuerListInfoEx(SafeHandle handle, byte[] nativeBuffer) } [StructLayout(LayoutKind.Sequential)] - internal struct SecureCredential + internal struct SCHANNEL_CRED { - /* - typedef struct _SCHANNEL_CRED - { - DWORD dwVersion; // always SCHANNEL_CRED_VERSION - DWORD cCreds; - PCCERT_CONTEXT *paCred; - HCERTSTORE hRootStore; - - DWORD cMappers; - struct _HMAPPER **aphMappers; - - DWORD cSupportedAlgs; - ALG_ID * palgSupportedAlgs; - - DWORD grbitEnabledProtocols; - DWORD dwMinimumCipherStrength; - DWORD dwMaximumCipherStrength; - DWORD dwSessionLifespan; - DWORD dwFlags; - DWORD reserved; - } SCHANNEL_CRED, *PSCHANNEL_CRED; - */ - public const int CurrentVersion = 0x4; - public int version; + public int dwVersion; public int cCreds; // ptr to an array of pointers @@ -297,72 +189,64 @@ struct _HMAPPER **aphMappers; // and replace this field with the pointer, during the call to AcquireCredentialsHandle. // Then we fix it up afterwards. Fine as long as all the SSPI credentials are not // supposed to be threadsafe. - public IntPtr certContextArray; + public IntPtr paCred; - public IntPtr rootStore; // == always null, OTHERWISE NOT RELIABLE + public IntPtr hRootStore; // == always null, OTHERWISE NOT RELIABLE public int cMappers; - public IntPtr phMappers; // == always null, OTHERWISE NOT RELIABLE + public IntPtr aphMappers; // == always null, OTHERWISE NOT RELIABLE public int cSupportedAlgs; public IntPtr palgSupportedAlgs; // == always null, OTHERWISE NOT RELIABLE public int grbitEnabledProtocols; public int dwMinimumCipherStrength; public int dwMaximumCipherStrength; public int dwSessionLifespan; - public SecureCredential.Flags dwFlags; + public SCHANNEL_CRED.Flags dwFlags; public int reserved; [Flags] public enum Flags { Zero = 0, - NoSystemMapper = 0x02, - NoNameCheck = 0x04, - ValidateManual = 0x08, - NoDefaultCred = 0x10, - ValidateAuto = 0x20, - SendAuxRecord = 0x00200000, - UseStrongCrypto = 0x00400000, + SCH_CRED_NO_SYSTEM_MAPPER = 0x02, + SCH_CRED_NO_SERVERNAME_CHECK = 0x04, + SCH_CRED_MANUAL_CRED_VALIDATION = 0x08, + SCH_CRED_NO_DEFAULT_CREDS = 0x10, + SCH_CRED_AUTO_CRED_VALIDATION = 0x20, + SCH_SEND_AUX_RECORD = 0x00200000, + SCH_USE_STRONG_CRYPTO = 0x00400000, } - } // SecureCredential + } [StructLayout(LayoutKind.Sequential)] - internal unsafe struct SecurityBufferStruct + internal unsafe struct SecBuffer { - public int count; - public SecurityBufferType type; - public IntPtr token; + public int cbBuffer; + public SecurityBufferType BufferType; + public IntPtr pvBuffer; - public static readonly int Size = sizeof(SecurityBufferStruct); + public static readonly int Size = sizeof(SecBuffer); } [StructLayout(LayoutKind.Sequential)] - internal unsafe class SecurityBufferDescriptor + internal unsafe class SecBufferDesc { - /* - typedef struct _SecBufferDesc { - ULONG ulVersion; - ULONG cBuffers; - PSecBuffer pBuffers; - } SecBufferDesc, * PSecBufferDesc; - */ - public readonly int Version; - public readonly int Count; - public void* UnmanagedPointer; - - public SecurityBufferDescriptor(int count) + public readonly int ulVersion; + public readonly int cBuffers; + public void* pBuffers; + + public SecBufferDesc(int count) { - Version = 0; - Count = count; - UnmanagedPointer = null; + ulVersion = 0; + cBuffers = count; + pBuffers = null; } - } // SecurityBufferDescriptor + } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct AuthIdentity + internal struct SEC_WINNT_AUTH_IDENTITY_W { - // see SEC_WINNT_AUTH_IDENTITY_W - internal string UserName; - internal int UserNameLength; + internal string User; + internal int UserLength; internal string Domain; internal int DomainLength; internal string Password; @@ -372,23 +256,23 @@ internal struct AuthIdentity [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal static extern int EncryptMessage( - ref SSPIHandle contextHandle, + ref CredHandle contextHandle, [In] uint qualityOfProtection, - [In, Out] SecurityBufferDescriptor inputOutput, + [In, Out] SecBufferDesc inputOutput, [In] uint sequenceNumber ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal static unsafe extern int DecryptMessage( - [In] ref SSPIHandle contextHandle, - [In, Out] SecurityBufferDescriptor inputOutput, + [In] ref CredHandle contextHandle, + [In, Out] SecBufferDesc inputOutput, [In] uint sequenceNumber, uint* qualityOfProtection ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal static extern int QuerySecurityContextToken( - ref SSPIHandle phContext, + ref CredHandle phContext, [Out] out SecurityContextTokenHandle handle); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] @@ -397,36 +281,36 @@ internal static extern int FreeContextBuffer( [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal static extern int FreeCredentialsHandle( - ref SSPIHandle handlePtr + ref CredHandle handlePtr ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal static extern int DeleteSecurityContext( - ref SSPIHandle handlePtr + ref CredHandle handlePtr ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal unsafe static extern int AcceptSecurityContext( - ref SSPIHandle credentialHandle, + ref CredHandle credentialHandle, [In] void* inContextPtr, - [In] SecurityBufferDescriptor inputBuffer, + [In] SecBufferDesc inputBuffer, [In] ContextFlags inFlags, [In] Endianness endianness, - ref SSPIHandle outContextPtr, - [In, Out] SecurityBufferDescriptor outputBuffer, + ref CredHandle outContextPtr, + [In, Out] SecBufferDesc outputBuffer, [In, Out] ref ContextFlags attributes, out long timeStamp ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal unsafe static extern int QueryContextAttributesW( - ref SSPIHandle contextHandle, + ref CredHandle contextHandle, [In] ContextAttribute attribute, [In] void* buffer); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal unsafe static extern int SetContextAttributesW( - ref SSPIHandle contextHandle, + ref CredHandle contextHandle, [In] ContextAttribute attribute, [In] byte[] buffer, [In] int bufferSize); @@ -442,10 +326,10 @@ internal unsafe static extern int AcquireCredentialsHandleW( [In] string moduleName, [In] int usage, [In] void* logonID, - [In] ref AuthIdentity authdata, + [In] ref SEC_WINNT_AUTH_IDENTITY_W authdata, [In] void* keyCallback, [In] void* keyArgument, - ref SSPIHandle handlePtr, + ref CredHandle handlePtr, [Out] out long timeStamp ); @@ -458,7 +342,7 @@ internal unsafe static extern int AcquireCredentialsHandleW( [In] IntPtr zero, [In] void* keyCallback, [In] void* keyArgument, - ref SSPIHandle handlePtr, + ref CredHandle handlePtr, [Out] out long timeStamp ); @@ -471,7 +355,7 @@ internal unsafe static extern int AcquireCredentialsHandleW( [In] SafeSspiAuthDataHandle authdata, [In] void* keyCallback, [In] void* keyArgument, - ref SSPIHandle handlePtr, + ref CredHandle handlePtr, [Out] out long timeStamp ); @@ -481,25 +365,25 @@ internal unsafe static extern int AcquireCredentialsHandleW( [In] string moduleName, [In] int usage, [In] void* logonID, - [In] ref SecureCredential authData, + [In] ref SCHANNEL_CRED authData, [In] void* keyCallback, [In] void* keyArgument, - ref SSPIHandle handlePtr, + ref CredHandle handlePtr, [Out] out long timeStamp ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal unsafe static extern int InitializeSecurityContextW( - ref SSPIHandle credentialHandle, + ref CredHandle credentialHandle, [In] void* inContextPtr, [In] byte* targetName, [In] ContextFlags inFlags, [In] int reservedI, [In] Endianness endianness, - [In] SecurityBufferDescriptor inputBuffer, + [In] SecBufferDesc inputBuffer, [In] int reservedII, - ref SSPIHandle outContextPtr, - [In, Out] SecurityBufferDescriptor outputBuffer, + ref CredHandle outContextPtr, + [In, Out] SecBufferDesc outputBuffer, [In, Out] ref ContextFlags attributes, out long timeStamp ); @@ -507,15 +391,21 @@ out long timeStamp [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] internal unsafe static extern int CompleteAuthToken( [In] void* inContextPtr, - [In, Out] SecurityBufferDescriptor inputBuffers + [In, Out] SecBufferDesc inputBuffers ); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] - internal unsafe static extern SecurityStatus SspiFreeAuthIdentity( + internal unsafe static extern int ApplyControlToken( + [In] void* inContextPtr, + [In, Out] SecBufferDesc inputBuffers + ); + + [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, SetLastError = true)] + internal unsafe static extern SECURITY_STATUS SspiFreeAuthIdentity( [In] IntPtr authData); [DllImport(Interop.Libraries.Sspi, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)] - internal unsafe static extern SecurityStatus SspiEncodeStringsAsAuthIdentity( + internal unsafe static extern SECURITY_STATUS SspiEncodeStringsAsAuthIdentity( [In] string userName, [In] string domainName, [In] string password, diff --git a/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs b/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs index ad81a9685307..446b6da3b7f5 100644 --- a/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs +++ b/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs @@ -35,7 +35,7 @@ public int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer p return SafeFreeContextBuffer.EnumeratePackages(out pkgnum, out pkgArray); } - public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.AuthIdentity authdata, out SafeFreeCredentials outCredential) + public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SEC_WINNT_AUTH_IDENTITY_W authdata, out SafeFreeCredentials outCredential) { return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); } @@ -50,7 +50,7 @@ public int AcquireDefaultCredential(string moduleName, Interop.SspiCli.Credentia return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential); } - public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SecureCredential authdata, out SafeFreeCredentials outCredential) + public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential) { return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); } @@ -75,7 +75,7 @@ public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDel return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); } - public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { try { @@ -90,9 +90,9 @@ public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBuf } } - public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { - int status = (int)Interop.SecurityStatus.InvalidHandle; + int status = (int)Interop.SECURITY_STATUS.InvalidHandle; uint qop = 0; try @@ -121,7 +121,7 @@ public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.Secu return status; } - public int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { try { @@ -137,7 +137,7 @@ public int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecurityBuff } } - public unsafe int VerifySignature(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public unsafe int VerifySignature(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { try { @@ -215,5 +215,10 @@ private static int GetSecurityContextToken(SafeDeleteContext phContext, out Secu phContext.DangerousRelease(); } } + + public int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) + { + throw new NotSupportedException(); + } } } diff --git a/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs b/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs index 4728c354669a..38f08705db6b 100644 --- a/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs +++ b/src/Common/src/Interop/Windows/sspicli/SSPIInterface.cs @@ -12,23 +12,24 @@ internal interface SSPIInterface { SecurityPackageInfoClass[] SecurityPackages { get; set; } int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer pkgArray); - int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.AuthIdentity authdata, out SafeFreeCredentials outCredential); + int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SEC_WINNT_AUTH_IDENTITY_W authdata, out SafeFreeCredentials outCredential); int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref SafeSspiAuthDataHandle authdata, out SafeFreeCredentials outCredential); int AcquireDefaultCredential(string moduleName, Interop.SspiCli.CredentialUse usage, out SafeFreeCredentials outCredential); - int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SecureCredential authdata, out SafeFreeCredentials outCredential); + int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential); int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags); int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags); int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags); int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags); - int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber); - int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber); - int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber); - int VerifySignature(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber); + int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber); + int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber); + int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber); + int VerifySignature(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber); int QueryContextChannelBinding(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, out SafeFreeContextBufferChannelBinding refHandle); int QueryContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, byte[] buffer, Type handleType, out SafeHandle refHandle); int SetContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, byte[] buffer); int QuerySecurityContextToken(SafeDeleteContext phContext, out SecurityContextTokenHandle phToken); int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers); + int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers); } } diff --git a/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs b/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs index d5f8bcd71cef..58ce7f3a44b5 100644 --- a/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs +++ b/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs @@ -33,7 +33,7 @@ public int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer p return SafeFreeContextBuffer.EnumeratePackages(out pkgnum, out pkgArray); } - public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.AuthIdentity authdata, out SafeFreeCredentials outCredential) + public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SEC_WINNT_AUTH_IDENTITY_W authdata, out SafeFreeCredentials outCredential) { return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); } @@ -48,7 +48,7 @@ public int AcquireDefaultCredential(string moduleName, Interop.SspiCli.Credentia return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential); } - public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SecureCredential authdata, out SafeFreeCredentials outCredential) + public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential) { return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential); } @@ -73,7 +73,7 @@ public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDel return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags); } - public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { try { @@ -87,7 +87,7 @@ public int EncryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBuf } } - public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, + public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { try @@ -102,12 +102,12 @@ public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.Secu } } - public int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public int MakeSignature(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } - public int VerifySignature(SafeDeleteContext context, Interop.SspiCli.SecurityBufferDescriptor inputOutput, uint sequenceNumber) + public int VerifySignature(SafeDeleteContext context, Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber) { throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } @@ -117,7 +117,7 @@ public unsafe int QueryContextChannelBinding(SafeDeleteContext phContext, Intero refHandle = SafeFreeContextBufferChannelBinding.CreateEmptyHandle(); // Bindings is on the stack, so there's no need for a fixed block. - Bindings bindings = new Bindings(); + SecPkgContext_Bindings bindings = new SecPkgContext_Bindings(); return SafeFreeContextBufferChannelBinding.QueryContextChannelBinding(phContext, attribute, &bindings, refHandle); } @@ -159,5 +159,10 @@ public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] { throw new NotSupportedException(); } + + public int ApplyControlToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers) + { + return SafeDeleteContext.ApplyControlToken(ref refContext, inputBuffers); + } } } diff --git a/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs b/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs index 315d10798427..d92d864f1221 100644 --- a/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs +++ b/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs @@ -137,7 +137,7 @@ public static SafeFreeCredentials AcquireDefaultCredential(SSPIInterface secModu return outCredential; } - public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, ref Interop.SspiCli.AuthIdentity authdata) + public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, ref Interop.SspiCli.SEC_WINNT_AUTH_IDENTITY_W authdata) { if (GlobalLog.IsEnabled) { @@ -196,7 +196,7 @@ public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModu return credentialsHandle; } - public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, Interop.SspiCli.SecureCredential scc) + public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, Interop.SspiCli.SCHANNEL_CRED scc) { if (GlobalLog.IsEnabled) { @@ -255,7 +255,7 @@ internal static int InitializeSecurityContext(SSPIInterface secModule, ref SafeF if (SecurityEventSource.Log.IsEnabled()) { - SecurityEventSource.Log.SecurityContextInputBuffer(nameof(InitializeSecurityContext), (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode); + SecurityEventSource.Log.SecurityContextInputBuffer(nameof(InitializeSecurityContext), (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return errorCode; @@ -275,7 +275,7 @@ internal static int InitializeSecurityContext(SSPIInterface secModule, SafeFreeC if (SecurityEventSource.Log.IsEnabled()) { - SecurityEventSource.Log.SecurityContextInputBuffers(nameof(InitializeSecurityContext), (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode); + SecurityEventSource.Log.SecurityContextInputBuffers(nameof(InitializeSecurityContext), (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return errorCode; @@ -292,7 +292,7 @@ internal static int AcceptSecurityContext(SSPIInterface secModule, ref SafeFreeC if (SecurityEventSource.Log.IsEnabled()) { - SecurityEventSource.Log.SecurityContextInputBuffer(nameof(AcceptSecurityContext), (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SecurityStatus)errorCode); + SecurityEventSource.Log.SecurityContextInputBuffer(nameof(AcceptSecurityContext), (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return errorCode; @@ -309,7 +309,7 @@ internal static int AcceptSecurityContext(SSPIInterface secModule, SafeFreeCrede if (SecurityEventSource.Log.IsEnabled()) { - SecurityEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SecurityStatus)errorCode); + SecurityEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (Interop.SECURITY_STATUS)errorCode); } return errorCode; @@ -321,7 +321,19 @@ internal static int CompleteAuthToken(SSPIInterface secModule, ref SafeDeleteCon if (SecurityEventSource.Log.IsEnabled()) { - SecurityEventSource.Log.OperationReturnedSomething("CompleteAuthToken()", (Interop.SecurityStatus)errorCode); + SecurityEventSource.Log.OperationReturnedSomething("CompleteAuthToken()", (Interop.SECURITY_STATUS)errorCode); + } + + return errorCode; + } + + internal static int ApplyControlToken(SSPIInterface secModule, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers) + { + int errorCode = secModule.ApplyControlToken(ref context, inputBuffers); + + if (SecurityEventSource.Log.IsEnabled()) + { + SecurityEventSource.Log.OperationReturnedSomething("ApplyControlToken()", (Interop.SECURITY_STATUS)errorCode); } return errorCode; @@ -362,12 +374,12 @@ private enum OP private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) { - Interop.SspiCli.SecurityBufferDescriptor sdcInOut = new Interop.SspiCli.SecurityBufferDescriptor(input.Length); - var unmanagedBuffer = new Interop.SspiCli.SecurityBufferStruct[input.Length]; + Interop.SspiCli.SecBufferDesc sdcInOut = new Interop.SspiCli.SecBufferDesc(input.Length); + var unmanagedBuffer = new Interop.SspiCli.SecBuffer[input.Length]; - fixed (Interop.SspiCli.SecurityBufferStruct* unmanagedBufferPtr = unmanagedBuffer) + fixed (Interop.SspiCli.SecBuffer* unmanagedBufferPtr = unmanagedBuffer) { - sdcInOut.UnmanagedPointer = unmanagedBufferPtr; + sdcInOut.pBuffers = unmanagedBufferPtr; GCHandle[] pinnedBuffers = new GCHandle[input.Length]; byte[][] buffers = new byte[input.Length][]; try @@ -375,16 +387,16 @@ private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, S for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; - unmanagedBuffer[i].count = iBuffer.size; - unmanagedBuffer[i].type = iBuffer.type; + unmanagedBuffer[i].cbBuffer = iBuffer.size; + unmanagedBuffer[i].BufferType = iBuffer.type; if (iBuffer.token == null || iBuffer.token.Length == 0) { - unmanagedBuffer[i].token = IntPtr.Zero; + unmanagedBuffer[i].pvBuffer = IntPtr.Zero; } else { pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); - unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); + unmanagedBuffer[i].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset); buffers[i] = iBuffer.token; } } @@ -423,8 +435,8 @@ private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, S for (int i = 0; i < input.Length; i++) { SecurityBuffer iBuffer = input[i]; - iBuffer.size = unmanagedBuffer[i].count; - iBuffer.type = unmanagedBuffer[i].type; + iBuffer.size = unmanagedBuffer[i].cbBuffer; + iBuffer.type = unmanagedBuffer[i].BufferType; if (iBuffer.size == 0) { @@ -445,10 +457,10 @@ private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, S } byte* bufferAddress = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0); - if ((byte*)unmanagedBuffer[i].token >= bufferAddress && - (byte*)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length) + if ((byte*)unmanagedBuffer[i].pvBuffer >= bufferAddress && + (byte*)unmanagedBuffer[i].pvBuffer + iBuffer.size <= bufferAddress + buffers[j].Length) { - iBuffer.offset = (int)((byte*)unmanagedBuffer[i].token - bufferAddress); + iBuffer.offset = (int)((byte*)unmanagedBuffer[i].pvBuffer - bufferAddress); iBuffer.token = buffers[j]; break; } @@ -561,45 +573,45 @@ public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteC switch (contextAttribute) { - case Interop.SspiCli.ContextAttribute.Sizes: - nativeBlockSize = SecSizes.SizeOf; + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: + nativeBlockSize = SecPkgContext_Sizes.SizeOf; break; - case Interop.SspiCli.ContextAttribute.StreamSizes: - nativeBlockSize = StreamSizes.SizeOf; + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: + nativeBlockSize = SecPkgContext_StreamSizes.SizeOf; break; - case Interop.SspiCli.ContextAttribute.Names: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: handleType = typeof(SafeFreeContextBuffer); break; - case Interop.SspiCli.ContextAttribute.PackageInfo: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: handleType = typeof(SafeFreeContextBuffer); break; - case Interop.SspiCli.ContextAttribute.NegotiationInfo: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: handleType = typeof(SafeFreeContextBuffer); - nativeBlockSize = Marshal.SizeOf(); + nativeBlockSize = Marshal.SizeOf(); break; - case Interop.SspiCli.ContextAttribute.ClientSpecifiedSpn: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: handleType = typeof(SafeFreeContextBuffer); break; - case Interop.SspiCli.ContextAttribute.RemoteCertificate: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; - case Interop.SspiCli.ContextAttribute.LocalCertificate: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: handleType = typeof(SafeFreeCertContext); break; - case Interop.SspiCli.ContextAttribute.IssuerListInfoEx: - nativeBlockSize = Marshal.SizeOf(); + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: + nativeBlockSize = Marshal.SizeOf(); handleType = typeof(SafeFreeContextBuffer); break; - case Interop.SspiCli.ContextAttribute.ConnectionInfo: - nativeBlockSize = Marshal.SizeOf(); + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: + nativeBlockSize = Marshal.SizeOf(); break; default: @@ -624,50 +636,50 @@ public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteC switch (contextAttribute) { - case Interop.SspiCli.ContextAttribute.Sizes: - attribute = new SecSizes(nativeBuffer); + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES: + attribute = new SecPkgContext_Sizes(nativeBuffer); break; - case Interop.SspiCli.ContextAttribute.StreamSizes: - attribute = new StreamSizes(nativeBuffer); + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES: + attribute = new SecPkgContext_StreamSizes(nativeBuffer); break; - case Interop.SspiCli.ContextAttribute.Names: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; - case Interop.SspiCli.ContextAttribute.PackageInfo: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO: attribute = new SecurityPackageInfoClass(sspiHandle, 0); break; - case Interop.SspiCli.ContextAttribute.NegotiationInfo: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO: unsafe { fixed (void* ptr = nativeBuffer) { - attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffest)); + attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), SecPkgContext_NegotiationInfoW.NegotiationStateOffest)); } } break; - case Interop.SspiCli.ContextAttribute.ClientSpecifiedSpn: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET: attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()); break; - case Interop.SspiCli.ContextAttribute.LocalCertificate: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT: // Fall-through to RemoteCertificate is intentional. - case Interop.SspiCli.ContextAttribute.RemoteCertificate: + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT: attribute = sspiHandle; sspiHandle = null; break; - case Interop.SspiCli.ContextAttribute.IssuerListInfoEx: - attribute = new Interop.SspiCli.IssuerListInfoEx(sspiHandle, nativeBuffer); + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX: + attribute = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer); sspiHandle = null; break; - case Interop.SspiCli.ContextAttribute.ConnectionInfo: - attribute = new SslConnectionInfo(nativeBuffer); + case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO: + attribute = new SecPkgContext_ConnectionInfo(nativeBuffer); break; default: // Will return null. @@ -697,27 +709,27 @@ public static string ErrorDescription(int errorCode) return "An exception when invoking Win32 API"; } - switch ((Interop.SecurityStatus)errorCode) + switch ((Interop.SECURITY_STATUS)errorCode) { - case Interop.SecurityStatus.InvalidHandle: + case Interop.SECURITY_STATUS.InvalidHandle: return "Invalid handle"; - case Interop.SecurityStatus.InvalidToken: + case Interop.SECURITY_STATUS.InvalidToken: return "Invalid token"; - case Interop.SecurityStatus.ContinueNeeded: + case Interop.SECURITY_STATUS.ContinueNeeded: return "Continue needed"; - case Interop.SecurityStatus.IncompleteMessage: + case Interop.SECURITY_STATUS.IncompleteMessage: return "Message incomplete"; - case Interop.SecurityStatus.WrongPrincipal: + case Interop.SECURITY_STATUS.WrongPrincipal: return "Wrong principal"; - case Interop.SecurityStatus.TargetUnknown: + case Interop.SECURITY_STATUS.TargetUnknown: return "Target unknown"; - case Interop.SecurityStatus.PackageNotFound: + case Interop.SECURITY_STATUS.PackageNotFound: return "Package not found"; - case Interop.SecurityStatus.BufferNotEnough: + case Interop.SECURITY_STATUS.BufferNotEnough: return "Buffer not enough"; - case Interop.SecurityStatus.MessageAltered: + case Interop.SECURITY_STATUS.MessageAltered: return "Message altered"; - case Interop.SecurityStatus.UntrustedRoot: + case Interop.SECURITY_STATUS.UntrustedRoot: return "Untrusted root"; default: return "0x" + errorCode.ToString("x", NumberFormatInfo.InvariantInfo); diff --git a/src/Common/src/Interop/Windows/sspicli/Bindings.cs b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.cs similarity index 76% rename from src/Common/src/Interop/Windows/sspicli/Bindings.cs rename to src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.cs index cabf31d2d4a1..eb31544de178 100644 --- a/src/Common/src/Interop/Windows/sspicli/Bindings.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Bindings.cs @@ -6,11 +6,11 @@ namespace System.Net { + // sspi.h [StructLayout(LayoutKind.Sequential)] - internal struct Bindings + internal struct SecPkgContext_Bindings { - // SecPkgContext_Bindings in sspi.h. internal int BindingsLength; - internal IntPtr pBindings; + internal IntPtr Bindings; } } diff --git a/src/Common/src/Interop/Windows/sspicli/NegotiationInfo.cs b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.cs similarity index 66% rename from src/Common/src/Interop/Windows/sspicli/NegotiationInfo.cs rename to src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.cs index 9b8cdf526a23..4d5ae59c1c6f 100644 --- a/src/Common/src/Interop/Windows/sspicli/NegotiationInfo.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_NegotiationInfoW.cs @@ -6,13 +6,13 @@ namespace System.Net { - // SecPkgContext_NegotiationInfoW in sspi.h. + // sspi.h [StructLayout(LayoutKind.Sequential)] - internal struct NegotiationInfo + internal struct SecPkgContext_NegotiationInfoW { internal IntPtr PackageInfo; internal uint NegotiationState; - internal static readonly int Size = Marshal.SizeOf(); - internal static readonly int NegotiationStateOffest = (int)Marshal.OffsetOf("NegotiationState"); + internal static readonly int Size = Marshal.SizeOf(); + internal static readonly int NegotiationStateOffest = (int)Marshal.OffsetOf("NegotiationState"); } } diff --git a/src/Common/src/Interop/Windows/sspicli/SecSizes.cs b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.cs similarity index 56% rename from src/Common/src/Interop/Windows/sspicli/SecSizes.cs rename to src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.cs index 0f8091c729e9..7ad645cf1ce0 100644 --- a/src/Common/src/Interop/Windows/sspicli/SecSizes.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_Sizes.cs @@ -7,16 +7,16 @@ namespace System.Net { - // _SecPkgContext_Sizes in sspi.h. + // sspi.h [StructLayout(LayoutKind.Sequential)] - internal class SecSizes + internal class SecPkgContext_Sizes { - public readonly int MaxToken; - public readonly int MaxSignature; - public readonly int BlockSize; - public readonly int SecurityTrailer; + public readonly int cbMaxToken; + public readonly int cbMaxSignature; + public readonly int cbBlockSize; + public readonly int cbSecurityTrailer; - internal unsafe SecSizes(byte[] memory) + internal unsafe SecPkgContext_Sizes(byte[] memory) { fixed (void* voidPtr = memory) { @@ -24,10 +24,10 @@ internal unsafe SecSizes(byte[] memory) try { // TODO (Issue #3114): replace with Marshal.PtrToStructure. - MaxToken = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress)); - MaxSignature = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 4)); - BlockSize = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 8)); - SecurityTrailer = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 12)); + cbMaxToken = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress)); + cbMaxSignature = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 4)); + cbBlockSize = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 8)); + cbSecurityTrailer = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 12)); } catch (OverflowException) { @@ -41,6 +41,7 @@ internal unsafe SecSizes(byte[] memory) } } } - public static readonly int SizeOf = Marshal.SizeOf(); + + public static readonly int SizeOf = Marshal.SizeOf(); } } diff --git a/src/Common/src/Interop/Windows/sspicli/StreamSizes.cs b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.cs similarity index 54% rename from src/Common/src/Interop/Windows/sspicli/StreamSizes.cs rename to src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.cs index 8ddd24e1ef50..32f78a0b92a9 100644 --- a/src/Common/src/Interop/Windows/sspicli/StreamSizes.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecPkgContext_StreamSizes.cs @@ -7,17 +7,17 @@ namespace System.Net { - // _SecPkgContext_StreamSizes in sspi.h. + // sspi.h [StructLayout(LayoutKind.Sequential)] - internal class StreamSizes + internal class SecPkgContext_StreamSizes { - public int header; - public int trailer; - public int maximumMessage; - public int buffersCount; - public int blockSize; + public int cbHeader; + public int cbTrailer; + public int cbMaximumMessage; + public int cBuffers; + public int cbBlockSize; - internal unsafe StreamSizes(byte[] memory) + internal unsafe SecPkgContext_StreamSizes(byte[] memory) { fixed (void* voidPtr = memory) { @@ -25,11 +25,11 @@ internal unsafe StreamSizes(byte[] memory) try { // TODO (Issue #3114): replace with Marshal.PtrToStructure. - header = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress)); - trailer = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 4)); - maximumMessage = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 8)); - buffersCount = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 12)); - blockSize = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 16)); + cbHeader = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress)); + cbTrailer = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 4)); + cbMaximumMessage = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 8)); + cBuffers = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 12)); + cbBlockSize = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 16)); } catch (OverflowException) { @@ -44,6 +44,6 @@ internal unsafe StreamSizes(byte[] memory) } } - public static readonly int SizeOf = Marshal.SizeOf(); + public static readonly int SizeOf = Marshal.SizeOf(); } } diff --git a/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs b/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs index 9c71157836b8..478536feb072 100644 --- a/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs @@ -26,7 +26,7 @@ public SafeSspiAuthDataHandle() : base(true) protected override bool ReleaseHandle() { - return Interop.SspiCli.SspiFreeAuthIdentity(handle) == Interop.SecurityStatus.OK; + return Interop.SspiCli.SspiFreeAuthIdentity(handle) == Interop.SECURITY_STATUS.OK; } } @@ -86,7 +86,7 @@ private unsafe static int QueryContextAttributes_SECURITY( byte* buffer, SafeHandle refHandle) { - int status = (int)Interop.SecurityStatus.InvalidHandle; + int status = (int)Interop.SECURITY_STATUS.InvalidHandle; try { @@ -193,11 +193,11 @@ internal abstract class SafeFreeCredentials : SafeHandle { #endif - internal Interop.SspiCli.SSPIHandle _handle; //should be always used as by ref in PInvokes parameters + internal Interop.SspiCli.CredHandle _handle; //should be always used as by ref in PInvokes parameters protected SafeFreeCredentials() : base(IntPtr.Zero, true) { - _handle = new Interop.SspiCli.SSPIHandle(); + _handle = new Interop.SspiCli.CredHandle(); } #if TRACE_VERBOSE @@ -223,7 +223,7 @@ public override bool IsInvalid public unsafe static int AcquireCredentialsHandle( string package, Interop.SspiCli.CredentialUse intent, - ref Interop.SspiCli.AuthIdentity authdata, + ref Interop.SspiCli.SEC_WINNT_AUTH_IDENTITY_W authdata, out SafeFreeCredentials outCredential) { if (GlobalLog.IsEnabled) @@ -343,7 +343,7 @@ public unsafe static int AcquireCredentialsHandle( public unsafe static int AcquireCredentialsHandle( string package, Interop.SspiCli.CredentialUse intent, - ref Interop.SspiCli.SecureCredential authdata, + ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential) { if (GlobalLog.IsEnabled) @@ -360,13 +360,13 @@ public unsafe static int AcquireCredentialsHandle( // If there is a certificate, wrap it into an array. // Not threadsafe. - IntPtr copiedPtr = authdata.certContextArray; + IntPtr copiedPtr = authdata.paCred; try { IntPtr certArrayPtr = new IntPtr(&copiedPtr); if (copiedPtr != IntPtr.Zero) { - authdata.certContextArray = certArrayPtr; + authdata.paCred = certArrayPtr; } outCredential = new SafeFreeCredential_SECURITY(); @@ -384,7 +384,7 @@ public unsafe static int AcquireCredentialsHandle( } finally { - authdata.certContextArray = copiedPtr; + authdata.paCred = copiedPtr; } #if TRACE_VERBOSE @@ -481,13 +481,13 @@ internal abstract class SafeDeleteContext : SafeHandle // ATN: _handle is internal since it is used on PInvokes by other wrapper methods. // However all such wrappers MUST manually and reliably adjust refCounter of SafeDeleteContext handle. // - internal Interop.SspiCli.SSPIHandle _handle; + internal Interop.SspiCli.CredHandle _handle; protected SafeFreeCredentials _EffectiveCredential; protected SafeDeleteContext() : base(IntPtr.Zero, true) { - _handle = new Interop.SspiCli.SSPIHandle(); + _handle = new Interop.SspiCli.CredHandle(); } public override bool IsInvalid @@ -568,24 +568,24 @@ internal unsafe static int InitializeSecurityContext( throw new ArgumentNullException(nameof(inCredentials)); } - Interop.SspiCli.SecurityBufferDescriptor inSecurityBufferDescriptor = null; + Interop.SspiCli.SecBufferDesc inSecurityBufferDescriptor = null; if (inSecBuffer != null) { - inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(1); + inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(1); } else if (inSecBuffers != null) { - inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(inSecBuffers.Length); + inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Length); } - Interop.SspiCli.SecurityBufferDescriptor outSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(1); + Interop.SspiCli.SecBufferDesc outSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(1); // Actually, this is returned in outFlags. bool isSspiAllocated = (inFlags & Interop.SspiCli.ContextFlags.AllocateMemory) != 0 ? true : false; int errorCode = -1; - Interop.SspiCli.SSPIHandle contextHandle = new Interop.SspiCli.SSPIHandle(); + Interop.SspiCli.CredHandle contextHandle = new Interop.SspiCli.CredHandle(); if (refContext != null) { contextHandle = refContext._handle; @@ -600,37 +600,37 @@ internal unsafe static int InitializeSecurityContext( try { pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); - Interop.SspiCli.SecurityBufferStruct[] inUnmanagedBuffer = new Interop.SspiCli.SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count]; + Interop.SspiCli.SecBuffer[] inUnmanagedBuffer = new Interop.SspiCli.SecBuffer[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.cBuffers]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { if (inSecurityBufferDescriptor != null) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. - inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; - pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; + inSecurityBufferDescriptor.pBuffers = inUnmanagedBufferPtr; + pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.cBuffers]; SecurityBuffer securityBuffer; - for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) + for (int index = 0; index < inSecurityBufferDescriptor.cBuffers; ++index) { securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index]; if (securityBuffer != null) { // Copy the SecurityBuffer content into unmanaged place holder. - inUnmanagedBuffer[index].count = securityBuffer.size; - inUnmanagedBuffer[index].type = securityBuffer.type; + inUnmanagedBuffer[index].cbBuffer = securityBuffer.size; + inUnmanagedBuffer[index].BufferType = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { - inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[index].pvBuffer = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { - inUnmanagedBuffer[index].token = IntPtr.Zero; + inUnmanagedBuffer[index].pvBuffer = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); - inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); + inUnmanagedBuffer[index].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE if (GlobalLog.IsEnabled) @@ -642,20 +642,20 @@ internal unsafe static int InitializeSecurityContext( } } - Interop.SspiCli.SecurityBufferStruct[] outUnmanagedBuffer = new Interop.SspiCli.SecurityBufferStruct[1]; + Interop.SspiCli.SecBuffer[] outUnmanagedBuffer = new Interop.SspiCli.SecBuffer[1]; fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. - outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr; - outUnmanagedBuffer[0].count = outSecBuffer.size; - outUnmanagedBuffer[0].type = outSecBuffer.type; + outSecurityBufferDescriptor.pBuffers = outUnmanagedBufferPtr; + outUnmanagedBuffer[0].cbBuffer = outSecBuffer.size; + outUnmanagedBuffer[0].BufferType = outSecBuffer.type; if (outSecBuffer.token == null || outSecBuffer.token.Length == 0) { - outUnmanagedBuffer[0].token = IntPtr.Zero; + outUnmanagedBuffer[0].pvBuffer = IntPtr.Zero; } else { - outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); + outUnmanagedBuffer[0].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (isSspiAllocated) @@ -694,12 +694,12 @@ internal unsafe static int InitializeSecurityContext( } // Get unmanaged buffer with index 0 as the only one passed into PInvoke. - outSecBuffer.size = outUnmanagedBuffer[0].count; - outSecBuffer.type = outUnmanagedBuffer[0].type; + outSecBuffer.size = outUnmanagedBuffer[0].cbBuffer; + outSecBuffer.type = outUnmanagedBuffer[0].BufferType; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; - Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size); + Marshal.Copy(outUnmanagedBuffer[0].pvBuffer, outSecBuffer.token, 0, outSecBuffer.size); } else { @@ -749,13 +749,13 @@ private static unsafe int MustRunInitializeSecurityContext_SECURITY( byte* targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, - Interop.SspiCli.SecurityBufferDescriptor inputBuffer, + Interop.SspiCli.SecBufferDesc inputBuffer, SafeDeleteContext outContext, - Interop.SspiCli.SecurityBufferDescriptor outputBuffer, + Interop.SspiCli.SecBufferDesc outputBuffer, ref Interop.SspiCli.ContextFlags attributes, SafeFreeContextBuffer handleTemplate) { - int errorCode = (int)Interop.SecurityStatus.InvalidHandle; + int errorCode = (int)Interop.SECURITY_STATUS.InvalidHandle; try { @@ -763,7 +763,7 @@ private static unsafe int MustRunInitializeSecurityContext_SECURITY( inCredentials.DangerousAddRef(ref ignore); outContext.DangerousAddRef(ref ignore); - Interop.SspiCli.SSPIHandle credentialHandle = inCredentials._handle; + Interop.SspiCli.CredHandle credentialHandle = inCredentials._handle; long timeStamp; @@ -810,7 +810,7 @@ private static unsafe int MustRunInitializeSecurityContext_SECURITY( if (handleTemplate != null) { //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes - handleTemplate.Set(((Interop.SspiCli.SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); + handleTemplate.Set(((Interop.SspiCli.SecBuffer*)outputBuffer.pBuffers)->pvBuffer); if (handleTemplate.IsInvalid) { handleTemplate.SetHandleAsInvalid(); @@ -880,24 +880,24 @@ internal unsafe static int AcceptSecurityContext( throw new ArgumentNullException(nameof(inCredentials)); } - Interop.SspiCli.SecurityBufferDescriptor inSecurityBufferDescriptor = null; + Interop.SspiCli.SecBufferDesc inSecurityBufferDescriptor = null; if (inSecBuffer != null) { - inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(1); + inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(1); } else if (inSecBuffers != null) { - inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(inSecBuffers.Length); + inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Length); } - Interop.SspiCli.SecurityBufferDescriptor outSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(1); + Interop.SspiCli.SecBufferDesc outSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(1); // Actually, this is returned in outFlags. bool isSspiAllocated = (inFlags & Interop.SspiCli.ContextFlags.AllocateMemory) != 0 ? true : false; int errorCode = -1; - Interop.SspiCli.SSPIHandle contextHandle = new Interop.SspiCli.SSPIHandle(); + Interop.SspiCli.CredHandle contextHandle = new Interop.SspiCli.CredHandle(); if (refContext != null) { contextHandle = refContext._handle; @@ -912,37 +912,37 @@ internal unsafe static int AcceptSecurityContext( try { pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned); - var inUnmanagedBuffer = new Interop.SspiCli.SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count]; + var inUnmanagedBuffer = new Interop.SspiCli.SecBuffer[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.cBuffers]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { if (inSecurityBufferDescriptor != null) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. - inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; - pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; + inSecurityBufferDescriptor.pBuffers = inUnmanagedBufferPtr; + pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.cBuffers]; SecurityBuffer securityBuffer; - for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) + for (int index = 0; index < inSecurityBufferDescriptor.cBuffers; ++index) { securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index]; if (securityBuffer != null) { // Copy the SecurityBuffer content into unmanaged place holder. - inUnmanagedBuffer[index].count = securityBuffer.size; - inUnmanagedBuffer[index].type = securityBuffer.type; + inUnmanagedBuffer[index].cbBuffer = securityBuffer.size; + inUnmanagedBuffer[index].BufferType = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { - inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[index].pvBuffer = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { - inUnmanagedBuffer[index].token = IntPtr.Zero; + inUnmanagedBuffer[index].pvBuffer = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); - inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); + inUnmanagedBuffer[index].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE if (GlobalLog.IsEnabled) @@ -954,22 +954,22 @@ internal unsafe static int AcceptSecurityContext( } } - var outUnmanagedBuffer = new Interop.SspiCli.SecurityBufferStruct[1]; + var outUnmanagedBuffer = new Interop.SspiCli.SecBuffer[1]; fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. - outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr; + outSecurityBufferDescriptor.pBuffers = outUnmanagedBufferPtr; // Copy the SecurityBuffer content into unmanaged place holder. - outUnmanagedBuffer[0].count = outSecBuffer.size; - outUnmanagedBuffer[0].type = outSecBuffer.type; + outUnmanagedBuffer[0].cbBuffer = outSecBuffer.size; + outUnmanagedBuffer[0].BufferType = outSecBuffer.type; if (outSecBuffer.token == null || outSecBuffer.token.Length == 0) { - outUnmanagedBuffer[0].token = IntPtr.Zero; + outUnmanagedBuffer[0].pvBuffer = IntPtr.Zero; } else { - outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); + outUnmanagedBuffer[0].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset); } if (isSspiAllocated) @@ -999,12 +999,12 @@ internal unsafe static int AcceptSecurityContext( } // Get unmanaged buffer with index 0 as the only one passed into PInvoke. - outSecBuffer.size = outUnmanagedBuffer[0].count; - outSecBuffer.type = outUnmanagedBuffer[0].type; + outSecBuffer.size = outUnmanagedBuffer[0].cbBuffer; + outSecBuffer.type = outUnmanagedBuffer[0].BufferType; if (outSecBuffer.size > 0) { outSecBuffer.token = new byte[outSecBuffer.size]; - Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size); + Marshal.Copy(outUnmanagedBuffer[0].pvBuffer, outSecBuffer.token, 0, outSecBuffer.size); } else { @@ -1052,15 +1052,15 @@ internal unsafe static int AcceptSecurityContext( private static unsafe int MustRunAcceptSecurityContext_SECURITY( ref SafeFreeCredentials inCredentials, void* inContextPtr, - Interop.SspiCli.SecurityBufferDescriptor inputBuffer, + Interop.SspiCli.SecBufferDesc inputBuffer, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, SafeDeleteContext outContext, - Interop.SspiCli.SecurityBufferDescriptor outputBuffer, + Interop.SspiCli.SecBufferDesc outputBuffer, ref Interop.SspiCli.ContextFlags outFlags, SafeFreeContextBuffer handleTemplate) { - int errorCode = (int)Interop.SecurityStatus.InvalidHandle; + int errorCode = (int)Interop.SECURITY_STATUS.InvalidHandle; // Run the body of this method as a non-interruptible block. try @@ -1070,7 +1070,7 @@ private static unsafe int MustRunAcceptSecurityContext_SECURITY( inCredentials.DangerousAddRef(ref ignore); outContext.DangerousAddRef(ref ignore); - Interop.SspiCli.SSPIHandle credentialHandle = inCredentials._handle; + Interop.SspiCli.CredHandle credentialHandle = inCredentials._handle; long timeStamp; errorCode = Interop.SspiCli.AcceptSecurityContext( @@ -1113,7 +1113,7 @@ private static unsafe int MustRunAcceptSecurityContext_SECURITY( if (handleTemplate != null) { //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes. - handleTemplate.Set(((Interop.SspiCli.SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); + handleTemplate.Set(((Interop.SspiCli.SecBuffer*)outputBuffer.pBuffers)->pvBuffer); if (handleTemplate.IsInvalid) { handleTemplate.SetHandleAsInvalid(); @@ -1151,41 +1151,41 @@ internal unsafe static int CompleteAuthToken( Debug.Fail("SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null"); } - var inSecurityBufferDescriptor = new Interop.SspiCli.SecurityBufferDescriptor(inSecBuffers.Length); + var inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Length); - int errorCode = (int)Interop.SecurityStatus.InvalidHandle; + int errorCode = (int)Interop.SECURITY_STATUS.InvalidHandle; // These are pinned user byte arrays passed along with SecurityBuffers. GCHandle[] pinnedInBytes = null; - var inUnmanagedBuffer = new Interop.SspiCli.SecurityBufferStruct[inSecurityBufferDescriptor.Count]; + var inUnmanagedBuffer = new Interop.SspiCli.SecBuffer[inSecurityBufferDescriptor.cBuffers]; fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) { // Fix Descriptor pointer that points to unmanaged SecurityBuffers. - inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr; - pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count]; + inSecurityBufferDescriptor.pBuffers = inUnmanagedBufferPtr; + pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.cBuffers]; SecurityBuffer securityBuffer; - for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index) + for (int index = 0; index < inSecurityBufferDescriptor.cBuffers; ++index) { securityBuffer = inSecBuffers[index]; if (securityBuffer != null) { - inUnmanagedBuffer[index].count = securityBuffer.size; - inUnmanagedBuffer[index].type = securityBuffer.type; + inUnmanagedBuffer[index].cbBuffer = securityBuffer.size; + inUnmanagedBuffer[index].BufferType = securityBuffer.type; // Use the unmanaged token if it's not null; otherwise use the managed buffer. if (securityBuffer.unmanagedToken != null) { - inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle(); + inUnmanagedBuffer[index].pvBuffer = securityBuffer.unmanagedToken.DangerousGetHandle(); } else if (securityBuffer.token == null || securityBuffer.token.Length == 0) { - inUnmanagedBuffer[index].token = IntPtr.Zero; + inUnmanagedBuffer[index].pvBuffer = IntPtr.Zero; } else { pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); - inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); + inUnmanagedBuffer[index].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); } #if TRACE_VERBOSE if (GlobalLog.IsEnabled) @@ -1196,7 +1196,7 @@ internal unsafe static int CompleteAuthToken( } } - Interop.SspiCli.SSPIHandle contextHandle = new Interop.SspiCli.SSPIHandle(); + Interop.SspiCli.CredHandle contextHandle = new Interop.SspiCli.CredHandle(); if (refContext != null) { contextHandle = refContext._handle; @@ -1241,6 +1241,123 @@ internal unsafe static int CompleteAuthToken( return errorCode; } + + internal unsafe static int ApplyControlToken( + ref SafeDeleteContext refContext, + SecurityBuffer[] inSecBuffers) + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Enter("SafeDeleteContext::ApplyControlToken"); + GlobalLog.Print(" refContext = " + LoggingHash.ObjectToString(refContext)); +#if TRACE_VERBOSE + GlobalLog.Print(" inSecBuffers[] = length:" + inSecBuffers.Length); +#endif + } + + if (inSecBuffers == null) + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Assert("SafeDeleteContext::ApplyControlToken()|inSecBuffers == null"); + } + + Debug.Fail("SafeDeleteContext::ApplyControlToken()|inSecBuffers == null"); + } + + var inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Length); + + int errorCode = (int)Interop.SECURITY_STATUS.InvalidHandle; + + // These are pinned user byte arrays passed along with SecurityBuffers. + GCHandle[] pinnedInBytes = null; + + var inUnmanagedBuffer = new Interop.SspiCli.SecBuffer[inSecurityBufferDescriptor.cBuffers]; + fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer) + { + // Fix Descriptor pointer that points to unmanaged SecurityBuffers. + inSecurityBufferDescriptor.pBuffers = inUnmanagedBufferPtr; + pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.cBuffers]; + SecurityBuffer securityBuffer; + for (int index = 0; index < inSecurityBufferDescriptor.cBuffers; ++index) + { + securityBuffer = inSecBuffers[index]; + if (securityBuffer != null) + { + inUnmanagedBuffer[index].cbBuffer = securityBuffer.size; + inUnmanagedBuffer[index].BufferType = securityBuffer.type; + + // Use the unmanaged token if it's not null; otherwise use the managed buffer. + if (securityBuffer.unmanagedToken != null) + { + inUnmanagedBuffer[index].pvBuffer = securityBuffer.unmanagedToken.DangerousGetHandle(); + } + else if (securityBuffer.token == null || securityBuffer.token.Length == 0) + { + inUnmanagedBuffer[index].pvBuffer = IntPtr.Zero; + } + else + { + pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned); + inUnmanagedBuffer[index].pvBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset); + } +#if TRACE_VERBOSE + if (GlobalLog.IsEnabled) + { + GlobalLog.Print("SecBuffer: cbBuffer:" + securityBuffer.size + " BufferType:" + securityBuffer.type); + } +#endif + } + } + + // TODO: (#3114): Optimizations to remove the unnecesary allocation of a CredHandle, remove the AddRef + // if refContext was previously null, refactor the code to unify CompleteAuthToken and ApplyControlToken. + Interop.SspiCli.CredHandle contextHandle = new Interop.SspiCli.CredHandle(); + if (refContext != null) + { + contextHandle = refContext._handle; + } + + try + { + if (refContext == null || refContext.IsInvalid) + { + refContext = new SafeDeleteContext_SECURITY(); + } + + try + { + bool ignore = false; + refContext.DangerousAddRef(ref ignore); + errorCode = Interop.SspiCli.ApplyControlToken(contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor); + } + finally + { + refContext.DangerousRelease(); + } + } + finally + { + if (pinnedInBytes != null) + { + for (int index = 0; index < pinnedInBytes.Length; index++) + { + if (pinnedInBytes[index].IsAllocated) + { + pinnedInBytes[index].Free(); + } + } + } + } + } + + if (GlobalLog.IsEnabled) + { + GlobalLog.Leave("SafeDeleteContext::ApplyControlToken() unmanaged ApplyControlToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + LoggingHash.ObjectToString(refContext)); + } + + return errorCode; + } } internal sealed class SafeDeleteContext_SECURITY : SafeDeleteContext @@ -1283,19 +1400,19 @@ internal static SafeFreeContextBufferChannelBinding CreateEmptyHandle() return new SafeFreeContextBufferChannelBinding_SECURITY(); } - public unsafe static int QueryContextChannelBinding(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute contextAttribute, Bindings* buffer, SafeFreeContextBufferChannelBinding refHandle) + public unsafe static int QueryContextChannelBinding(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute contextAttribute, SecPkgContext_Bindings* buffer, SafeFreeContextBufferChannelBinding refHandle) { return QueryContextChannelBinding_SECURITY(phContext, contextAttribute, buffer, refHandle); } - private unsafe static int QueryContextChannelBinding_SECURITY(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute contextAttribute, Bindings* buffer, SafeFreeContextBufferChannelBinding refHandle) + private unsafe static int QueryContextChannelBinding_SECURITY(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute contextAttribute, SecPkgContext_Bindings* buffer, SafeFreeContextBufferChannelBinding refHandle) { - int status = (int)Interop.SecurityStatus.InvalidHandle; + int status = (int)Interop.SECURITY_STATUS.InvalidHandle; // SCHANNEL only supports SECPKG_ATTR_ENDPOINT_BINDINGS and SECPKG_ATTR_UNIQUE_BINDINGS which // map to our enum ChannelBindingKind.Endpoint and ChannelBindingKind.Unique. - if (contextAttribute != Interop.SspiCli.ContextAttribute.EndpointBindings && - contextAttribute != Interop.SspiCli.ContextAttribute.UniqueBindings) + if (contextAttribute != Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ENDPOINT_BINDINGS && + contextAttribute != Interop.SspiCli.ContextAttribute.SECPKG_ATTR_UNIQUE_BINDINGS) { return status; } @@ -1313,7 +1430,7 @@ private unsafe static int QueryContextChannelBinding_SECURITY(SafeDeleteContext if (status == 0 && refHandle != null) { - refHandle.Set((*buffer).pBindings); + refHandle.Set((*buffer).Bindings); refHandle._size = (*buffer).BindingsLength; } diff --git a/src/Common/src/System/Net/Logging/SecurityEventSource.Windows.cs b/src/Common/src/System/Net/Logging/SecurityEventSource.Windows.cs index 0514ef55d4f7..5109590a5839 100644 --- a/src/Common/src/System/Net/Logging/SecurityEventSource.Windows.cs +++ b/src/Common/src/System/Net/Logging/SecurityEventSource.Windows.cs @@ -119,7 +119,7 @@ internal unsafe void AcceptSecurityContext(string credential, string context, In [Event(OperationReturnedSomethingId, Keywords = Keywords.Default, Level = EventLevel.Informational)] - internal void OperationReturnedSomething(string operation, Interop.SecurityStatus errorCode) + internal void OperationReturnedSomething(string operation, Interop.SECURITY_STATUS errorCode) { if (!s_log.IsEnabled()) { @@ -131,7 +131,7 @@ internal void OperationReturnedSomething(string operation, Interop.SecurityStatu [Event(SecurityContextInputBufferId, Keywords = Keywords.Default, Level = EventLevel.Informational)] - internal unsafe void SecurityContextInputBuffer(string context, int inputBufferSize, int outputBufferSize, Interop.SecurityStatus errorCode) + internal unsafe void SecurityContextInputBuffer(string context, int inputBufferSize, int outputBufferSize, Interop.SECURITY_STATUS errorCode) { if (!s_log.IsEnabled()) { @@ -157,7 +157,7 @@ internal unsafe void SecurityContextInputBuffer(string context, int inputBufferS [Event(SecurityContextInputBuffersId, Keywords = Keywords.Default, Level = EventLevel.Informational)] - internal unsafe void SecurityContextInputBuffers(string context, int inputBuffersSize, int outputBufferSize, Interop.SecurityStatus errorCode) + internal unsafe void SecurityContextInputBuffers(string context, int inputBuffersSize, int outputBufferSize, Interop.SECURITY_STATUS errorCode) { if (!s_log.IsEnabled()) { diff --git a/src/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs b/src/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs index c0497b0c22ce..9886da3fd1c9 100644 --- a/src/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs +++ b/src/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs @@ -68,7 +68,7 @@ public override long Position public override void Flush() { - throw new NotImplementedException(); + // No-op. } public override void SetLength(long value) diff --git a/src/System.Net.Security/System.Net.Security.sln b/src/System.Net.Security/System.Net.Security.sln index 0014ca89865f..cdac7bef715d 100644 --- a/src/System.Net.Security/System.Net.Security.sln +++ b/src/System.Net.Security/System.Net.Security.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{1B8F56A7-863B-4E11-A882-D83EEA79C997}" EndProject diff --git a/src/System.Net.Security/pkg/System.Net.Security.pkgproj b/src/System.Net.Security/pkg/System.Net.Security.pkgproj index ee85852bf1ea..435fbfa0e5af 100644 --- a/src/System.Net.Security/pkg/System.Net.Security.pkgproj +++ b/src/System.Net.Security/pkg/System.Net.Security.pkgproj @@ -3,7 +3,7 @@ - net46;netcoreapp1.0;$(AllXamarinFrameworks) + net463;netcoreapp1.1;$(AllXamarinFrameworks) diff --git a/src/System.Net.Security/ref/System.Net.Security.cs b/src/System.Net.Security/ref/System.Net.Security.cs index d7fdc25dafc6..aef648358f78 100644 --- a/src/System.Net.Security/ref/System.Net.Security.cs +++ b/src/System.Net.Security/ref/System.Net.Security.cs @@ -133,6 +133,9 @@ public override void Flush() { } public override int Read(byte[] buffer, int offset, int count) { throw null; } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } public override void SetLength(long value) { } +#if netcoreapp11 + public virtual System.Threading.Tasks.Task ShutdownAsync() { return default(System.Threading.Tasks.Task); } +#endif public void Write(byte[] buffer) { } public override void Write(byte[] buffer, int offset, int count) { } } diff --git a/src/System.Net.Security/ref/System.Net.Security.csproj b/src/System.Net.Security/ref/System.Net.Security.csproj index 70051f527391..09b6ba9aa453 100644 --- a/src/System.Net.Security/ref/System.Net.Security.csproj +++ b/src/System.Net.Security/ref/System.Net.Security.csproj @@ -3,7 +3,7 @@ Library - .NETStandard,Version=v1.3 + .NETStandard,Version=v1.7 diff --git a/src/System.Net.Security/ref/project.json b/src/System.Net.Security/ref/project.json index 2a93773c4201..8a3ca1ad27ae 100644 --- a/src/System.Net.Security/ref/project.json +++ b/src/System.Net.Security/ref/project.json @@ -1,18 +1,14 @@ { "dependencies": { - "System.IO": "4.0.0", - "System.Net.Primitives": "4.0.10", - "System.Runtime": "4.0.0", - "System.Runtime.Handles": "4.0.0", - "System.Security.Cryptography.X509Certificates": "4.1.0", - "System.Security.Principal": "4.0.0", - "System.Threading.Tasks": "4.0.0" + "System.IO": "4.4.0-beta-24613-01", + "System.Net.Primitives": "4.4.0-beta-24613-01", + "System.Runtime": "4.4.0-beta-24613-01", + "System.Runtime.Handles": "4.4.0-beta-24613-01", + "System.Security.Cryptography.X509Certificates": "4.4.0-beta-24613-01", + "System.Security.Principal": "4.4.0-beta-24613-01", + "System.Threading.Tasks": "4.4.0-beta-24613-01" }, "frameworks": { - "netstandard1.3": { - "imports": [ - "dotnet5.4" - ] - } + "netstandard1.7": {} } } diff --git a/src/System.Net.Security/src/Resources/Strings.resx b/src/System.Net.Security/src/Resources/Strings.resx index 019a5b068b9b..435b394fb4a7 100644 --- a/src/System.Net.Security/src/Resources/Strings.resx +++ b/src/System.Net.Security/src/Resources/Strings.resx @@ -192,6 +192,9 @@ The server mode SSL must use a certificate with the associated private key. + + Write operations are not allowed after the channel was shutdown. + The server has rejected the client credentials. diff --git a/src/System.Net.Security/src/System.Net.Security.builds b/src/System.Net.Security/src/System.Net.Security.builds index 49b7cc531576..f7bc64f5d66f 100644 --- a/src/System.Net.Security/src/System.Net.Security.builds +++ b/src/System.Net.Security/src/System.Net.Security.builds @@ -9,9 +9,8 @@ Windows_NT - net46 + net463 - diff --git a/src/System.Net.Security/src/System.Net.Security.csproj b/src/System.Net.Security/src/System.Net.Security.csproj index a0d53c0de16a..d2d593db57d1 100644 --- a/src/System.Net.Security/src/System.Net.Security.csproj +++ b/src/System.Net.Security/src/System.Net.Security.csproj @@ -9,10 +9,9 @@ {89F37791-6254-4D60-AB96-ACD3CCA0E771} true $(DefineConstants);FEATURE_CORECLR - true - None - .NETStandard,Version=v1.3 - .NETStandard,Version=v1.6 + true + None + .NETStandard,Version=v1.7 win/project.json @@ -27,33 +26,38 @@ - - - + + + - - - + + - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + @@ -108,9 +112,6 @@ Common\System\Net\LazyAsyncResult.cs - - Common\System\Net\Shims\DBNull.cs - Common\System\Net\UriScheme.cs @@ -127,9 +128,6 @@ Common\System\NotImplemented.cs - - Common\Microsoft\Win32\SafeHandles\SafeHandleZeroOrMinusOneIsInvalid.cs - Common\System\IO\StreamApmExtensions.cs @@ -140,14 +138,16 @@ Common\System\IO\Error.cs - - - + + + + + - + Common\Interop\Windows\Interop.Libraries.cs @@ -164,20 +164,23 @@ Common\Interop\Windows\mincore\Interop.CloseHandle.cs + + Common\Interop\Windows\SChannel\Interop.Alerts.cs + Common\Interop\Windows\SChannel\Interop.SchProtocols.cs - - Common\Interop\Windows\SChannel\Interop.SecurityStatus.cs + + Common\Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs - - Common\Interop\Windows\SChannel\SslConnectionInfo.cs + + Common\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs Common\Interop\Windows\SChannel\UnmanagedCertificateContext.cs - - Common\Interop\Windows\sspicli\Bindings.cs + + Common\Interop\Windows\sspicli\SecPkgContext_Bindings.cs Common\Interop\Windows\sspicli\GlobalSSPI.cs @@ -185,14 +188,14 @@ Common\Interop\Windows\sspicli\Interop.SSPI.cs - - Common\Interop\Windows\sspicli\NegotiationInfo.cs + + Common\Interop\Windows\sspicli\SecPkgContext_NegotiationInfoW.cs Common\Interop\Windows\sspicli\NegotiationInfoClass.cs - - Common\Interop\Windows\sspicli\SecSizes.cs + + Common\Interop\Windows\sspicli\SecPkgContext_Sizes.cs Common\System\Collections\Generic\BidirectionalDictionary.cs @@ -221,22 +224,24 @@ Common\Interop\Windows\sspicli\SSPIWrapper.cs - - Common\Interop\Windows\sspicli\StreamSizes.cs + + Common\Interop\Windows\sspicli\SecPkgContext_StreamSizes.cs Common\System\Net\ContextAwareResult.Windows.cs - + + + Common\System\Net\Security\CertificateValidation.Unix.cs - + Common\Interop\Unix\Interop.Libraries.cs @@ -292,12 +297,6 @@ Common\Interop\Unix\System.Security.Cryptography.Native\Interop.X509StoreCtx.cs - - Common\Interop\Unix\System.Security.Cryptography.Native\SslConnectionInfo.cs - - - Common\Interop\Unix\System.Security.Cryptography.Native\StreamSizes.cs - Common\Interop\Unix\System.Net.Security.Native\Interop.Initialization.cs @@ -359,7 +358,7 @@ Common\System\Net\Security\Unix\SafeFreeSslCredentials.cs - + diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/BufferAsyncResult.cs b/src/System.Net.Security/src/System/Net/BufferAsyncResult.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/BufferAsyncResult.cs rename to src/System.Net.Security/src/System/Net/BufferAsyncResult.cs diff --git a/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs b/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs index 7d05ff49e036..3543a4fa9da4 100644 --- a/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs +++ b/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs @@ -104,7 +104,7 @@ internal static X509Certificate2 GetRemoteCertificate(SafeDeleteContext security SafeFreeCertContext remoteContext = null; try { - remoteContext = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, securityContext, Interop.SspiCli.ContextAttribute.RemoteCertificate) as SafeFreeCertContext; + remoteContext = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPISecureChannel, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT) as SafeFreeCertContext; if (remoteContext != null && !remoteContext.IsInvalid) { result = new X509Certificate2(remoteContext.DangerousGetHandle()); @@ -138,11 +138,11 @@ internal static X509Certificate2 GetRemoteCertificate(SafeDeleteContext security // internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext) { - Interop.SspiCli.IssuerListInfoEx issuerList = - (Interop.SspiCli.IssuerListInfoEx)SSPIWrapper.QueryContextAttributes( + Interop.SspiCli.SecPkgContext_IssuerListInfoEx issuerList = + (Interop.SspiCli.SecPkgContext_IssuerListInfoEx)SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, securityContext, - Interop.SspiCli.ContextAttribute.IssuerListInfoEx); + Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX); string[] issuers = Array.Empty(); @@ -154,10 +154,10 @@ internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext secu { uint count = issuerList.cIssuers; issuers = new string[issuerList.cIssuers]; - Interop.SspiCli._CERT_CHAIN_ELEMENT* pIL = (Interop.SspiCli._CERT_CHAIN_ELEMENT*)issuerList.aIssuers.DangerousGetHandle(); + Interop.SspiCli.CERT_CHAIN_ELEMENT* pIL = (Interop.SspiCli.CERT_CHAIN_ELEMENT*)issuerList.aIssuers.DangerousGetHandle(); for (int i = 0; i < count; ++i) { - Interop.SspiCli._CERT_CHAIN_ELEMENT* pIL2 = pIL + i; + Interop.SspiCli.CERT_CHAIN_ELEMENT* pIL2 = pIL + i; if (pIL2->cbSize <= 0) { if (GlobalLog.IsEnabled) diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/FixedSizeReader.cs b/src/System.Net.Security/src/System/Net/FixedSizeReader.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/FixedSizeReader.cs rename to src/System.Net.Security/src/System/Net/FixedSizeReader.cs diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/HelperAsyncResults.cs b/src/System.Net.Security/src/System/Net/HelperAsyncResults.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/HelperAsyncResults.cs rename to src/System.Net.Security/src/System/Net/HelperAsyncResults.cs diff --git a/src/System.Net.Security/src/System/Net/NTAuthentication.cs b/src/System.Net.Security/src/System/Net/NTAuthentication.cs index 46d969f4092d..b4269f1b1b7a 100644 --- a/src/System.Net.Security/src/System/Net/NTAuthentication.cs +++ b/src/System.Net.Security/src/System/Net/NTAuthentication.cs @@ -319,7 +319,7 @@ internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out Secu if (incomingBlob != null) { - list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.Token)); + list.Add(new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN)); } if (_channelBinding != null) @@ -333,7 +333,7 @@ internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out Secu inSecurityBufferArray = list.ToArray(); } - var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.Token); + var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.SECBUFFER_TOKEN); bool firstTime = _securityContext == null; try diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/AuthenticatedStream.cs b/src/System.Net.Security/src/System/Net/Security/AuthenticatedStream.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/AuthenticatedStream.cs rename to src/System.Net.Security/src/System/Net/Security/AuthenticatedStream.cs diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/InternalNegotiateStream.cs b/src/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/InternalNegotiateStream.cs rename to src/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/NegoState.cs b/src/System.Net.Security/src/System/Net/Security/NegoState.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/NegoState.cs rename to src/System.Net.Security/src/System/Net/Security/NegoState.cs diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/NegotiateStream.cs b/src/System.Net.Security/src/System/Net/Security/NegotiateStream.cs similarity index 98% rename from src/System.Net.Security/src/System/Net/SecureProtocols/NegotiateStream.cs rename to src/System.Net.Security/src/System/Net/Security/NegotiateStream.cs index d20bb6b5dd0e..1eb156224ebc 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/NegotiateStream.cs +++ b/src/System.Net.Security/src/System/Net/Security/NegotiateStream.cs @@ -532,7 +532,7 @@ public override void Write(byte[] buffer, int offset, int count) #endif } - private IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) @@ -554,7 +554,7 @@ private IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallba #endif } - private int EndRead(IAsyncResult asyncResult) + public override int EndRead(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) @@ -604,7 +604,7 @@ private int EndRead(IAsyncResult asyncResult) } // // - private IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) @@ -627,7 +627,7 @@ private IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallb #endif } - private void EndWrite(IAsyncResult asyncResult) + public override void EndWrite(IAsyncResult asyncResult) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User)) diff --git a/src/System.Net.Security/src/System/Net/NegotiateStreamPal.Unix.cs b/src/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Unix.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/NegotiateStreamPal.Unix.cs rename to src/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Unix.cs diff --git a/src/System.Net.Security/src/System/Net/NegotiateStreamPal.Windows.cs b/src/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs similarity index 87% rename from src/System.Net.Security/src/System/Net/NegotiateStreamPal.Windows.cs rename to src/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs index 9bb02f6e66dc..04f69382f6c1 100644 --- a/src/System.Net.Security/src/System/Net/NegotiateStreamPal.Windows.cs +++ b/src/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs @@ -42,11 +42,11 @@ internal static IIdentity GetIdentity(NTAuthentication context) // This will return a client token when conducted authentication on server side. // This token can be used for impersonation. We use it to create a WindowsIdentity and hand it out to the server app. - Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.QuerySecurityContextToken( + Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.QuerySecurityContextToken( GlobalSSPI.SSPIAuth, securityContext, out token); - if (winStatus != Interop.SecurityStatus.OK) + if (winStatus != Interop.SECURITY_STATUS.OK) { throw new Win32Exception((int)winStatus); } @@ -78,12 +78,12 @@ internal static IIdentity GetIdentity(NTAuthentication context) internal static string QueryContextAssociatedName(SafeDeleteContext securityContext) { - return SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.Names) as string; + return SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES) as string; } internal static string QueryContextAuthenticationPackage(SafeDeleteContext securityContext) { - var negotiationInfoClass = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.NegotiationInfo) as NegotiationInfoClass; + var negotiationInfoClass = SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO) as NegotiationInfoClass; return negotiationInfoClass?.AuthenticationPackage; } @@ -94,7 +94,7 @@ internal static int QueryMaxTokenSize(string package) internal static string QueryContextClientSpecifiedSpn(SafeDeleteContext securityContext) { - return SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.ClientSpecifiedSpn) as string; + return SSPIWrapper.QueryContextAttributes(GlobalSSPI.SSPIAuth, securityContext, Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET) as string; } internal static SafeFreeCredentials AcquireDefaultCredential(string package, bool isServer) @@ -102,7 +102,7 @@ internal static SafeFreeCredentials AcquireDefaultCredential(string package, boo return SSPIWrapper.AcquireDefaultCredential( GlobalSSPI.SSPIAuth, package, - (isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound)); + (isServer ? Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND : Interop.SspiCli.CredentialUse.SECPKG_CRED_OUTBOUND)); } internal unsafe static SafeFreeCredentials AcquireCredentialsHandle(string package, bool isServer, NetworkCredential credential) @@ -110,11 +110,11 @@ internal unsafe static SafeFreeCredentials AcquireCredentialsHandle(string packa SafeSspiAuthDataHandle authData = null; try { - Interop.SecurityStatus result = Interop.SspiCli.SspiEncodeStringsAsAuthIdentity( + Interop.SECURITY_STATUS result = Interop.SspiCli.SspiEncodeStringsAsAuthIdentity( credential.UserName, credential.Domain, credential.Password, out authData); - if (result != Interop.SecurityStatus.OK) + if (result != Interop.SECURITY_STATUS.OK) { if (NetEventSource.Log.IsEnabled()) { @@ -130,7 +130,7 @@ internal unsafe static SafeFreeCredentials AcquireCredentialsHandle(string packa } return SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPIAuth, - package, (isServer ? Interop.SspiCli.CredentialUse.Inbound : Interop.SspiCli.CredentialUse.Outbound), ref authData); + package, (isServer ? Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND : Interop.SspiCli.CredentialUse.SECPKG_CRED_OUTBOUND), ref authData); } finally { @@ -151,13 +151,13 @@ internal static SecurityStatusPal InitializeSecurityContext( ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; - Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.InitializeSecurityContext( + Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, spn, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), - Interop.SspiCli.Endianness.Network, + Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); @@ -170,7 +170,7 @@ internal static SecurityStatusPal CompleteAuthToken( ref SafeDeleteContext securityContext, SecurityBuffer[] inSecurityBufferArray) { - Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.CompleteAuthToken( + Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.CompleteAuthToken( GlobalSSPI.SSPIAuth, ref securityContext, inSecurityBufferArray); @@ -186,12 +186,12 @@ internal static SecurityStatusPal AcceptSecurityContext( ref ContextFlagsPal contextFlags) { Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero; - Interop.SecurityStatus winStatus = (Interop.SecurityStatus)SSPIWrapper.AcceptSecurityContext( + Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, credentialsHandle, ref securityContext, ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags), - Interop.SspiCli.Endianness.Network, + Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP, inSecurityBufferArray, outSecurityBuffer, ref outContextFlags); @@ -225,15 +225,15 @@ internal static int Encrypt( ref byte[] output, uint sequenceNumber) { - SecSizes sizes = SSPIWrapper.QueryContextAttributes( + SecPkgContext_Sizes sizes = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPIAuth, securityContext, - Interop.SspiCli.ContextAttribute.Sizes - ) as SecSizes; + Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES + ) as SecPkgContext_Sizes; try { - int maxCount = checked(Int32.MaxValue - 4 - sizes.BlockSize - sizes.SecurityTrailer); + int maxCount = checked(Int32.MaxValue - 4 - sizes.cbBlockSize - sizes.cbSecurityTrailer); if (count > maxCount || count < 0) { @@ -255,20 +255,20 @@ internal static int Encrypt( throw; } - int resultSize = count + sizes.SecurityTrailer + sizes.BlockSize; + int resultSize = count + sizes.cbSecurityTrailer + sizes.cbBlockSize; if (output == null || output.Length < resultSize + 4) { output = new byte[resultSize + 4]; } // Make a copy of user data for in-place encryption. - Buffer.BlockCopy(buffer, offset, output, 4 + sizes.SecurityTrailer, count); + Buffer.BlockCopy(buffer, offset, output, 4 + sizes.cbSecurityTrailer, count); // Prepare buffers TOKEN(signature), DATA and Padding. var securityBuffer = new SecurityBuffer[3]; - securityBuffer[0] = new SecurityBuffer(output, 4, sizes.SecurityTrailer, SecurityBufferType.Token); - securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer, count, SecurityBufferType.Data); - securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.SecurityTrailer + count, sizes.BlockSize, SecurityBufferType.Padding); + securityBuffer[0] = new SecurityBuffer(output, 4, sizes.cbSecurityTrailer, SecurityBufferType.SECBUFFER_TOKEN); + securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer, count, SecurityBufferType.SECBUFFER_DATA); + securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer + count, sizes.cbBlockSize, SecurityBufferType.SECBUFFER_PADDING); int errorCode; if (isConfidential) @@ -279,7 +279,7 @@ internal static int Encrypt( { if (isNtlm) { - securityBuffer[1].type |= SecurityBufferType.ReadOnlyFlag; + securityBuffer[1].type |= SecurityBufferType.SECBUFFER_READONLY; } errorCode = SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, 0); @@ -297,14 +297,14 @@ internal static int Encrypt( // Compacting the result. resultSize = securityBuffer[0].size; bool forceCopy = false; - if (resultSize != sizes.SecurityTrailer) + if (resultSize != sizes.cbSecurityTrailer) { forceCopy = true; Buffer.BlockCopy(output, securityBuffer[1].offset, output, 4 + resultSize, securityBuffer[1].size); } resultSize += securityBuffer[1].size; - if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.SecurityTrailer))) + if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.cbSecurityTrailer))) { Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size); } @@ -364,8 +364,8 @@ internal static int Decrypt( // Kerberos and up // var securityBuffer = new SecurityBuffer[2]; - securityBuffer[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.Stream); - securityBuffer[1] = new SecurityBuffer(0, SecurityBufferType.Data); + securityBuffer[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.SECBUFFER_STREAM); + securityBuffer[1] = new SecurityBuffer(0, SecurityBufferType.SECBUFFER_DATA); int errorCode; if (isConfidential) @@ -386,7 +386,7 @@ internal static int Decrypt( throw new Win32Exception(errorCode); } - if (securityBuffer[1].type != SecurityBufferType.Data) + if (securityBuffer[1].type != SecurityBufferType.SECBUFFER_DATA) { throw new InternalException(); } @@ -419,11 +419,11 @@ private static int DecryptNtlm( } var securityBuffer = new SecurityBuffer[2]; - securityBuffer[0] = new SecurityBuffer(buffer, offset, ntlmSignatureLength, SecurityBufferType.Token); - securityBuffer[1] = new SecurityBuffer(buffer, offset + ntlmSignatureLength, count - ntlmSignatureLength, SecurityBufferType.Data); + securityBuffer[0] = new SecurityBuffer(buffer, offset, ntlmSignatureLength, SecurityBufferType.SECBUFFER_TOKEN); + securityBuffer[1] = new SecurityBuffer(buffer, offset + ntlmSignatureLength, count - ntlmSignatureLength, SecurityBufferType.SECBUFFER_DATA); int errorCode; - SecurityBufferType realDataType = SecurityBufferType.Data; + SecurityBufferType realDataType = SecurityBufferType.SECBUFFER_DATA; if (isConfidential) { @@ -431,7 +431,7 @@ private static int DecryptNtlm( } else { - realDataType |= SecurityBufferType.ReadOnlyFlag; + realDataType |= SecurityBufferType.SECBUFFER_READONLY; securityBuffer[1].type = realDataType; errorCode = SSPIWrapper.VerifySignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/ProtectionLevel.cs b/src/System.Net.Security/src/System/Net/Security/ProtectionLevel.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/ProtectionLevel.cs rename to src/System.Net.Security/src/System/Net/Security/ProtectionLevel.cs diff --git a/src/System.Net.Security/src/System/Net/SSPIHandleCache.cs b/src/System.Net.Security/src/System/Net/Security/SSPIHandleCache.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SSPIHandleCache.cs rename to src/System.Net.Security/src/System/Net/Security/SSPIHandleCache.cs diff --git a/src/System.Net.Security/src/System/Net/SecureChannel.cs b/src/System.Net.Security/src/System/Net/Security/SecureChannel.cs similarity index 86% rename from src/System.Net.Security/src/System/Net/SecureChannel.cs rename to src/System.Net.Security/src/System/Net/Security/SecureChannel.cs index 8bc31021f033..1122c2645a27 100644 --- a/src/System.Net.Security/src/System/Net/SecureChannel.cs +++ b/src/System.Net.Security/src/System/Net/Security/SecureChannel.cs @@ -47,7 +47,6 @@ internal class SecureChannel private bool _refreshCredentialNeeded; - internal SecureChannel(string hostname, bool serverMode, SslProtocols sslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, LocalCertSelectionCallback certSelectionDelegate) { @@ -87,6 +86,7 @@ internal SecureChannel(string hostname, bool serverMode, SslProtocols sslProtoco _certSelectionDelegate = certSelectionDelegate; _refreshCredentialNeeded = true; _encryptionPolicy = encryptionPolicy; + if (GlobalLog.IsEnabled) { GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::.ctor"); @@ -872,15 +872,15 @@ private SecurityStatusPal GenerateToken(byte[] input, int offset, int count, ref if (input != null) { - incomingSecurity = new SecurityBuffer(input, offset, count, SecurityBufferType.Token); + incomingSecurity = new SecurityBuffer(input, offset, count, SecurityBufferType.SECBUFFER_TOKEN); incomingSecurityBuffers = new SecurityBuffer[] { incomingSecurity, - new SecurityBuffer(null, 0, 0, SecurityBufferType.Empty) + new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY) }; } - SecurityBuffer outgoingSecurity = new SecurityBuffer(null, SecurityBufferType.Token); + SecurityBuffer outgoingSecurity = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_TOKEN); SecurityStatusPal status = default(SecurityStatusPal); @@ -993,9 +993,9 @@ internal void ProcessHandshakeSuccess() { try { - _headerSize = streamSizes.header; - _trailerSize = streamSizes.trailer; - _maxDataSize = checked(streamSizes.maximumMessage - (_headerSize + _trailerSize)); + _headerSize = streamSizes.Header; + _trailerSize = streamSizes.Trailer; + _maxDataSize = checked(streamSizes.MaximumMessage - (_headerSize + _trailerSize)); } catch (Exception e) { @@ -1148,7 +1148,7 @@ internal SecurityStatusPal Decrypt(byte[] payload, ref int offset, ref int count //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build // A user callback has unique signature so it is safe to call it under permission assert. // - internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback) + internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback, ref ProtocolToken alertToken) { if (GlobalLog.IsEnabled) { @@ -1212,53 +1212,18 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertVal if (SecurityEventSource.Log.IsEnabled()) { - if (sslPolicyErrors != SslPolicyErrors.None) - { - SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_has_errors); - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) - { - SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_not_available); - } - - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) - { - SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_name_mismatch); - } - - if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) - { - string chainStatusString = "ChainStatus: "; - foreach (X509ChainStatus chainStatus in chain.ChainStatus) - { - chainStatusString += "\t" + chainStatus.StatusInformation; - } - SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), chainStatusString); - } - } - if (success) - { - if (remoteCertValidationCallback != null) - { - SecurityEventSource.Log.RemoteCertDeclaredValid(LoggingHash.HashInt(this)); - } - else - { - SecurityEventSource.Log.RemoteCertHasNoErrors(LoggingHash.HashInt(this)); - } - } - else - { - if (remoteCertValidationCallback != null) - { - SecurityEventSource.Log.RemoteCertUserDeclaredInvalid(LoggingHash.HashInt(this)); - } - } + LogCertificateValidation(remoteCertValidationCallback, sslPolicyErrors, success, chain); } if (GlobalLog.IsEnabled) { GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "" : remoteCertificateEx.ToString(true))); } + + if (!success) + { + alertToken = CreateFatalHandshakeAlertToken(sslPolicyErrors, chain); + } } finally { @@ -1279,8 +1244,208 @@ internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertVal { GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate", success.ToString()); } + return success; } + + public ProtocolToken CreateFatalHandshakeAlertToken(SslPolicyErrors sslPolicyErrors, X509Chain chain) + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Enter("SecureChannel#" + LoggingHash.HashString(this) + "::CreateFatalHandshakeAlertToken"); + } + + TlsAlertMessage alertMessage; + + switch (sslPolicyErrors) + { + case SslPolicyErrors.RemoteCertificateChainErrors: + alertMessage = GetAlertMessageFromChain(chain); + break; + case SslPolicyErrors.RemoteCertificateNameMismatch: + alertMessage = TlsAlertMessage.BadCertificate; + break; + case SslPolicyErrors.RemoteCertificateNotAvailable: + default: + alertMessage = TlsAlertMessage.CertificateUnknown; + break; + } + + if (GlobalLog.IsEnabled) + { + GlobalLog.Print("SecureChannel#" + LoggingHash.HashString(this) + "::CreateFatalHandshakeAlertToken() alertMessage: " + alertMessage.ToString()); + } + + SecurityStatusPal status; + status = SslStreamPal.ApplyAlertToken(ref _credentialsHandle, _securityContext, TlsAlertType.Fatal, alertMessage); + + if (status.ErrorCode != SecurityStatusPalErrorCode.OK) + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Print("SecureChannel#" + LoggingHash.HashString(this) + "::ApplyAlertToken() returned " + status.ErrorCode); + } + + if (status.Exception != null) + { + throw status.Exception; + } + + return null; + } + + ProtocolToken token = GenerateAlertToken(); + + if (GlobalLog.IsEnabled) + { + GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::CreateFatalHandshakeAlertToken", token.ToString()); + } + + return token; + } + + public ProtocolToken CreateShutdownToken() + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Enter("SecureChannel#" + LoggingHash.HashString(this) + "::CreateShutdownToken"); + } + + SecurityStatusPal status; + status = SslStreamPal.ApplyShutdownToken(ref _credentialsHandle, _securityContext); + + if (status.ErrorCode != SecurityStatusPalErrorCode.OK) + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Print("SecureChannel#" + LoggingHash.HashString(this) + "::ApplyAlertToken() returned " + status.ErrorCode); + } + + if (status.Exception != null) + { + throw status.Exception; + } + + return null; + } + + ProtocolToken token = GenerateAlertToken(); + + if (GlobalLog.IsEnabled) + { + GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::CreateShutdownToken", token.ToString()); + } + + return token; + } + + private ProtocolToken GenerateAlertToken() + { + byte[] nextmsg = null; + + SecurityStatusPal status; + status = GenerateToken(null, 0, 0, ref nextmsg); + + ProtocolToken token = new ProtocolToken(nextmsg, status); + + return token; + } + + private static TlsAlertMessage GetAlertMessageFromChain(X509Chain chain) + { + foreach (X509ChainStatus chainStatus in chain.ChainStatus) + { + if (chainStatus.Status == X509ChainStatusFlags.NoError) + { + continue; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.UntrustedRoot | X509ChainStatusFlags.PartialChain | + X509ChainStatusFlags.Cyclic)) != 0) + { + return TlsAlertMessage.UnknownCA; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.Revoked | X509ChainStatusFlags.OfflineRevocation )) != 0) + { + return TlsAlertMessage.CertificateRevoked; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.CtlNotTimeValid | X509ChainStatusFlags.NotTimeNested | + X509ChainStatusFlags.NotTimeValid)) != 0) + { + return TlsAlertMessage.CertificateExpired; + } + + if ((chainStatus.Status & X509ChainStatusFlags.CtlNotValidForUsage) != 0) + { + return TlsAlertMessage.UnsupportedCert; + } + + if ((chainStatus.Status & + (X509ChainStatusFlags.CtlNotSignatureValid | X509ChainStatusFlags.InvalidExtension | + X509ChainStatusFlags.NotSignatureValid | X509ChainStatusFlags.InvalidPolicyConstraints) | + X509ChainStatusFlags.NoIssuanceChainPolicy | X509ChainStatusFlags.NotValidForUsage) != 0) + { + return TlsAlertMessage.BadCertificate; + } + + // All other errors: + return TlsAlertMessage.CertificateUnknown; + } + + Debug.Fail("GetAlertMessageFromChain was called but none of the chain elements had errors."); + return TlsAlertMessage.BadCertificate; + } + + private void LogCertificateValidation(RemoteCertValidationCallback remoteCertValidationCallback, SslPolicyErrors sslPolicyErrors, bool success, X509Chain chain) + { + if (sslPolicyErrors != SslPolicyErrors.None) + { + SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_has_errors); + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) + { + SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_not_available); + } + + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) + { + SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_name_mismatch); + } + + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) + { + string chainStatusString = "ChainStatus: "; + foreach (X509ChainStatus chainStatus in chain.ChainStatus) + { + chainStatusString += "\t" + chainStatus.StatusInformation; + } + SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), chainStatusString); + } + } + + if (success) + { + if (remoteCertValidationCallback != null) + { + SecurityEventSource.Log.RemoteCertDeclaredValid(LoggingHash.HashInt(this)); + } + else + { + SecurityEventSource.Log.RemoteCertHasNoErrors(LoggingHash.HashInt(this)); + } + } + else + { + if (remoteCertValidationCallback != null) + { + SecurityEventSource.Log.RemoteCertUserDeclaredInvalid(LoggingHash.HashInt(this)); + } + } + } } // ProtocolToken - used to process and handle the return codes from the SSPI wrapper diff --git a/src/System.Net.Security/src/System/Net/SecurityBuffer.cs b/src/System.Net.Security/src/System/Net/Security/SecurityBuffer.cs similarity index 97% rename from src/System.Net.Security/src/System/Net/SecurityBuffer.cs rename to src/System.Net.Security/src/System/Net/Security/SecurityBuffer.cs index 0ace2dafe4d9..bfb185a9b6ba 100644 --- a/src/System.Net.Security/src/System/Net/SecurityBuffer.cs +++ b/src/System.Net.Security/src/System/Net/Security/SecurityBuffer.cs @@ -71,7 +71,7 @@ public SecurityBuffer(int size, SecurityBufferType tokentype) public SecurityBuffer(ChannelBinding binding) { this.size = (binding == null ? 0 : binding.Size); - this.type = SecurityBufferType.ChannelBindings; + this.type = SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS; this.unmanagedToken = binding; } } diff --git a/src/System.Net.Security/src/System/Net/Security/SecurityBufferType.cs b/src/System.Net.Security/src/System/Net/Security/SecurityBufferType.cs new file mode 100644 index 000000000000..a587cabbd72e --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/SecurityBufferType.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net.Security +{ + // sspi.h + internal enum SecurityBufferType + { + SECBUFFER_EMPTY = 0, + SECBUFFER_DATA = 1, + SECBUFFER_TOKEN = 2, + SECBUFFER_PKG_PARAMS = 3, + SECBUFFER_MISSING = 4, + SECBUFFER_EXTRA = 5, + SECBUFFER_STREAM_TRAILER = 6, + SECBUFFER_STREAM_HEADER = 7, + SECBUFFER_PADDING = 9, // non-data padding + SECBUFFER_STREAM = 10, + SECBUFFER_CHANNEL_BINDINGS = 14, + SECBUFFER_TARGET_HOST = 16, + SECBUFFER_ALERT = 17, + SECBUFFER_APPLICATION_PROTOCOLS = 18, + + SECBUFFER_READONLY = unchecked((int)0x80000000), + SECBUFFER_READONLY_WITH_CHECKSUM = 0x10000000 + } +} diff --git a/src/System.Net.Security/src/System/Net/SecurityContextTokenHandle.cs b/src/System.Net.Security/src/System/Net/Security/SecurityContextTokenHandle.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecurityContextTokenHandle.cs rename to src/System.Net.Security/src/System/Net/Security/SecurityContextTokenHandle.cs diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/SslConnectionInfo.cs b/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.Unix.cs similarity index 65% rename from src/Common/src/Interop/Unix/System.Security.Cryptography.Native/SslConnectionInfo.cs rename to src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.Unix.cs index 123a01025402..40f77b3b2dd2 100644 --- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/SslConnectionInfo.cs +++ b/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.Unix.cs @@ -2,50 +2,57 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Security.Authentication; using Microsoft.Win32.SafeHandles; +using System.Security.Authentication; -namespace System.Net +namespace System.Net.Security { - internal class SslConnectionInfo + internal partial class SslConnectionInfo { - public readonly int Protocol; - public readonly int DataCipherAlg; - public readonly int DataKeySize; - public readonly int DataHashAlg; - public readonly int DataHashKeySize; - public readonly int KeyExchangeAlg; - public readonly int KeyExchKeySize = 0; - - internal SslConnectionInfo(SafeSslHandle sslContext) + public SslConnectionInfo(SafeSslHandle sslContext) { string protocolVersion = Interop.Ssl.GetProtocolVersion(sslContext); Protocol = (int)MapProtocolVersion(protocolVersion); + int dataCipherAlg; + int keyExchangeAlg; + int dataHashAlg; + int dataKeySize; + int dataHashKeySize; + if (!Interop.Ssl.GetSslConnectionInfo( sslContext, - out DataCipherAlg, - out KeyExchangeAlg, - out DataHashAlg, - out DataKeySize, - out DataHashKeySize)) + out dataCipherAlg, + out keyExchangeAlg, + out dataHashAlg, + out dataKeySize, + out dataHashKeySize)) { throw Interop.OpenSsl.CreateSslException(SR.net_ssl_get_connection_info_failed); } + DataCipherAlg = dataCipherAlg; + KeyExchangeAlg = keyExchangeAlg; + DataHashAlg = dataHashAlg; + DataKeySize = dataKeySize; + DataHashKeySize = dataHashKeySize; + //Openssl does not provide a way to return a exchange key size. //It internally does calculate the key size before generating key to exchange //It is not a constant (Algorthim specific) either that we can hardcode and return. + KeyExchKeySize = 0; } private SslProtocols MapProtocolVersion(string protocolVersion) { switch (protocolVersion) { +#pragma warning disable 0618 // Ssl2, Ssl3 are deprecated. case "SSLv2": return SslProtocols.Ssl2; case "SSLv3": return SslProtocols.Ssl3; +#pragma warning restore case "TLSv1": return SslProtocols.Tls; case "TLSv1.1": diff --git a/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.Windows.cs b/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.Windows.cs new file mode 100644 index 000000000000..f701e97fb015 --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.Windows.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net.Security +{ + internal partial class SslConnectionInfo + { + public SslConnectionInfo(SecPkgContext_ConnectionInfo interopConnectionInfo) + { + Protocol = interopConnectionInfo.Protocol; + DataCipherAlg = interopConnectionInfo.DataCipherAlg; + DataKeySize = interopConnectionInfo.DataKeySize; + DataHashAlg = interopConnectionInfo.DataHashAlg; + DataHashKeySize = interopConnectionInfo.DataHashKeySize; + KeyExchangeAlg = interopConnectionInfo.KeyExchangeAlg; + KeyExchKeySize = interopConnectionInfo.KeyExchKeySize; + } + } +} diff --git a/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.cs b/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.cs new file mode 100644 index 000000000000..512199d6fcc0 --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/SslConnectionInfo.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net.Security +{ + internal partial class SslConnectionInfo + { + public int Protocol + { + get; + private set; + } + + public int DataCipherAlg + { + get; + private set; + } + + public int DataKeySize + { + get; + private set; + } + + public int DataHashAlg + { + get; + private set; + } + + public int DataHashKeySize + { + get; + private set; + } + + public int KeyExchangeAlg + { + get; + private set; + } + + public int KeyExchKeySize + { + get; + private set; + } + } +} diff --git a/src/System.Net.Security/src/System/Net/SslSessionsCache.cs b/src/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SslSessionsCache.cs rename to src/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs b/src/System.Net.Security/src/System/Net/Security/SslState.cs similarity index 97% rename from src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs rename to src/System.Net.Security/src/System/Net/Security/SslState.cs index 1ddebcda6d0d..5425a0b194e2 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs +++ b/src/System.Net.Security/src/System/Net/Security/SslState.cs @@ -35,6 +35,8 @@ internal class SslState private bool _handshakeCompleted; private bool _certValidationFailed; + private bool _shutdown; + private SecurityStatusPal _securityStatus; private ExceptionDispatchInfo _exception; @@ -236,6 +238,14 @@ internal bool IsCertValidationFailed } } + internal bool IsShutdown + { + get + { + return _shutdown; + } + } + internal bool DataAvailable { get @@ -346,6 +356,7 @@ internal SslProtocols SslProtocol SslProtocols proto = (SslProtocols)info.Protocol; SslProtocols ret = SslProtocols.None; +#pragma warning disable 0618 // Ssl2, Ssl3 are deprecated. // Restore client/server bits so the result maps exactly on published constants. if ((proto & SslProtocols.Ssl2) != 0) { @@ -356,6 +367,7 @@ internal SslProtocols SslProtocol { ret |= SslProtocols.Ssl3; } +#pragma warning restore if ((proto & SslProtocols.Tls) != 0) { @@ -447,17 +459,22 @@ private SecureChannel Context } } - internal void CheckThrow(bool authSucessCheck) + internal void CheckThrow(bool authSuccessCheck, bool shutdownCheck = false) { if (_exception != null) { _exception.Throw(); } - if (authSucessCheck && !IsAuthenticated) + if (authSuccessCheck && !IsAuthenticated) { throw new InvalidOperationException(SR.net_auth_noauth); } + + if (shutdownCheck && _shutdown) + { + throw new InvalidOperationException(SR.net_ssl_io_already_shutdown); + } } internal void Flush() @@ -800,9 +817,11 @@ private void CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtoc } else if (message.Done && !_pendingReHandshake) { - if (!CompleteHandshake()) + ProtocolToken alertToken = null; + + if (!CompleteHandshake(ref alertToken)) { - StartSendAuthResetSignal(null, asyncRequest, ExceptionDispatchInfo.Capture(new AuthenticationException(SR.net_ssl_io_cert_validation, null))); + StartSendAuthResetSignal(alertToken, asyncRequest, ExceptionDispatchInfo.Capture(new AuthenticationException(SR.net_ssl_io_cert_validation, null))); return; } @@ -951,6 +970,7 @@ private void ProcessReceivedBlob(byte[] buffer, int count, AsyncProtocolRequest Buffer.BlockCopy(buffer, offset, buffer, 0, count); } } + StartSendBlob(buffer, count, asyncRequest); } @@ -994,7 +1014,7 @@ private void StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolReques // // - Returns false if failed to verify the Remote Cert // - private bool CompleteHandshake() + private bool CompleteHandshake(ref ProtocolToken alertToken) { if (GlobalLog.IsEnabled) { @@ -1003,23 +1023,27 @@ private bool CompleteHandshake() Context.ProcessHandshakeSuccess(); - if (!Context.VerifyRemoteCertificate(_certValidationDelegate)) + if (!Context.VerifyRemoteCertificate(_certValidationDelegate, ref alertToken)) { _handshakeCompleted = false; _certValidationFailed = true; + if (GlobalLog.IsEnabled) { GlobalLog.Leave("CompleteHandshake", false); } + return false; } _certValidationFailed = false; _handshakeCompleted = true; + if (GlobalLog.IsEnabled) { GlobalLog.Leave("CompleteHandshake", true); } + return true; } @@ -1852,5 +1876,21 @@ private void RehandshakeCompleteCallback(IAsyncResult result) FinishHandshake(exception, null); } } + + internal IAsyncResult BeginShutdown(AsyncCallback asyncCallback, object asyncState) + { + CheckThrow(authSuccessCheck:true, shutdownCheck:true); + + ProtocolToken message = Context.CreateShutdownToken(); + return InnerStream.BeginWrite(message.Payload, 0, message.Payload.Length, asyncCallback, asyncState); + } + + internal void EndShutdown(IAsyncResult result) + { + CheckThrow(authSuccessCheck: true, shutdownCheck:true); + + InnerStream.EndWrite(result); + _shutdown = true; + } } } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs b/src/System.Net.Security/src/System/Net/Security/SslStream.cs similarity index 95% rename from src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs rename to src/System.Net.Security/src/System/Net/Security/SslStream.cs index 11229cbcd103..b4f2991492ee 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs +++ b/src/System.Net.Security/src/System/Net/Security/SslStream.cs @@ -154,6 +154,16 @@ public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) _sslState.EndProcessAuthentication(asyncResult); } + internal virtual IAsyncResult BeginShutdown(AsyncCallback asyncCallback, object asyncState) + { + return _sslState.BeginShutdown(asyncCallback, asyncState); + } + + internal virtual void EndShutdown(IAsyncResult asyncResult) + { + _sslState.EndShutdown(asyncResult); + } + public TransportContext TransportContext { get @@ -214,6 +224,14 @@ public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate, return Task.Factory.FromAsync((callback, state) => BeginAuthenticateAsServer(serverCertificate, clientCertificateRequired, enabledSslProtocols, checkCertificateRevocation, callback, state), EndAuthenticateAsServer, null); } + + public virtual Task ShutdownAsync() + { + return Task.Factory.FromAsync( + (callback, state) => BeginShutdown(callback, state), + EndShutdown, + null); + } #endregion public override bool IsAuthenticated @@ -377,7 +395,7 @@ public override bool CanWrite { get { - return _sslState.IsAuthenticated && InnerStream.CanWrite; + return _sslState.IsAuthenticated && InnerStream.CanWrite && !_sslState.IsShutdown; } } @@ -472,22 +490,22 @@ public override void Write(byte[] buffer, int offset, int count) _sslState.SecureStream.Write(buffer, offset, count); } - private IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { return _sslState.SecureStream.BeginRead(buffer, offset, count, asyncCallback, asyncState); } - private int EndRead(IAsyncResult asyncResult) + public override int EndRead(IAsyncResult asyncResult) { return _sslState.SecureStream.EndRead(asyncResult); } - private IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { return _sslState.SecureStream.BeginWrite(buffer, offset, count, asyncCallback, asyncState); } - private void EndWrite(IAsyncResult asyncResult) + public override void EndWrite(IAsyncResult asyncResult) { _sslState.SecureStream.EndWrite(asyncResult); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs b/src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs similarity index 99% rename from src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs rename to src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs index b87cc3ea4001..457fad64a574 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs +++ b/src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs @@ -324,6 +324,7 @@ private void ValidateParameters(byte[] buffer, int offset, int count) // private void ProcessWrite(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { + _sslState.CheckThrow(authSuccessCheck:true, shutdownCheck:true); ValidateParameters(buffer, offset, count); if (Interlocked.Exchange(ref _nestedWrite, 1) == 1) @@ -704,9 +705,6 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count return readBytes; } - // - // Only processing SEC_I_RENEGOTIATE. - // private int ProcessReadErrorCode(SecurityStatusPal status, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest, byte[] extraBuffer) { ProtocolToken message = new ProtocolToken(null, status); diff --git a/src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs b/src/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs similarity index 92% rename from src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs rename to src/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs index 2f5835010059..a98f7211502a 100644 --- a/src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs +++ b/src/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs @@ -10,7 +10,7 @@ using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace System.Net +namespace System.Net.Security { internal static class SslStreamPal { @@ -160,5 +160,17 @@ private static SecurityStatusPal EncryptDecryptHelper(SafeDeleteContext security return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex); } } + + public static SecurityStatusPal ApplyAlertToken(ref SafeFreeCredentials credentialsHandle, SafeDeleteContext securityContext, TlsAlertType alertType, TlsAlertMessage alertMessage) + { + // TODO (#12319): Not implemented. + return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); + } + + public static SecurityStatusPal ApplyShutdownToken(ref SafeFreeCredentials credentialsHandle, SafeDeleteContext securityContext) + { + // TODO (#12319): Not implemented. + return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); + } } } diff --git a/src/System.Net.Security/src/System/Net/SslStreamPal.Windows.cs b/src/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs similarity index 72% rename from src/System.Net.Security/src/System/Net/SslStreamPal.Windows.cs rename to src/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 3d8b61ade20e..c3be722b65b9 100644 --- a/src/System.Net.Security/src/System/Net/SslStreamPal.Windows.cs +++ b/src/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -6,12 +6,13 @@ using System.ComponentModel; using System.Diagnostics; using System.Net.Security; +using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Authentication.ExtendedProtection; using System.Security.Cryptography.X509Certificates; using System.Security.Principal; -namespace System.Net +namespace System.Net.Security { internal static class SslStreamPal { @@ -48,7 +49,7 @@ public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials cr ref credentialsHandle, ref context, ServerRequiredFlags | (remoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero), - Interop.SspiCli.Endianness.Native, + Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffer, outputBuffer, ref unusedAttributes); @@ -66,7 +67,7 @@ public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredential ref context, targetName, RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation, - Interop.SspiCli.Endianness.Native, + Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffer, outputBuffer, ref unusedAttributes); @@ -84,7 +85,7 @@ public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials cr ref context, targetName, RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation, - Interop.SspiCli.Endianness.Native, + Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffers, outputBuffer, ref unusedAttributes); @@ -95,32 +96,32 @@ public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials cr public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { int protocolFlags = GetProtocolFlagsFromSslProtocols(protocols, isServer); - Interop.SspiCli.SecureCredential.Flags flags; + Interop.SspiCli.SCHANNEL_CRED.Flags flags; Interop.SspiCli.CredentialUse direction; if (!isServer) { - direction = Interop.SspiCli.CredentialUse.Outbound; + direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_OUTBOUND; flags = - Interop.SspiCli.SecureCredential.Flags.ValidateManual | - Interop.SspiCli.SecureCredential.Flags.NoDefaultCred | - Interop.SspiCli.SecureCredential.Flags.SendAuxRecord; + Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_MANUAL_CRED_VALIDATION | + Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_NO_DEFAULT_CREDS | + Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_SEND_AUX_RECORD; // CoreFX: always opt-in SCH_USE_STRONG_CRYPTO except for SSL3. if (((protocolFlags & (Interop.SChannel.SP_PROT_TLS1_0 | Interop.SChannel.SP_PROT_TLS1_1 | Interop.SChannel.SP_PROT_TLS1_2)) != 0) && (policy != EncryptionPolicy.AllowNoEncryption) && (policy != EncryptionPolicy.NoEncryption)) { - flags |= Interop.SspiCli.SecureCredential.Flags.UseStrongCrypto; + flags |= Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_USE_STRONG_CRYPTO; } } else { - direction = Interop.SspiCli.CredentialUse.Inbound; - flags = Interop.SspiCli.SecureCredential.Flags.SendAuxRecord; + direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND; + flags = Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_SEND_AUX_RECORD; } - Interop.SspiCli.SecureCredential secureCredential = CreateSecureCredential( - Interop.SspiCli.SecureCredential.CurrentVersion, + Interop.SspiCli.SCHANNEL_CRED secureCredential = CreateSecureCredential( + Interop.SspiCli.SCHANNEL_CRED.CurrentVersion, certificate, flags, protocolFlags, @@ -164,10 +165,10 @@ public static SecurityStatusPal EncryptMessage(SafeDeleteContext securityContext // Encryption using SCHANNEL requires 4 buffers: header, payload, trailer, empty. SecurityBuffer[] securityBuffer = new SecurityBuffer[4]; - securityBuffer[0] = new SecurityBuffer(writeBuffer, 0, headerSize, SecurityBufferType.Header); - securityBuffer[1] = new SecurityBuffer(writeBuffer, headerSize, size, SecurityBufferType.Data); - securityBuffer[2] = new SecurityBuffer(writeBuffer, headerSize + size, trailerSize, SecurityBufferType.Trailer); - securityBuffer[3] = new SecurityBuffer(null, SecurityBufferType.Empty); + securityBuffer[0] = new SecurityBuffer(writeBuffer, 0, headerSize, SecurityBufferType.SECBUFFER_STREAM_HEADER); + securityBuffer[1] = new SecurityBuffer(writeBuffer, headerSize, size, SecurityBufferType.SECBUFFER_DATA); + securityBuffer[2] = new SecurityBuffer(writeBuffer, headerSize + size, trailerSize, SecurityBufferType.SECBUFFER_STREAM_TRAILER); + securityBuffer[3] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); int errorCode = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPISecureChannel, securityContext, securityBuffer, 0); @@ -192,12 +193,12 @@ public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext { // Decryption using SCHANNEL requires four buffers. SecurityBuffer[] decspc = new SecurityBuffer[4]; - decspc[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.Data); - decspc[1] = new SecurityBuffer(null, SecurityBufferType.Empty); - decspc[2] = new SecurityBuffer(null, SecurityBufferType.Empty); - decspc[3] = new SecurityBuffer(null, SecurityBufferType.Empty); + decspc[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.SECBUFFER_DATA); + decspc[1] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); + decspc[2] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); + decspc[3] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); - Interop.SecurityStatus errorCode = (Interop.SecurityStatus)SSPIWrapper.DecryptMessage( + Interop.SECURITY_STATUS errorCode = (Interop.SECURITY_STATUS)SSPIWrapper.DecryptMessage( GlobalSSPI.SSPISecureChannel, securityContext, decspc, @@ -207,9 +208,9 @@ public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext for (int i = 0; i < decspc.Length; i++) { // Successfully decoded data and placed it at the following position in the buffer, - if ((errorCode == Interop.SecurityStatus.OK && decspc[i].type == SecurityBufferType.Data) + if ((errorCode == Interop.SECURITY_STATUS.OK && decspc[i].type == SecurityBufferType.SECBUFFER_DATA) // or we failed to decode the data, here is the encoded data. - || (errorCode != Interop.SecurityStatus.OK && decspc[i].type == SecurityBufferType.Extra)) + || (errorCode != Interop.SECURITY_STATUS.OK && decspc[i].type == SecurityBufferType.SECBUFFER_EXTRA)) { offset = decspc[i].offset; count = decspc[i].size; @@ -220,6 +221,54 @@ public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode); } + public static SecurityStatusPal ApplyAlertToken(ref SafeFreeCredentials credentialsHandle, SafeDeleteContext securityContext, TlsAlertType alertType, TlsAlertMessage alertMessage) + { + Interop.SChannel.SCHANNEL_ALERT_TOKEN alertToken; + alertToken.dwTokenType = Interop.SChannel.SCHANNEL_ALERT; + alertToken.dwAlertType = (uint)alertType; + alertToken.dwAlertNumber = (uint)alertMessage; + + var bufferDesc = new SecurityBuffer[1]; + + int alertTokenByteSize = Marshal.SizeOf(); + IntPtr p = Marshal.AllocHGlobal(alertTokenByteSize); + + try + { + var buffer = new byte[alertTokenByteSize]; + Marshal.StructureToPtr(alertToken, p, false); + Marshal.Copy(p, buffer, 0, alertTokenByteSize); + + bufferDesc[0] = new SecurityBuffer(buffer, SecurityBufferType.SECBUFFER_TOKEN); + var errorCode = (Interop.SECURITY_STATUS)SSPIWrapper.ApplyControlToken( + GlobalSSPI.SSPISecureChannel, + ref securityContext, + bufferDesc); + + return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode, attachException:true); + } + finally + { + Marshal.FreeHGlobal(p); + } + } + + public static SecurityStatusPal ApplyShutdownToken(ref SafeFreeCredentials credentialsHandle, SafeDeleteContext securityContext) + { + int shutdownToken = Interop.SChannel.SCHANNEL_SHUTDOWN; + + var bufferDesc = new SecurityBuffer[1]; + var buffer = BitConverter.GetBytes(shutdownToken); + + bufferDesc[0] = new SecurityBuffer(buffer, SecurityBufferType.SECBUFFER_TOKEN); + var errorCode = (Interop.SECURITY_STATUS)SSPIWrapper.ApplyControlToken( + GlobalSSPI.SSPISecureChannel, + ref securityContext, + bufferDesc); + + return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode, attachException:true); + } + public unsafe static SafeFreeContextBufferChannelBinding QueryContextChannelBinding(SafeDeleteContext securityContext, ChannelBindingKind attribute) { return SSPIWrapper.QueryContextChannelBinding(GlobalSSPI.SSPISecureChannel, securityContext, (Interop.SspiCli.ContextAttribute)attribute); @@ -227,18 +276,22 @@ public unsafe static SafeFreeContextBufferChannelBinding QueryContextChannelBind public static void QueryContextStreamSizes(SafeDeleteContext securityContext, out StreamSizes streamSizes) { - streamSizes = SSPIWrapper.QueryContextAttributes( + var interopStreamSizes = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, securityContext, - Interop.SspiCli.ContextAttribute.StreamSizes) as StreamSizes; + Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES) as SecPkgContext_StreamSizes; + + streamSizes = new StreamSizes(interopStreamSizes); } public static void QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo) { - connectionInfo = SSPIWrapper.QueryContextAttributes( + var interopConnectionInfo = SSPIWrapper.QueryContextAttributes( GlobalSSPI.SSPISecureChannel, securityContext, - Interop.SspiCli.ContextAttribute.ConnectionInfo) as SslConnectionInfo; + Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO) as SecPkgContext_ConnectionInfo; + + connectionInfo = new SslConnectionInfo(interopConnectionInfo); } private static int GetProtocolFlagsFromSslProtocols(SslProtocols protocols, bool isServer) @@ -257,18 +310,18 @@ private static int GetProtocolFlagsFromSslProtocols(SslProtocols protocols, bool return protocolFlags; } - private static Interop.SspiCli.SecureCredential CreateSecureCredential( + private static Interop.SspiCli.SCHANNEL_CRED CreateSecureCredential( int version, X509Certificate certificate, - Interop.SspiCli.SecureCredential.Flags flags, + Interop.SspiCli.SCHANNEL_CRED.Flags flags, int protocols, EncryptionPolicy policy) { - var credential = new Interop.SspiCli.SecureCredential() + var credential = new Interop.SspiCli.SCHANNEL_CRED() { - rootStore = IntPtr.Zero, - phMappers = IntPtr.Zero, + hRootStore = IntPtr.Zero, + aphMappers = IntPtr.Zero, palgSupportedAlgs = IntPtr.Zero, - certContextArray = IntPtr.Zero, + paCred = IntPtr.Zero, cCreds = 0, cMappers = 0, cSupportedAlgs = 0, @@ -299,12 +352,12 @@ private static Interop.SspiCli.SecureCredential CreateSecureCredential( throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), nameof(policy)); } - credential.version = version; + credential.dwVersion = version; credential.dwFlags = flags; credential.grbitEnabledProtocols = protocols; if (certificate != null) { - credential.certContextArray = certificate.Handle; + credential.paCred = certificate.Handle; credential.cCreds = 1; } @@ -314,7 +367,7 @@ private static Interop.SspiCli.SecureCredential CreateSecureCredential( // // Security: we temporarily reset thread token to open the handle under process account. // - private static SafeFreeCredentials AcquireCredentialsHandle(Interop.SspiCli.CredentialUse credUsage, Interop.SspiCli.SecureCredential secureCredential) + private static SafeFreeCredentials AcquireCredentialsHandle(Interop.SspiCli.CredentialUse credUsage, Interop.SspiCli.SCHANNEL_CRED secureCredential) { // First try without impersonation, if it fails, then try the process account. // I.E. We don't know which account the certificate context was created under. diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/StreamSizes.cs b/src/System.Net.Security/src/System/Net/Security/StreamSizes.Unix.cs similarity index 87% rename from src/Common/src/Interop/Unix/System.Security.Cryptography.Native/StreamSizes.cs rename to src/System.Net.Security/src/System/Net/Security/StreamSizes.Unix.cs index 1fad77dff661..58025fa76032 100644 --- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/StreamSizes.cs +++ b/src/System.Net.Security/src/System/Net/Security/StreamSizes.Unix.cs @@ -4,7 +4,7 @@ namespace System.Net { - internal class StreamSizes + internal partial class StreamSizes { // Windows SChannel requires that you pass it a buffer big enough to hold // the header, the trailer, and the payload. You're also required to do your @@ -19,8 +19,12 @@ internal class StreamSizes // We could really set maximumMessage to int.MaxValue and have everything still work, // but using a bound of 32k means that if we were to switch from pointers to temporary // arrays, we'd be maintaining a reasonable upper bound. - public readonly int header = 0; - public readonly int trailer = 0; - public readonly int maximumMessage = 32 * 1024; + + public StreamSizes() + { + Header = 0; + Trailer = 0; + MaximumMessage = 32 * 1024; + } } } diff --git a/src/System.Net.Security/src/System/Net/Security/StreamSizes.Windows.cs b/src/System.Net.Security/src/System/Net/Security/StreamSizes.Windows.cs new file mode 100644 index 000000000000..a09cad726aa4 --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/StreamSizes.Windows.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net +{ + internal partial class StreamSizes + { + public StreamSizes(SecPkgContext_StreamSizes interopStreamSizes) + { + Header = interopStreamSizes.cbHeader; + Trailer = interopStreamSizes.cbTrailer; + MaximumMessage = interopStreamSizes.cbMaximumMessage; + } + } +} diff --git a/src/System.Net.Security/src/System/Net/Security/StreamSizes.cs b/src/System.Net.Security/src/System/Net/Security/StreamSizes.cs new file mode 100644 index 000000000000..a885fa364e56 --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/StreamSizes.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net +{ + internal partial class StreamSizes + { + public int Header + { + get; + private set; + } + + public int Trailer + { + get; + private set; + } + + public int MaximumMessage + { + get; + private set; + } + } +} diff --git a/src/System.Net.Security/src/System/Net/Security/TlsAlertMessage.cs b/src/System.Net.Security/src/System/Net/Security/TlsAlertMessage.cs new file mode 100644 index 000000000000..7e8cb7e2f01d --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/TlsAlertMessage.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net.Security +{ + internal enum TlsAlertMessage + { + CloseNotify = 0, // warning + UnexpectedMessage = 10, // error + BadRecordMac = 20, // error + DecryptionFailed = 21, // reserved + RecordOverflow = 22, // error + DecompressionFail = 30, // error + HandshakeFailure = 40, // error + BadCertificate = 42, // warning or error + UnsupportedCert = 43, // warning or error + CertificateRevoked = 44, // warning or error + CertificateExpired = 45, // warning or error + CertificateUnknown = 46, // warning or error + IllegalParameter = 47, // error + UnknownCA = 48, // error + AccessDenied = 49, // error + DecodeError = 50, // error + DecryptError = 51, // error + ExportRestriction = 60, // reserved + ProtocolVersion = 70, // error + InsuffientSecurity = 71, // error + InternalError = 80, // error + UserCanceled = 90, // warning or error + NoRenegotiation = 100, // warning + UnsupportedExt = 110, // error + } +} diff --git a/src/System.Net.Security/src/System/Net/Security/TlsAlertType.cs b/src/System.Net.Security/src/System/Net/Security/TlsAlertType.cs new file mode 100644 index 000000000000..4943910f3f99 --- /dev/null +++ b/src/System.Net.Security/src/System/Net/Security/TlsAlertType.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Net.Security +{ + internal enum TlsAlertType + { + Warning = 1, + Fatal = 2, + } +} diff --git a/src/System.Net.Security/src/System/Net/SecurityBufferType.cs b/src/System.Net.Security/src/System/Net/SecurityBufferType.cs deleted file mode 100644 index a1ffaa491e7d..000000000000 --- a/src/System.Net.Security/src/System/Net/SecurityBufferType.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace System.Net.Security -{ - internal enum SecurityBufferType - { - Empty = 0x00, - Data = 0x01, - Token = 0x02, - Parameters = 0x03, - Missing = 0x04, - Extra = 0x05, - Trailer = 0x06, - Header = 0x07, - Padding = 0x09, // non-data padding - Stream = 0x0A, - ChannelBindings = 0x0E, - TargetHost = 0x10, - ReadOnlyFlag = unchecked((int)0x80000000), - ReadOnlyWithChecksum = 0x10000000 - } -} diff --git a/src/System.Net.Security/src/System/Net/SecurityStatusAdapterPal.Windows.cs b/src/System.Net.Security/src/System/Net/SecurityStatusAdapterPal.Windows.cs index e6369e260106..a02338bd59eb 100644 --- a/src/System.Net.Security/src/System/Net/SecurityStatusAdapterPal.Windows.cs +++ b/src/System.Net.Security/src/System/Net/SecurityStatusAdapterPal.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; namespace System.Net @@ -17,55 +18,55 @@ static SecurityStatusAdapterPal() } #endif - private static readonly BidirectionalDictionary s_statusDictionary = new BidirectionalDictionary(StatusDictionarySize) + private static readonly BidirectionalDictionary s_statusDictionary = new BidirectionalDictionary(StatusDictionarySize) { - { Interop.SecurityStatus.AlgorithmMismatch, SecurityStatusPalErrorCode.AlgorithmMismatch }, - { Interop.SecurityStatus.BadBinding, SecurityStatusPalErrorCode.BadBinding }, - { Interop.SecurityStatus.BufferNotEnough, SecurityStatusPalErrorCode.BufferNotEnough }, - { Interop.SecurityStatus.CannotInstall, SecurityStatusPalErrorCode.CannotInstall }, - { Interop.SecurityStatus.CertExpired, SecurityStatusPalErrorCode.CertExpired }, - { Interop.SecurityStatus.CertUnknown, SecurityStatusPalErrorCode.CertUnknown }, - { Interop.SecurityStatus.CompAndContinue, SecurityStatusPalErrorCode.CompAndContinue }, - { Interop.SecurityStatus.CompleteNeeded, SecurityStatusPalErrorCode.CompleteNeeded }, - { Interop.SecurityStatus.ContextExpired, SecurityStatusPalErrorCode.ContextExpired }, - { Interop.SecurityStatus.CredentialsNeeded, SecurityStatusPalErrorCode.CredentialsNeeded }, - { Interop.SecurityStatus.ContinueNeeded, SecurityStatusPalErrorCode.ContinueNeeded }, - { Interop.SecurityStatus.IllegalMessage, SecurityStatusPalErrorCode.IllegalMessage }, - { Interop.SecurityStatus.CannotPack, SecurityStatusPalErrorCode.CannotPack }, - { Interop.SecurityStatus.IncompleteCredentials, SecurityStatusPalErrorCode.IncompleteCredentials }, - { Interop.SecurityStatus.IncompleteMessage, SecurityStatusPalErrorCode.IncompleteMessage }, - { Interop.SecurityStatus.InternalError, SecurityStatusPalErrorCode.InternalError }, - { Interop.SecurityStatus.InvalidHandle, SecurityStatusPalErrorCode.InvalidHandle }, - { Interop.SecurityStatus.InvalidToken, SecurityStatusPalErrorCode.InvalidToken }, - { Interop.SecurityStatus.LogonDenied, SecurityStatusPalErrorCode.LogonDenied }, - { Interop.SecurityStatus.NoAuthenticatingAuthority, SecurityStatusPalErrorCode.NoAuthenticatingAuthority }, - { Interop.SecurityStatus.NoImpersonation, SecurityStatusPalErrorCode.NoImpersonation }, - { Interop.SecurityStatus.NoCredentials, SecurityStatusPalErrorCode.NoCredentials }, - { Interop.SecurityStatus.NotOwner, SecurityStatusPalErrorCode.NotOwner }, - { Interop.SecurityStatus.OK, SecurityStatusPalErrorCode.OK }, - { Interop.SecurityStatus.OutOfMemory, SecurityStatusPalErrorCode.OutOfMemory }, - { Interop.SecurityStatus.OutOfSequence, SecurityStatusPalErrorCode.OutOfSequence }, - { Interop.SecurityStatus.PackageNotFound, SecurityStatusPalErrorCode.PackageNotFound }, - { Interop.SecurityStatus.MessageAltered, SecurityStatusPalErrorCode.MessageAltered }, - { Interop.SecurityStatus.QopNotSupported, SecurityStatusPalErrorCode.QopNotSupported }, - { Interop.SecurityStatus.Renegotiate, SecurityStatusPalErrorCode.Renegotiate }, - { Interop.SecurityStatus.SecurityQosFailed, SecurityStatusPalErrorCode.SecurityQosFailed }, - { Interop.SecurityStatus.SmartcardLogonRequired, SecurityStatusPalErrorCode.SmartcardLogonRequired }, - { Interop.SecurityStatus.TargetUnknown, SecurityStatusPalErrorCode.TargetUnknown }, - { Interop.SecurityStatus.TimeSkew, SecurityStatusPalErrorCode.TimeSkew }, - { Interop.SecurityStatus.UnknownCredentials, SecurityStatusPalErrorCode.UnknownCredentials }, - { Interop.SecurityStatus.UnsupportedPreauth, SecurityStatusPalErrorCode.UnsupportedPreauth }, - { Interop.SecurityStatus.Unsupported, SecurityStatusPalErrorCode.Unsupported }, - { Interop.SecurityStatus.UntrustedRoot, SecurityStatusPalErrorCode.UntrustedRoot }, - { Interop.SecurityStatus.WrongPrincipal, SecurityStatusPalErrorCode.WrongPrincipal } + { Interop.SECURITY_STATUS.AlgorithmMismatch, SecurityStatusPalErrorCode.AlgorithmMismatch }, + { Interop.SECURITY_STATUS.BadBinding, SecurityStatusPalErrorCode.BadBinding }, + { Interop.SECURITY_STATUS.BufferNotEnough, SecurityStatusPalErrorCode.BufferNotEnough }, + { Interop.SECURITY_STATUS.CannotInstall, SecurityStatusPalErrorCode.CannotInstall }, + { Interop.SECURITY_STATUS.CertExpired, SecurityStatusPalErrorCode.CertExpired }, + { Interop.SECURITY_STATUS.CertUnknown, SecurityStatusPalErrorCode.CertUnknown }, + { Interop.SECURITY_STATUS.CompAndContinue, SecurityStatusPalErrorCode.CompAndContinue }, + { Interop.SECURITY_STATUS.CompleteNeeded, SecurityStatusPalErrorCode.CompleteNeeded }, + { Interop.SECURITY_STATUS.ContextExpired, SecurityStatusPalErrorCode.ContextExpired }, + { Interop.SECURITY_STATUS.CredentialsNeeded, SecurityStatusPalErrorCode.CredentialsNeeded }, + { Interop.SECURITY_STATUS.ContinueNeeded, SecurityStatusPalErrorCode.ContinueNeeded }, + { Interop.SECURITY_STATUS.IllegalMessage, SecurityStatusPalErrorCode.IllegalMessage }, + { Interop.SECURITY_STATUS.CannotPack, SecurityStatusPalErrorCode.CannotPack }, + { Interop.SECURITY_STATUS.IncompleteCredentials, SecurityStatusPalErrorCode.IncompleteCredentials }, + { Interop.SECURITY_STATUS.IncompleteMessage, SecurityStatusPalErrorCode.IncompleteMessage }, + { Interop.SECURITY_STATUS.InternalError, SecurityStatusPalErrorCode.InternalError }, + { Interop.SECURITY_STATUS.InvalidHandle, SecurityStatusPalErrorCode.InvalidHandle }, + { Interop.SECURITY_STATUS.InvalidToken, SecurityStatusPalErrorCode.InvalidToken }, + { Interop.SECURITY_STATUS.LogonDenied, SecurityStatusPalErrorCode.LogonDenied }, + { Interop.SECURITY_STATUS.NoAuthenticatingAuthority, SecurityStatusPalErrorCode.NoAuthenticatingAuthority }, + { Interop.SECURITY_STATUS.NoImpersonation, SecurityStatusPalErrorCode.NoImpersonation }, + { Interop.SECURITY_STATUS.NoCredentials, SecurityStatusPalErrorCode.NoCredentials }, + { Interop.SECURITY_STATUS.NotOwner, SecurityStatusPalErrorCode.NotOwner }, + { Interop.SECURITY_STATUS.OK, SecurityStatusPalErrorCode.OK }, + { Interop.SECURITY_STATUS.OutOfMemory, SecurityStatusPalErrorCode.OutOfMemory }, + { Interop.SECURITY_STATUS.OutOfSequence, SecurityStatusPalErrorCode.OutOfSequence }, + { Interop.SECURITY_STATUS.PackageNotFound, SecurityStatusPalErrorCode.PackageNotFound }, + { Interop.SECURITY_STATUS.MessageAltered, SecurityStatusPalErrorCode.MessageAltered }, + { Interop.SECURITY_STATUS.QopNotSupported, SecurityStatusPalErrorCode.QopNotSupported }, + { Interop.SECURITY_STATUS.Renegotiate, SecurityStatusPalErrorCode.Renegotiate }, + { Interop.SECURITY_STATUS.SecurityQosFailed, SecurityStatusPalErrorCode.SecurityQosFailed }, + { Interop.SECURITY_STATUS.SmartcardLogonRequired, SecurityStatusPalErrorCode.SmartcardLogonRequired }, + { Interop.SECURITY_STATUS.TargetUnknown, SecurityStatusPalErrorCode.TargetUnknown }, + { Interop.SECURITY_STATUS.TimeSkew, SecurityStatusPalErrorCode.TimeSkew }, + { Interop.SECURITY_STATUS.UnknownCredentials, SecurityStatusPalErrorCode.UnknownCredentials }, + { Interop.SECURITY_STATUS.UnsupportedPreauth, SecurityStatusPalErrorCode.UnsupportedPreauth }, + { Interop.SECURITY_STATUS.Unsupported, SecurityStatusPalErrorCode.Unsupported }, + { Interop.SECURITY_STATUS.UntrustedRoot, SecurityStatusPalErrorCode.UntrustedRoot }, + { Interop.SECURITY_STATUS.WrongPrincipal, SecurityStatusPalErrorCode.WrongPrincipal } }; internal static SecurityStatusPal GetSecurityStatusPalFromNativeInt(int win32SecurityStatus) { - return GetSecurityStatusPalFromInterop((Interop.SecurityStatus) win32SecurityStatus); + return GetSecurityStatusPalFromInterop((Interop.SECURITY_STATUS) win32SecurityStatus); } - internal static SecurityStatusPal GetSecurityStatusPalFromInterop(Interop.SecurityStatus win32SecurityStatus) + internal static SecurityStatusPal GetSecurityStatusPalFromInterop(Interop.SECURITY_STATUS win32SecurityStatus, bool attachException = false) { SecurityStatusPalErrorCode statusCode; @@ -74,12 +75,20 @@ internal static SecurityStatusPal GetSecurityStatusPalFromInterop(Interop.Securi Debug.Fail("Unknown Interop.SecurityStatus value: " + win32SecurityStatus); throw new InternalException(); } - return new SecurityStatusPal(statusCode); + + if (attachException) + { + return new SecurityStatusPal(statusCode, new Win32Exception((int)win32SecurityStatus)); + } + else + { + return new SecurityStatusPal(statusCode); + } } - internal static Interop.SecurityStatus GetInteropFromSecurityStatusPal(SecurityStatusPal status) + internal static Interop.SECURITY_STATUS GetInteropFromSecurityStatusPal(SecurityStatusPal status) { - Interop.SecurityStatus interopStatus; + Interop.SECURITY_STATUS interopStatus; if (!s_statusDictionary.TryGetBackward(status.ErrorCode, out interopStatus)) { Debug.Fail("Unknown SecurityStatus value: " + status); diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamContext.cs b/src/System.Net.Security/src/System/Net/SslStreamContext.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamContext.cs rename to src/System.Net.Security/src/System/Net/SslStreamContext.cs diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/AuthenticationException.cs b/src/System.Net.Security/src/System/Security/Authentication/AuthenticationException.cs similarity index 100% rename from src/System.Net.Security/src/System/Net/SecureProtocols/AuthenticationException.cs rename to src/System.Net.Security/src/System/Security/Authentication/AuthenticationException.cs diff --git a/src/System.Net.Security/src/unix/project.json b/src/System.Net.Security/src/unix/project.json index c6f44e799f0f..d0fe6b7dbedf 100644 --- a/src/System.Net.Security/src/unix/project.json +++ b/src/System.Net.Security/src/unix/project.json @@ -1,32 +1,29 @@ { - "dependencies": { - "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.Win32.Primitives": "4.0.0", - "System.Collections": "4.0.0", - "System.Collections.Concurrent": "4.0.0", - "System.Diagnostics.Contracts": "4.0.0", - "System.Diagnostics.Debug": "4.0.10", - "System.Diagnostics.Tracing": "4.0.0", - "System.Globalization": "4.0.0", - "System.Globalization.Extensions": "4.0.0", - "System.Net.Primitives": "4.0.10", - "System.Resources.ResourceManager": "4.0.0", - "System.Runtime.Extensions": "4.0.10", - "System.Runtime.Handles": "4.0.0", - "System.Security.Cryptography.OpenSsl": "4.0.0", - "System.Security.Cryptography.X509Certificates": "4.1.0", - "System.Security.Principal": "4.0.0", - "System.Security.Principal.Windows": "4.0.0", - "System.Text.Encoding": "4.0.10", - "System.Threading": "4.0.10", - "System.Threading.Tasks": "4.0.10", - "System.Threading.ThreadPool": "4.0.10" - }, "frameworks": { - "netstandard1.6": { - "imports": [ - "dotnet5.5" - ] + "netstandard1.7": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1", + "Microsoft.Win32.Primitives": "4.4.0-beta-24613-01", + "System.Collections": "4.4.0-beta-24613-01", + "System.Collections.Concurrent": "4.4.0-beta-24613-01", + "System.Diagnostics.Contracts": "4.4.0-beta-24613-01", + "System.Diagnostics.Debug": "4.4.0-beta-24613-01", + "System.Diagnostics.Tracing": "4.4.0-beta-24613-01", + "System.Globalization": "4.4.0-beta-24613-01", + "System.Globalization.Extensions": "4.4.0-beta-24613-01", + "System.Net.Primitives": "4.4.0-beta-24613-01", + "System.Resources.ResourceManager": "4.4.0-beta-24613-01", + "System.Runtime.Extensions": "4.4.0-beta-24613-01", + "System.Runtime.Handles": "4.4.0-beta-24613-01", + "System.Security.Cryptography.OpenSsl": "4.4.0-beta-24613-01", + "System.Security.Cryptography.X509Certificates": "4.4.0-beta-24613-01", + "System.Security.Principal": "4.4.0-beta-24613-01", + "System.Security.Principal.Windows": "4.4.0-beta-24613-01", + "System.Text.Encoding": "4.4.0-beta-24613-01", + "System.Threading": "4.4.0-beta-24613-01", + "System.Threading.Tasks": "4.4.0-beta-24613-01", + "System.Threading.ThreadPool": "4.4.0-beta-24613-01" + } } } } diff --git a/src/System.Net.Security/src/win/project.json b/src/System.Net.Security/src/win/project.json index 539a1917e499..82dcd6b5bdb5 100644 --- a/src/System.Net.Security/src/win/project.json +++ b/src/System.Net.Security/src/win/project.json @@ -1,33 +1,30 @@ { "frameworks": { - "netstandard1.3": { - "imports": [ - "dotnet5.4" - ], + "netstandard1.7": { "dependencies": { "Microsoft.NETCore.Platforms": "1.0.1", - "Microsoft.Win32.Primitives": "4.0.0", - "System.Collections": "4.0.0", - "System.Collections.Concurrent": "4.0.0", - "System.Diagnostics.Contracts": "4.0.0", - "System.Diagnostics.Debug": "4.0.10", - "System.Diagnostics.Tracing": "4.0.0", - "System.Globalization": "4.0.0", - "System.Net.Primitives": "4.0.10", - "System.Resources.ResourceManager": "4.0.0", - "System.Runtime.Extensions": "4.0.10", - "System.Runtime.Handles": "4.0.0", - "System.Security.Cryptography.X509Certificates": "4.1.0", - "System.Security.Principal": "4.0.0", - "System.Security.Principal.Windows": "4.0.0", - "System.Threading": "4.0.10", - "System.Threading.Tasks": "4.0.10", - "System.Threading.ThreadPool": "4.0.10" + "Microsoft.Win32.Primitives": "4.4.0-beta-24613-01", + "System.Collections": "4.4.0-beta-24613-01", + "System.Collections.Concurrent": "4.4.0-beta-24613-01", + "System.Diagnostics.Contracts": "4.4.0-beta-24613-01", + "System.Diagnostics.Debug": "4.4.0-beta-24613-01", + "System.Diagnostics.Tracing": "4.4.0-beta-24613-01", + "System.Globalization": "4.4.0-beta-24613-01", + "System.Net.Primitives": "4.4.0-beta-24613-01", + "System.Resources.ResourceManager": "4.4.0-beta-24613-01", + "System.Runtime.Extensions": "4.4.0-beta-24613-01", + "System.Runtime.Handles": "4.4.0-beta-24613-01", + "System.Security.Cryptography.X509Certificates": "4.4.0-beta-24613-01", + "System.Security.Principal": "4.4.0-beta-24613-01", + "System.Security.Principal.Windows": "4.4.0-beta-24613-01", + "System.Threading": "4.4.0-beta-24613-01", + "System.Threading.Tasks": "4.4.0-beta-24613-01", + "System.Threading.ThreadPool": "4.4.0-beta-24613-01" } }, - "net46": { + "net463": { "dependencies": { - "Microsoft.TargetingPack.NETFramework.v4.6": "1.0.1" + "Microsoft.TargetingPack.NETFramework.v4.6.2": "1.0.1" } } } diff --git a/src/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs b/src/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs index 42b61060454f..bb2ea9e153f3 100644 --- a/src/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs +++ b/src/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs @@ -11,6 +11,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public class CertificateValidationClientServer : IDisposable { private readonly X509Certificate2 _clientCertificate; diff --git a/src/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs b/src/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs index 8bb9b1338f25..f74c2d8209d9 100644 --- a/src/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs +++ b/src/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs @@ -11,6 +11,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public class CertificateValidationRemoteServer { [Fact] diff --git a/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs b/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs index 9d10d9c32ecb..e0828a425b0a 100644 --- a/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs +++ b/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs @@ -8,10 +8,11 @@ using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; -using Xunit; namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + // Callback method that is called when the server receives data from a connected client. // The callback method should return a byte array and the number of bytes to send from that array. public delegate void DummyTcpServerReceiveCallback(byte[] bufferReceived, int bytesReceived, Stream stream); diff --git a/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamKerberosTest.cs b/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamKerberosTest.cs index c8c66da1c67b..3477f90c4dcf 100644 --- a/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamKerberosTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamKerberosTest.cs @@ -14,6 +14,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public class NegotiateStreamKerberosTest { public static bool IsServerAndDomainAvailable => diff --git a/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 831790eb30d3..ef69b303ba6c 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -15,6 +15,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public class ServerAsyncAuthenticateTest : IDisposable { private readonly ITestOutputHelper _log; diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamAlertsTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamAlertsTest.cs new file mode 100644 index 000000000000..793725547cb2 --- /dev/null +++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamAlertsTest.cs @@ -0,0 +1,171 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.IO; +using System.Net.Test.Common; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +using Xunit; + +namespace System.Net.Security.Tests +{ + using Configuration = System.Net.Test.Common.Configuration; + + public class SslStreamAlertsTest + { + private const uint SEC_E_ILLEGAL_MESSAGE = 0x80090326; + private const uint SEC_E_CERT_UNKNOWN = 0x80090327; + + [Fact] + [ActiveIssue(12319, TestPlatforms.AnyUnix)] + public async Task SslStream_StreamToStream_HandshakeAlert_Ok() + { + VirtualNetwork network = new VirtualNetwork(); + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var client = new SslStream(clientStream, true, AllowAnyServerCertificate)) + using (var server = new SslStream(serverStream, true, FailClientCertificate)) + using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate()) + { + Task serverAuth = server.AuthenticateAsServerAsync(certificate); + await client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)); + + byte[] buffer = new byte[1024]; + + // Schannel semantics require that Decrypt is called to receive an alert. + await client.WriteAsync(buffer, 0, buffer.Length); + var exception = await Assert.ThrowsAsync(() => client.ReadAsync(buffer, 0, buffer.Length)); + + Assert.IsType(exception.InnerException); + var win32ex = (Win32Exception)exception.InnerException; + + // The Schannel HResults for each alert are documented here: + // https://msdn.microsoft.com/en-us/library/windows/desktop/dd721886(v=vs.85).aspx + Assert.Equal(SEC_E_CERT_UNKNOWN, (uint)win32ex.NativeErrorCode); + + await Assert.ThrowsAsync(() => serverAuth); + + await Assert.ThrowsAsync(() => server.WriteAsync(buffer, 0, buffer.Length)); + await Assert.ThrowsAsync(() => server.ReadAsync(buffer, 0, buffer.Length)); + } + } + + [Fact] + [ActiveIssue(12319, TestPlatforms.AnyUnix)] + public async Task SslStream_StreamToStream_ServerInitiatedCloseNotify_Ok() + { + VirtualNetwork network = new VirtualNetwork(); + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var client = new SslStream(clientStream, true, AllowAnyServerCertificate)) + using (var server = new SslStream(serverStream)) + using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate()) + { + var handshake = new Task[2]; + + handshake[0] = server.AuthenticateAsServerAsync(certificate); + handshake[1] = client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)); + + await Task.WhenAll(handshake).TimeoutAfter(TestConfiguration.PassingTestTimeoutMilliseconds); + + var readBuffer = new byte[1024]; + + await server.ShutdownAsync(); + int bytesRead = await client.ReadAsync(readBuffer, 0, readBuffer.Length); + // close_notify received by the client. + Assert.Equal(0, bytesRead); + + await client.ShutdownAsync(); + bytesRead = await server.ReadAsync(readBuffer, 0, readBuffer.Length); + // close_notify received by the server. + Assert.Equal(0, bytesRead); + } + } + + [Fact] + [ActiveIssue(12319, TestPlatforms.AnyUnix)] + public async Task SslStream_StreamToStream_ClientInitiatedCloseNotify_Ok() + { + VirtualNetwork network = new VirtualNetwork(); + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var client = new SslStream(clientStream, true, AllowAnyServerCertificate)) + using (var server = new SslStream(serverStream)) + using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate()) + { + var handshake = new Task[2]; + + handshake[0] = server.AuthenticateAsServerAsync(certificate); + handshake[1] = client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)); + + await Task.WhenAll(handshake).TimeoutAfter(TestConfiguration.PassingTestTimeoutMilliseconds); + + var readBuffer = new byte[1024]; + + await client.ShutdownAsync(); + int bytesRead = await server.ReadAsync(readBuffer, 0, readBuffer.Length); + // close_notify received by the server. + Assert.Equal(0, bytesRead); + + await server.ShutdownAsync(); + bytesRead = await client.ReadAsync(readBuffer, 0, readBuffer.Length); + // close_notify received by the client. + Assert.Equal(0, bytesRead); + } + } + + [Fact] + [ActiveIssue(12319, TestPlatforms.AnyUnix)] + public async Task SslStream_StreamToStream_DataAfterShutdown_Fail() + { + VirtualNetwork network = new VirtualNetwork(); + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var client = new SslStream(clientStream, true, AllowAnyServerCertificate)) + using (var server = new SslStream(serverStream)) + using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate()) + { + var handshake = new Task[2]; + + handshake[0] = server.AuthenticateAsServerAsync(certificate); + handshake[1] = client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)); + + await Task.WhenAll(handshake).TimeoutAfter(TestConfiguration.PassingTestTimeoutMilliseconds); + + var buffer = new byte[1024]; + + Assert.Equal(true, client.CanWrite); + + await client.ShutdownAsync(); + + Assert.Equal(false, client.CanWrite); + + await Assert.ThrowsAsync(() => client.ShutdownAsync()); + await Assert.ThrowsAsync(() => client.WriteAsync(buffer, 0, buffer.Length)); + } + } + + private bool FailClientCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + return false; + } + + private bool AllowAnyServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + return true; + } + } +} diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index 698be2e66251..713169e69ef3 100644 --- a/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -12,6 +12,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public class SslStreamNetworkStreamTest { [OuterLoop] // TODO: Issue #11345 diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamSchSendAuxRecordTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamSchSendAuxRecordTest.cs index 8f90c00dcf78..28323633b16c 100644 --- a/src/System.Net.Security/tests/FunctionalTests/SslStreamSchSendAuxRecordTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamSchSendAuxRecordTest.cs @@ -13,6 +13,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public class SchSendAuxRecordTest { readonly ITestOutputHelper _output; diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs index 3c92e6c3a956..247629a48a19 100644 --- a/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs @@ -14,6 +14,8 @@ namespace System.Net.Security.Tests { + using Configuration = System.Net.Test.Common.Configuration; + public abstract class SslStreamStreamToStreamTest { private readonly byte[] _sampleMsg = Encoding.UTF8.GetBytes("Sample Test Message"); diff --git a/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index c8bf6cba261f..b99b2db50467 100644 --- a/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -1,15 +1,15 @@ - + Windows_Debug - Debug + Windows_Debug AnyCPU {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2} Library - .NETStandard,Version=v1.3 + .NETStandard,Version=v1.7 true @@ -32,7 +32,6 @@ - @@ -44,17 +43,16 @@ + - - Common\System\PlatformDetection.cs @@ -144,8 +142,8 @@ - - {89f37791-6254-4d60-ab96-acd3cca0e771} + + {89F37791-6254-4D60-AB96-ACD3CCA0E771} System.Net.Security diff --git a/src/System.Net.Security/tests/FunctionalTests/unix/project.json b/src/System.Net.Security/tests/FunctionalTests/unix/project.json index a31b51e5c691..4fedc0318f2f 100644 --- a/src/System.Net.Security/tests/FunctionalTests/unix/project.json +++ b/src/System.Net.Security/tests/FunctionalTests/unix/project.json @@ -29,13 +29,10 @@ "Microsoft.DotNet.BuildTools.TestSuite": "1.0.0-prerelease-00830-02" }, "frameworks": { - "netstandard1.3": {} + "netstandard1.7": {} }, "supports": { - "coreFx.Test.netcoreapp1.0": {}, - "coreFx.Test.net46": {}, - "coreFx.Test.net461": {}, - "coreFx.Test.net462": {}, + "coreFx.Test.netcoreapp1.1": {}, "coreFx.Test.net463": {} } } diff --git a/src/System.Net.Security/tests/FunctionalTests/win/project.json b/src/System.Net.Security/tests/FunctionalTests/win/project.json index c2d3c1cf63ff..43f314f07720 100644 --- a/src/System.Net.Security/tests/FunctionalTests/win/project.json +++ b/src/System.Net.Security/tests/FunctionalTests/win/project.json @@ -25,13 +25,10 @@ "Microsoft.DotNet.BuildTools.TestSuite": "1.0.0-prerelease-00830-02" }, "frameworks": { - "netstandard1.3": {} + "netstandard1.7": {} }, "supports": { - "coreFx.Test.netcoreapp1.0": {}, - "coreFx.Test.net46": {}, - "coreFx.Test.net461": {}, - "coreFx.Test.net462": {}, + "coreFx.Test.netcoreapp1.1": {}, "coreFx.Test.net463": {} } } diff --git a/src/System.Net.Security/tests/System.Net.Security.Tests.builds b/src/System.Net.Security/tests/System.Net.Security.Tests.builds index 76ab9f500331..d0c951828c69 100644 --- a/src/System.Net.Security/tests/System.Net.Security.Tests.builds +++ b/src/System.Net.Security/tests/System.Net.Security.Tests.builds @@ -10,14 +10,14 @@ Windows_NT - netcoreapp1.0;net46 + netcoreapp1.1;net463 Unix Windows_NT - netcoreapp1.0;net46 + netcoreapp1.1;net463 diff --git a/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs b/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs index ec778e5d9ac9..9a72c84bcab6 100644 --- a/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs +++ b/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs @@ -145,6 +145,8 @@ internal _SslStream SecureStream } } + public bool IsShutdown { get; internal set; } + internal void CheckThrow(bool authSucessCheck) { } @@ -171,6 +173,16 @@ internal void ProcessAuthentication(LazyAsyncResult lazyResult) internal void EndProcessAuthentication(IAsyncResult result) { } + + internal IAsyncResult BeginShutdown(AsyncCallback asyncCallback, object asyncState) + { + throw new NotImplementedException(); + } + + internal void EndShutdown(IAsyncResult asyncResult) + { + throw new NotImplementedException(); + } } internal class _SslStream : Stream @@ -245,22 +257,22 @@ public override void Write(byte[] buffer, int offset, int count) throw new NotImplementedException(); } - internal IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { throw new NotImplementedException(); } - internal int EndRead(IAsyncResult asyncResult) + public override int EndRead(IAsyncResult asyncResult) { throw new NotImplementedException(); } - internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) { throw new NotImplementedException(); } - internal void EndWrite(IAsyncResult asyncResult) + public override void EndWrite(IAsyncResult asyncResult) { throw new NotImplementedException(); } diff --git a/src/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index 7a0eec243b54..a21804f43778 100644 --- a/src/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -10,13 +10,21 @@ {0D174EA9-9E61-4519-8D31-7BD2331A1982} Library ../../src/Resources/Strings.resx - .NETStandard,Version=v1.3 + .NETStandard,Version=v1.7 + + 436 + + @@ -32,15 +40,24 @@ - - ProductionCode\System\Net\SecureProtocols\SslStream.cs + + ProductionCode\System\Net\Security\SslStream.cs - - ProductionCode\System\Net\SecureProtocols\SslStreamContext.cs + + ProductionCode\System\Net\SslStreamContext.cs ProductionCode\Common\System\Net\SecurityProtocol.cs + + ProductionCode\Common\System\Net\TlsAlertType.cs + + + ProductionCode\Common\System\Net\TlsAlertMessage.cs + + + Common\Interop\Windows\SChannel\Interop.Alerts.cs + diff --git a/src/System.Net.Security/tests/UnitTests/TlsAlertsMatchWindowsInterop.cs b/src/System.Net.Security/tests/UnitTests/TlsAlertsMatchWindowsInterop.cs new file mode 100644 index 000000000000..a05f54692477 --- /dev/null +++ b/src/System.Net.Security/tests/UnitTests/TlsAlertsMatchWindowsInterop.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.Net.Security.Tests +{ + public class TlsAlertsMatchWindowsInterop + { + [Fact] + public void TlsAlertEnums_MatchWindowsInterop_Ok() + { + Assert.Equal((int)TlsAlertType.Warning, (int)Interop.SChannel.TLS1_ALERT_WARNING); + Assert.Equal((int)TlsAlertType.Fatal, (int)Interop.SChannel.TLS1_ALERT_FATAL); + + Assert.Equal((int)TlsAlertMessage.CloseNotify, Interop.SChannel.TLS1_ALERT_CLOSE_NOTIFY); + Assert.Equal((int)TlsAlertMessage.UnexpectedMessage, Interop.SChannel.TLS1_ALERT_UNEXPECTED_MESSAGE); + Assert.Equal((int)TlsAlertMessage.BadRecordMac, Interop.SChannel.TLS1_ALERT_BAD_RECORD_MAC); + Assert.Equal((int)TlsAlertMessage.DecryptionFailed, Interop.SChannel.TLS1_ALERT_DECRYPTION_FAILED); + Assert.Equal((int)TlsAlertMessage.RecordOverflow, Interop.SChannel.TLS1_ALERT_RECORD_OVERFLOW); + Assert.Equal((int)TlsAlertMessage.DecompressionFail, Interop.SChannel.TLS1_ALERT_DECOMPRESSION_FAIL); + Assert.Equal((int)TlsAlertMessage.HandshakeFailure, Interop.SChannel.TLS1_ALERT_HANDSHAKE_FAILURE); + Assert.Equal((int)TlsAlertMessage.BadCertificate, Interop.SChannel.TLS1_ALERT_BAD_CERTIFICATE); + Assert.Equal((int)TlsAlertMessage.UnsupportedCert, Interop.SChannel.TLS1_ALERT_UNSUPPORTED_CERT); + Assert.Equal((int)TlsAlertMessage.CertificateRevoked, Interop.SChannel.TLS1_ALERT_CERTIFICATE_REVOKED); + Assert.Equal((int)TlsAlertMessage.CertificateExpired, Interop.SChannel.TLS1_ALERT_CERTIFICATE_EXPIRED); + Assert.Equal((int)TlsAlertMessage.CertificateUnknown, Interop.SChannel.TLS1_ALERT_CERTIFICATE_UNKNOWN); + Assert.Equal((int)TlsAlertMessage.IllegalParameter, Interop.SChannel.TLS1_ALERT_ILLEGAL_PARAMETER); + Assert.Equal((int)TlsAlertMessage.UnknownCA, Interop.SChannel.TLS1_ALERT_UNKNOWN_CA); + Assert.Equal((int)TlsAlertMessage.AccessDenied, Interop.SChannel.TLS1_ALERT_ACCESS_DENIED); + Assert.Equal((int)TlsAlertMessage.DecodeError, Interop.SChannel.TLS1_ALERT_DECODE_ERROR); + Assert.Equal((int)TlsAlertMessage.DecryptError, Interop.SChannel.TLS1_ALERT_DECRYPT_ERROR); + Assert.Equal((int)TlsAlertMessage.ExportRestriction, Interop.SChannel.TLS1_ALERT_EXPORT_RESTRICTION); + Assert.Equal((int)TlsAlertMessage.ProtocolVersion, Interop.SChannel.TLS1_ALERT_PROTOCOL_VERSION); + Assert.Equal((int)TlsAlertMessage.InsuffientSecurity, Interop.SChannel.TLS1_ALERT_INSUFFIENT_SECURITY); + Assert.Equal((int)TlsAlertMessage.InternalError, Interop.SChannel.TLS1_ALERT_INTERNAL_ERROR); + Assert.Equal((int)TlsAlertMessage.UserCanceled, Interop.SChannel.TLS1_ALERT_USER_CANCELED); + Assert.Equal((int)TlsAlertMessage.NoRenegotiation, Interop.SChannel.TLS1_ALERT_NO_RENEGOTIATION); + Assert.Equal((int)TlsAlertMessage.UnsupportedExt, Interop.SChannel.TLS1_ALERT_UNSUPPORTED_EXT); + } + } +} diff --git a/src/System.Net.Security/tests/UnitTests/project.json b/src/System.Net.Security/tests/UnitTests/project.json index 1af9f693a0c2..8358c5da0464 100644 --- a/src/System.Net.Security/tests/UnitTests/project.json +++ b/src/System.Net.Security/tests/UnitTests/project.json @@ -18,13 +18,10 @@ "Microsoft.DotNet.BuildTools.TestSuite": "1.0.0-prerelease-00830-02" }, "frameworks": { - "netstandard1.3": {} + "netstandard1.7": {} }, "supports": { - "coreFx.Test.netcoreapp1.0": {}, - "coreFx.Test.net46": {}, - "coreFx.Test.net461": {}, - "coreFx.Test.net462": {}, + "coreFx.Test.netcoreapp1.1": {}, "coreFx.Test.net463": {} } }