Пример #1
0
 private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode)
 {
     return(errorCode != SecurityStatusPalErrorCode.NotSet &&
            errorCode != SecurityStatusPalErrorCode.OK &&
            errorCode != SecurityStatusPalErrorCode.ContinueNeeded &&
            errorCode != SecurityStatusPalErrorCode.CompleteNeeded &&
            errorCode != SecurityStatusPalErrorCode.CompAndContinue &&
            errorCode != SecurityStatusPalErrorCode.ContextExpired &&
            errorCode != SecurityStatusPalErrorCode.CredentialsNeeded &&
            errorCode != SecurityStatusPalErrorCode.Renegotiate);
 }
        internal static SecurityStatusPal AcceptSecurityContext(
            SafeFreeCredentials credentialsHandle,
            ref SafeDeleteContext securityContext,
            ContextFlagsPal requestedContextFlags,
            byte[] incomingBlob,
            ChannelBinding channelBinding,
            ref byte[] resultBlob,
            ref ContextFlagsPal contextFlags)
        {
            if (securityContext == null)
            {
                securityContext = new SafeDeleteNegoContext((SafeFreeNegoCredentials)credentialsHandle);
            }

            SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)securityContext;

            try
            {
                SafeGssContextHandle contextHandle = negoContext.GssContext;
                bool done = GssAcceptSecurityContext(
                    ref contextHandle,
                    incomingBlob,
                    out resultBlob,
                    out uint outputFlags);

                Debug.Assert(resultBlob != null, "Unexpected null buffer returned by GssApi");
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);

                // Save the inner context handle for further calls to NetSecurity
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);
                if (null == negoContext.GssContext)
                {
                    negoContext.SetGssContext(contextHandle);
                }

                contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(
                    (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: true);

                SecurityStatusPalErrorCode errorCode = done ?
                                                       (negoContext.IsNtlmUsed && resultBlob.Length > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) :
                                                       SecurityStatusPalErrorCode.ContinueNeeded;

                return(new SecurityStatusPal(errorCode));
            }
            catch (Exception ex)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(null, ex);
                }
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex));
            }
        }
Пример #3
0
        private static SecurityStatusPal HandshakeInternal(
            SafeFreeCredentials credential,
            ref SafeDeleteSslContext?context,
            ReadOnlySpan <byte> inputBuffer,
            ref byte[]?outputBuffer,
            SslAuthenticationOptions sslAuthenticationOptions)
        {
            Debug.Assert(!credential.IsInvalid);

            try
            {
                SafeDeleteSslContext?sslContext = ((SafeDeleteSslContext?)context);

                if ((context == null) || context.IsInvalid)
                {
                    context    = new SafeDeleteSslContext((credential as SafeFreeSslCredentials) !, sslAuthenticationOptions);
                    sslContext = context;
                }

                if (inputBuffer.Length > 0)
                {
                    sslContext !.Write(inputBuffer);
                }

                SafeSslHandle sslHandle = sslContext !.SslContext;

                PAL_SSLStreamStatus        ret        = Interop.AndroidCrypto.SSLStreamHandshake(sslHandle);
                SecurityStatusPalErrorCode statusCode = ret switch
                {
                    PAL_SSLStreamStatus.OK => SecurityStatusPalErrorCode.OK,
                    PAL_SSLStreamStatus.NeedData => SecurityStatusPalErrorCode.ContinueNeeded,
                    _ => SecurityStatusPalErrorCode.InternalError
                };

                outputBuffer = sslContext.ReadPendingWrites();

                return(new SecurityStatusPal(statusCode));
            }
            catch (Exception exc)
            {
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc));
            }
        }
Пример #4
0
        public static SecurityStatusPal EncryptMessage(
            SafeDeleteContext securityContext,
            ReadOnlyMemory <byte> input,
            int headerSize,
            int trailerSize,
            ref byte[] output,
            out int resultSize)
        {
            resultSize = 0;
            Debug.Assert(input.Length > 0, $"{nameof(input.Length)} > 0 since {nameof(CanEncryptEmptyMessage)} is false");

            try
            {
                SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext;
                SafeSslHandle        sslHandle  = sslContext.SslContext;

                PAL_SSLStreamStatus        ret        = Interop.AndroidCrypto.SSLStreamWrite(sslHandle, input);
                SecurityStatusPalErrorCode statusCode = ret switch
                {
                    PAL_SSLStreamStatus.OK => SecurityStatusPalErrorCode.OK,
                    PAL_SSLStreamStatus.NeedData => SecurityStatusPalErrorCode.ContinueNeeded,
                    PAL_SSLStreamStatus.Renegotiate => SecurityStatusPalErrorCode.Renegotiate,
                    PAL_SSLStreamStatus.Closed => SecurityStatusPalErrorCode.ContextExpired,
                    _ => SecurityStatusPalErrorCode.InternalError
                };

                if (sslContext.BytesReadyForConnection <= output?.Length)
                {
                    resultSize = sslContext.ReadPendingWrites(output, 0, output.Length);
                }
                else
                {
                    output     = sslContext.ReadPendingWrites() !;
                    resultSize = output.Length;
                }

                return(new SecurityStatusPal(statusCode));
            }
            catch (Exception e)
            {
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, e));
            }
        }
Пример #5
0
        public static SecurityStatusPal DecryptMessage(
            SafeDeleteSslContext securityContext,
            Span <byte> buffer,
            out int offset,
            out int count)
        {
            offset = 0;
            count  = 0;

            try
            {
                SafeSslHandle sslHandle = securityContext.SslContext;

                securityContext.Write(buffer);

                PAL_SSLStreamStatus ret = Interop.AndroidCrypto.SSLStreamRead(sslHandle, buffer, out int read);
                if (ret == PAL_SSLStreamStatus.Error)
                {
                    return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError));
                }

                count = read;

                SecurityStatusPalErrorCode statusCode = ret switch
                {
                    PAL_SSLStreamStatus.OK => SecurityStatusPalErrorCode.OK,
                    PAL_SSLStreamStatus.NeedData => SecurityStatusPalErrorCode.OK,
                    PAL_SSLStreamStatus.Renegotiate => SecurityStatusPalErrorCode.Renegotiate,
                    PAL_SSLStreamStatus.Closed => SecurityStatusPalErrorCode.ContextExpired,
                    _ => SecurityStatusPalErrorCode.InternalError
                };

                return(new SecurityStatusPal(statusCode));
            }
            catch (Exception e)
            {
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, e));
            }
        }
Пример #6
0
        private static SecurityStatusPal EstablishSecurityContext(
            SafeFreeNegoCredentials credential,
            ref SafeDeleteContext?context,
            ChannelBinding?channelBinding,
            string?targetName,
            ContextFlagsPal inFlags,
            byte[]?incomingBlob,
            ref byte[]?resultBuffer,
            ref ContextFlagsPal outFlags)
        {
            bool isNtlmOnly = credential.IsNtlmOnly;

            if (context == null)
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    string protocol = isNtlmOnly ? "NTLM" : "SPNEGO";
                    NetEventSource.Info(context, $"requested protocol = {protocol}, target = {targetName}");
                }

                context = new SafeDeleteNegoContext(credential, targetName !);
            }

            SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context;

            try
            {
                Interop.NetSecurityNative.GssFlags inputFlags =
                    ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false);
                uint outputFlags;
                bool isNtlmUsed;
                SafeGssContextHandle?contextHandle = negoContext.GssContext;
                bool done = GssInitSecurityContext(
                    ref contextHandle,
                    credential.GssCredential,
                    isNtlmOnly,
                    channelBinding,
                    negoContext.TargetName,
                    inputFlags,
                    incomingBlob,
                    out resultBuffer,
                    out outputFlags,
                    out isNtlmUsed);

                if (done)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        string protocol = isNtlmOnly ? "NTLM" : isNtlmUsed ? "SPNEGO-NTLM" : "SPNEGO-Kerberos";
                        NetEventSource.Info(context, $"actual protocol = {protocol}");
                    }

                    // Populate protocol used for authentication
                    negoContext.SetAuthenticationPackage(isNtlmUsed);
                }

                Debug.Assert(resultBuffer != null, "Unexpected null buffer returned by GssApi");
                outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(
                    (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false);
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);

                // Save the inner context handle for further calls to NetSecurity
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);
                if (null == negoContext.GssContext)
                {
                    negoContext.SetGssContext(contextHandle !);
                }

                SecurityStatusPalErrorCode errorCode = done ?
                                                       (negoContext.IsNtlmUsed && resultBuffer.Length > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) :
                                                       SecurityStatusPalErrorCode.ContinueNeeded;
                return(new SecurityStatusPal(errorCode));
            }
            catch (Exception ex)
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Error(null, ex);
                }
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex));
            }
        }
Пример #7
0
        private static SecurityStatusPal EstablishSecurityContext(
            SafeFreeNegoCredentials credential,
            ref SafeDeleteContext context,
            string targetName,
            ContextFlagsPal inFlags,
            SecurityBuffer inputBuffer,
            SecurityBuffer outputBuffer,
            ref ContextFlagsPal outFlags)
        {
            bool isNtlmOnly = credential.IsNtlmOnly;

            if (context == null)
            {
                // Empty target name causes the failure on Linux, hence passing a non-empty string
                context = isNtlmOnly ? new SafeDeleteNegoContext(credential, credential.UserName) : new SafeDeleteNegoContext(credential, targetName);
            }

            SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context;

            try
            {
                Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false);
                uint outputFlags;
                int  isNtlmUsed;
                SafeGssContextHandle contextHandle = negoContext.GssContext;
                bool done = GssInitSecurityContext(
                    ref contextHandle,
                    credential.GssCredential,
                    isNtlmOnly,
                    negoContext.TargetName,
                    inputFlags,
                    inputBuffer?.token,
                    out outputBuffer.token,
                    out outputFlags,
                    out isNtlmUsed);

                Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi");
                outputBuffer.size   = outputBuffer.token.Length;
                outputBuffer.offset = 0;
                outFlags            = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false);
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);

                // Save the inner context handle for further calls to NetSecurity
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);
                if (null == negoContext.GssContext)
                {
                    negoContext.SetGssContext(contextHandle);
                }

                // Populate protocol used for authentication
                if (done)
                {
                    negoContext.SetAuthenticationPackage(Convert.ToBoolean(isNtlmUsed));
                }

                SecurityStatusPalErrorCode errorCode = done ?
                                                       (negoContext.IsNtlmUsed && outputBuffer.size > 0 ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.CompleteNeeded) :
                                                       SecurityStatusPalErrorCode.ContinueNeeded;
                return(new SecurityStatusPal(errorCode));
            }
            catch (Exception ex)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(null, ex);
                }
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex));
            }
        }
Пример #8
0
        private static SecurityStatusPal EstablishSecurityContext(
            SafeFreeNegoCredentials credential,
            ref SafeDeleteContext?context,
            ChannelBinding?channelBinding,
            string?targetName,
            ContextFlagsPal inFlags,
            ReadOnlySpan <byte> incomingBlob,
            out byte[]?resultBuffer,
            ref ContextFlagsPal outFlags)
        {
            bool isNtlmOnly = credential.IsNtlmOnly;

            resultBuffer = null;

            if (context == null)
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    string protocol = isNtlmOnly ? "NTLM" : "SPNEGO";
                    NetEventSource.Info(context, $"requested protocol = {protocol}, target = {targetName}");
                }

                context = new SafeDeleteNegoContext(credential, targetName !);
            }

            Interop.NetSecurityNative.GssBuffer token = default(Interop.NetSecurityNative.GssBuffer);
            Interop.NetSecurityNative.Status    status;
            Interop.NetSecurityNative.Status    minorStatus;
            SafeDeleteNegoContext negoContext   = (SafeDeleteNegoContext)context;
            SafeGssContextHandle  contextHandle = negoContext.GssContext;

            try
            {
                Interop.NetSecurityNative.GssFlags inputFlags =
                    ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags, isServer: false);
                uint outputFlags;
                bool isNtlmUsed;

                if (channelBinding != null)
                {
                    // If a TLS channel binding token (cbt) is available then get the pointer
                    // to the application specific data.
                    int appDataOffset = Marshal.SizeOf <SecChannelBindings>();
                    Debug.Assert(appDataOffset < channelBinding.Size);
                    IntPtr cbtAppData     = channelBinding.DangerousGetHandle() + appDataOffset;
                    int    cbtAppDataSize = channelBinding.Size - appDataOffset;
                    status = Interop.NetSecurityNative.InitSecContext(out minorStatus,
                                                                      credential.GssCredential,
                                                                      ref contextHandle,
                                                                      isNtlmOnly,
                                                                      cbtAppData,
                                                                      cbtAppDataSize,
                                                                      negoContext.TargetName,
                                                                      (uint)inputFlags,
                                                                      incomingBlob,
                                                                      ref token,
                                                                      out outputFlags,
                                                                      out isNtlmUsed);
                }
                else
                {
                    status = Interop.NetSecurityNative.InitSecContext(out minorStatus,
                                                                      credential.GssCredential,
                                                                      ref contextHandle,
                                                                      isNtlmOnly,
                                                                      negoContext.TargetName,
                                                                      (uint)inputFlags,
                                                                      incomingBlob,
                                                                      ref token,
                                                                      out outputFlags,
                                                                      out isNtlmUsed);
                }

                if ((status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE) &&
                    (status != Interop.NetSecurityNative.Status.GSS_S_CONTINUE_NEEDED))
                {
                    if (negoContext.GssContext.IsInvalid)
                    {
                        context.Dispose();
                    }

                    Interop.NetSecurityNative.GssApiException gex = new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Error(null, gex);
                    }
                    resultBuffer = Array.Empty <byte>();
                    return(new SecurityStatusPal(GetErrorCode(gex), gex));
                }

                resultBuffer = token.ToByteArray();

                if (status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        string protocol = isNtlmOnly ? "NTLM" : isNtlmUsed ? "SPNEGO-NTLM" : "SPNEGO-Kerberos";
                        NetEventSource.Info(context, $"actual protocol = {protocol}");
                    }

                    // Populate protocol used for authentication
                    negoContext.SetAuthenticationPackage(isNtlmUsed);
                }

                Debug.Assert(resultBuffer != null, "Unexpected null buffer returned by GssApi");
                outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(
                    (Interop.NetSecurityNative.GssFlags)outputFlags, isServer: false);

                SecurityStatusPalErrorCode errorCode = status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE ?
                                                       SecurityStatusPalErrorCode.OK :
                                                       SecurityStatusPalErrorCode.ContinueNeeded;
                return(new SecurityStatusPal(errorCode));
            }
            catch (Exception ex)
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Error(null, ex);
                }
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex));
            }
            finally
            {
                token.Dispose();

                // Save the inner context handle for further calls to NetSecurity
                //
                // For the first call `negoContext.GssContext` is invalid and we expect the
                // inital handle to be returned from InitSecContext. For any subsequent
                // call the handle should stay the same or it can be destroyed by the native
                // InitSecContext call.
                Debug.Assert(
                    negoContext.GssContext == contextHandle ||
                    negoContext.GssContext.IsInvalid ||
                    contextHandle.IsInvalid);
                negoContext.SetGssContext(contextHandle);
            }
        }
Пример #9
0
 public SecurityStatusPal(SecurityStatusPalErrorCode errorCode, Exception exception = null)
 {
     ErrorCode = errorCode;
     Exception = exception;
 }
Пример #10
0
        private static SecurityStatusPal EstablishSecurityContext(
            SafeFreeNegoCredentials credential,
            ref SafeDeleteContext context,
            bool isNtlm,
            string targetName,
            ContextFlagsPal inFlags,
            SecurityBuffer inputBuffer,
            SecurityBuffer outputBuffer,
            ref ContextFlagsPal outFlags)
        {
            Debug.Assert(!isNtlm, "EstablishSecurityContext: NTLM is not yet supported");

            if (context == null)
            {
                context = new SafeDeleteNegoContext(credential, targetName);
            }

            SafeDeleteNegoContext negoContext = (SafeDeleteNegoContext)context;

            try
            {
                Interop.NetSecurityNative.GssFlags inputFlags = ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(inFlags);
                uint outputFlags;
                SafeGssContextHandle contextHandle = negoContext.GssContext;
                bool done = Interop.GssApi.EstablishSecurityContext(
                    ref contextHandle,
                    credential.GssCredential,
                    isNtlm,
                    negoContext.TargetName,
                    inputFlags,
                    inputBuffer?.token,
                    out outputBuffer.token,
                    out outputFlags);

                Debug.Assert(outputBuffer.token != null, "Unexpected null buffer returned by GssApi");
                outputBuffer.size   = outputBuffer.token.Length;
                outputBuffer.offset = 0;

                outFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop((Interop.NetSecurityNative.GssFlags)outputFlags);

                // Save the inner context handle for further calls to NetSecurity
                Debug.Assert(negoContext.GssContext == null || contextHandle == negoContext.GssContext);
                if (null == negoContext.GssContext)
                {
                    negoContext.SetGssContext(contextHandle);
                }

                SecurityStatusPalErrorCode errorCode = done ? SecurityStatusPalErrorCode.CompleteNeeded : SecurityStatusPalErrorCode.ContinueNeeded;
                return(new SecurityStatusPal(errorCode));
            }
            catch (Exception ex)
            {
                //TODO (Issue #5890): Print exception until issue is fixed
                Debug.Write("Exception Caught. - " + ex);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("Exception Caught. - " + ex);
                }

                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, ex));
            }
        }
Пример #11
0
 public SecurityStatusPal(SecurityStatusPalErrorCode errorCode, Exception exception = null)
 {
     ErrorCode = errorCode;
     Exception = exception;
 }
Пример #12
0
 // This only works for context-destroying errors.
 internal static bool IsClientFault(SecurityStatusPalErrorCode error)
 {
     return error == SecurityStatusPalErrorCode.InvalidToken ||
         error == SecurityStatusPalErrorCode.CannotPack ||
         error == SecurityStatusPalErrorCode.QopNotSupported ||
         error == SecurityStatusPalErrorCode.NoCredentials ||
         error == SecurityStatusPalErrorCode.MessageAltered ||
         error == SecurityStatusPalErrorCode.OutOfSequence ||
         error == SecurityStatusPalErrorCode.IncompleteMessage ||
         error == SecurityStatusPalErrorCode.IncompleteCredentials ||
         error == SecurityStatusPalErrorCode.WrongPrincipal ||
         error == SecurityStatusPalErrorCode.TimeSkew ||
         error == SecurityStatusPalErrorCode.IllegalMessage ||
         error == SecurityStatusPalErrorCode.CertUnknown ||
         error == SecurityStatusPalErrorCode.AlgorithmMismatch ||
         error == SecurityStatusPalErrorCode.SecurityQosFailed ||
         error == SecurityStatusPalErrorCode.UnsupportedPreauth;
 }
Пример #13
0
 // This only works for context-destroying errors.
 internal static bool IsCredentialFailure(SecurityStatusPalErrorCode error)
 {
     return error == SecurityStatusPalErrorCode.LogonDenied ||
         error == SecurityStatusPalErrorCode.UnknownCredentials ||
         error == SecurityStatusPalErrorCode.NoImpersonation ||
         error == SecurityStatusPalErrorCode.NoAuthenticatingAuthority ||
         error == SecurityStatusPalErrorCode.UntrustedRoot ||
         error == SecurityStatusPalErrorCode.CertExpired ||
         error == SecurityStatusPalErrorCode.SmartcardLogonRequired ||
         error == SecurityStatusPalErrorCode.BadBinding;
 }
Пример #14
0
 // This only works for context-destroying errors.
 private HttpStatusCode HttpStatusFromSecurityStatus(SecurityStatusPalErrorCode statusErrorCode)
 {
     if (IsCredentialFailure(statusErrorCode))
     {
         return HttpStatusCode.Unauthorized;
     }
     if (IsClientFault(statusErrorCode))
     {
         return HttpStatusCode.BadRequest;
     }
     return HttpStatusCode.InternalServerError;
 }
Пример #15
0
        private static Interop.SecurityStatus GetInteropFromSecurityStatusPal(SecurityStatusPalErrorCode status)
        {
            switch (status)
            {
            case SecurityStatusPalErrorCode.NotSet:
                Debug.Fail("SecurityStatus NotSet");
                throw new InternalException();

            case SecurityStatusPalErrorCode.OK:
                return(Interop.SecurityStatus.OK);

            case SecurityStatusPalErrorCode.ContinueNeeded:
                return(Interop.SecurityStatus.ContinueNeeded);

            case SecurityStatusPalErrorCode.CompleteNeeded:
                return(Interop.SecurityStatus.CompleteNeeded);

            case SecurityStatusPalErrorCode.CompAndContinue:
                return(Interop.SecurityStatus.CompAndContinue);

            case SecurityStatusPalErrorCode.ContextExpired:
                return(Interop.SecurityStatus.ContextExpired);

            case SecurityStatusPalErrorCode.CredentialsNeeded:
                return(Interop.SecurityStatus.CredentialsNeeded);

            case SecurityStatusPalErrorCode.Renegotiate:
                return(Interop.SecurityStatus.Renegotiate);

            case SecurityStatusPalErrorCode.OutOfMemory:
                return(Interop.SecurityStatus.OutOfMemory);

            case SecurityStatusPalErrorCode.InvalidHandle:
                return(Interop.SecurityStatus.InvalidHandle);

            case SecurityStatusPalErrorCode.Unsupported:
                return(Interop.SecurityStatus.Unsupported);

            case SecurityStatusPalErrorCode.TargetUnknown:
                return(Interop.SecurityStatus.TargetUnknown);

            case SecurityStatusPalErrorCode.InternalError:
                return(Interop.SecurityStatus.InternalError);

            case SecurityStatusPalErrorCode.PackageNotFound:
                return(Interop.SecurityStatus.PackageNotFound);

            case SecurityStatusPalErrorCode.NotOwner:
                return(Interop.SecurityStatus.NotOwner);

            case SecurityStatusPalErrorCode.CannotInstall:
                return(Interop.SecurityStatus.CannotInstall);

            case SecurityStatusPalErrorCode.InvalidToken:
                return(Interop.SecurityStatus.InvalidToken);

            case SecurityStatusPalErrorCode.CannotPack:
                return(Interop.SecurityStatus.CannotPack);

            case SecurityStatusPalErrorCode.QopNotSupported:
                return(Interop.SecurityStatus.QopNotSupported);

            case SecurityStatusPalErrorCode.NoImpersonation:
                return(Interop.SecurityStatus.NoImpersonation);

            case SecurityStatusPalErrorCode.LogonDenied:
                return(Interop.SecurityStatus.LogonDenied);

            case SecurityStatusPalErrorCode.UnknownCredentials:
                return(Interop.SecurityStatus.UnknownCredentials);

            case SecurityStatusPalErrorCode.NoCredentials:
                return(Interop.SecurityStatus.NoCredentials);

            case SecurityStatusPalErrorCode.MessageAltered:
                return(Interop.SecurityStatus.MessageAltered);

            case SecurityStatusPalErrorCode.OutOfSequence:
                return(Interop.SecurityStatus.OutOfSequence);

            case SecurityStatusPalErrorCode.NoAuthenticatingAuthority:
                return(Interop.SecurityStatus.NoAuthenticatingAuthority);

            case SecurityStatusPalErrorCode.IncompleteMessage:
                return(Interop.SecurityStatus.IncompleteMessage);

            case SecurityStatusPalErrorCode.IncompleteCredentials:
                return(Interop.SecurityStatus.IncompleteCredentials);

            case SecurityStatusPalErrorCode.BufferNotEnough:
                return(Interop.SecurityStatus.BufferNotEnough);

            case SecurityStatusPalErrorCode.WrongPrincipal:
                return(Interop.SecurityStatus.WrongPrincipal);

            case SecurityStatusPalErrorCode.TimeSkew:
                return(Interop.SecurityStatus.TimeSkew);

            case SecurityStatusPalErrorCode.UntrustedRoot:
                return(Interop.SecurityStatus.UntrustedRoot);

            case SecurityStatusPalErrorCode.IllegalMessage:
                return(Interop.SecurityStatus.IllegalMessage);

            case SecurityStatusPalErrorCode.CertUnknown:
                return(Interop.SecurityStatus.CertUnknown);

            case SecurityStatusPalErrorCode.CertExpired:
                return(Interop.SecurityStatus.CertExpired);

            case SecurityStatusPalErrorCode.AlgorithmMismatch:
                return(Interop.SecurityStatus.AlgorithmMismatch);

            case SecurityStatusPalErrorCode.SecurityQosFailed:
                return(Interop.SecurityStatus.SecurityQosFailed);

            case SecurityStatusPalErrorCode.SmartcardLogonRequired:
                return(Interop.SecurityStatus.SmartcardLogonRequired);

            case SecurityStatusPalErrorCode.UnsupportedPreauth:
                return(Interop.SecurityStatus.UnsupportedPreauth);

            case SecurityStatusPalErrorCode.BadBinding:
                return(Interop.SecurityStatus.BadBinding);

            default:
                Debug.Fail("Unknown Interop.SecurityStatus value: " + status);
                throw new InternalException();
            }
        }