private static SecurityStatusPal HandshakeInternal( SafeFreeCredentials credential, ref SafeDeleteSslContext?context, ReadOnlySpan <byte> inputBuffer, ref byte[]?outputBuffer, SslAuthenticationOptions sslAuthenticationOptions, SelectClientCertificate?clientCertificateSelectionCallback) { try { SafeDeleteSslContext?sslContext = ((SafeDeleteSslContext?)context); if ((null == context) || context.IsInvalid) { sslContext = new SafeDeleteSslContext(sslAuthenticationOptions); context = sslContext; } if (inputBuffer.Length > 0) { sslContext !.Write(inputBuffer); } SafeSslHandle sslHandle = sslContext !.SslContext; SecurityStatusPal status = PerformHandshake(sslHandle); if (status.ErrorCode == SecurityStatusPalErrorCode.CredentialsNeeded && clientCertificateSelectionCallback != null) { X509Certificate2?clientCertificate = clientCertificateSelectionCallback(out bool _); if (clientCertificate != null) { sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(clientCertificate); SafeDeleteSslContext.SetCertificate(sslContext.SslContext, sslAuthenticationOptions.CertificateContext); } // We either got certificate or we can proceed without it. It is up to the server to decide if either is OK. status = PerformHandshake(sslHandle); } outputBuffer = sslContext.ReadPendingWrites(); return(status); } catch (Exception exc) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }
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 ((null == context) || context.IsInvalid) { sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials) !, sslAuthenticationOptions); context = sslContext; if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost)) { Debug.Assert(!sslAuthenticationOptions.IsServer, "targetName should not be set for server-side handshakes"); Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost); } if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired) { Interop.AppleCrypto.SslSetAcceptClientCert(sslContext.SslContext); } } if (inputBuffer.Length > 0) { sslContext !.Write(inputBuffer); } SafeSslHandle sslHandle = sslContext !.SslContext; SecurityStatusPal status = PerformHandshake(sslHandle); outputBuffer = sslContext.ReadPendingWrites(); return(status); } catch (Exception exc) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }
public static SecurityStatusPal AcceptSecurityContext( ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { if (inputBuffers != null) { Debug.Assert(inputBuffers.Length == 2); Debug.Assert(inputBuffers[1].token == null); return(HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, sslAuthenticationOptions)); } else { return(HandshakeInternal(credential, ref context, inputBuffer: null, outputBuffer, sslAuthenticationOptions)); } }
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)); } }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions) : base(credential) { Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { _sslContext = Interop.OpenSsl.AllocateSslContext( credential.Protocols, credential.CertHandle, credential.CertKeyHandle, credential.Policy, sslAuthenticationOptions); } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } }
private SslAuthenticationOptions CreateAuthenticationOptions(SslServerAuthenticationOptions sslServerAuthenticationOptions) { if (sslServerAuthenticationOptions.ServerCertificate == null && sslServerAuthenticationOptions.ServerCertificateSelectionCallback == null) { throw new ArgumentNullException(nameof(sslServerAuthenticationOptions.ServerCertificate)); } if (sslServerAuthenticationOptions.ServerCertificate != null && sslServerAuthenticationOptions.ServerCertificateSelectionCallback != null) { throw new InvalidOperationException(SR.Format(SR.net_conflicting_options, nameof(ServerCertificateSelectionCallback))); } var authOptions = new SslAuthenticationOptions(sslServerAuthenticationOptions); _userServerCertificateSelectionCallback = sslServerAuthenticationOptions.ServerCertificateSelectionCallback; authOptions.ServerCertSelectionDelegate = _userServerCertificateSelectionCallback == null ? null : new ServerCertSelectionCallback(ServerCertSelectionCallbackWrapper); authOptions.CertValidationDelegate = _certValidationDelegate; return(authOptions); }
public static SecurityBuffer[] GetIncomingSecurityBuffers(SslAuthenticationOptions options, ref SecurityBuffer incomingSecurity) { SecurityBuffer alpnBuffer = null; SecurityBuffer[] incomingSecurityBuffers = null; if (options.ApplicationProtocols != null && options.ApplicationProtocols.Count != 0) { byte[] alpnBytes = SslStreamPal.ConvertAlpnProtocolListToByteArray(options.ApplicationProtocols); alpnBuffer = new SecurityBuffer(alpnBytes, 0, alpnBytes.Length, SecurityBufferType.SECBUFFER_APPLICATION_PROTOCOLS); } if (incomingSecurity != null) { if (alpnBuffer != null) { incomingSecurityBuffers = new SecurityBuffer[] { incomingSecurity, new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY), alpnBuffer }; } else { incomingSecurityBuffers = new SecurityBuffer[] { incomingSecurity, new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY) }; } } else if (alpnBuffer != null) { incomingSecurity = alpnBuffer; } return(incomingSecurityBuffers); }
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Debug.Assert(inputBuffers.Length == 2); Debug.Assert(inputBuffers[1].token == null); return(HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, sslAuthenticationOptions)); }
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Debug.Assert(!credential.IsInvalid); try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, sslAuthenticationOptions); } byte[] output = null; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, null, 0, 0, out output, out outputSize); } else { done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize); } outputBuffer.size = outputSize; outputBuffer.offset = 0; outputBuffer.token = outputSize > 0 ? output : null; return(new SecurityStatusPal(done ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded)); } catch (Exception exc) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { return(HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, sslAuthenticationOptions)); }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials?credential, ref SafeDeleteSslContext?context, ReadOnlySpan <byte> inputBuffer, ref byte[]?outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { return(HandshakeInternal(credential !, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions)); }
public static SecurityStatusPal Renegotiate(ref SafeFreeCredentials?credentialsHandle, ref SafeDeleteSslContext?context, SslAuthenticationOptions sslAuthenticationOptions, out byte[]?outputBuffer) { throw new PlatformNotSupportedException(); }
internal void ValidateCreateContext(SslAuthenticationOptions sslAuthenticationOptions) { }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteSslContext context, byte[] inputBuffer, int offset, int count, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Interop.SspiCli.ContextFlags unusedAttributes = default; ArraySegment <byte> input = inputBuffer != null ? new ArraySegment <byte>(inputBuffer, offset, count) : default; ThreeSecurityBuffers threeSecurityBuffers = default; SecurityBuffer? incomingSecurity = input.Array != null ? new SecurityBuffer(input.Array, input.Offset, input.Count, SecurityBufferType.SECBUFFER_TOKEN) : (SecurityBuffer?)null; Span <SecurityBuffer> inputBuffers = MemoryMarshal.CreateSpan(ref threeSecurityBuffers._item0, 3); GetIncomingSecurityBuffers(sslAuthenticationOptions, in incomingSecurity, ref inputBuffers); var resultBuffer = new SecurityBuffer(outputBuffer, SecurityBufferType.SECBUFFER_TOKEN); int errorCode = SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPISecureChannel, credentialsHandle, ref context, ServerRequiredFlags | (sslAuthenticationOptions.RemoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero), Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffers, ref resultBuffer, ref unusedAttributes); outputBuffer = resultBuffer.token; return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode)); }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, ArraySegment <byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { return(HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions)); }
private static void GetIncomingSecurityBuffers(SslAuthenticationOptions options, in SecurityBuffer?incomingSecurity, ref Span <SecurityBuffer> incomingSecurityBuffers)
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteSslContext context, ReadOnlySpan <byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Debug.Assert(!credential.IsInvalid); byte[] output = null; int outputSize = 0; try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, sslAuthenticationOptions); } bool done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer, out output, out outputSize); // When the handshake is done, and the context is server, check if the alpnHandle target was set to null during ALPN. // If it was, then that indicates ALPN failed, send failure. // We have this workaround, as openssl supports terminating handshake only from version 1.1.0, // whereas ALPN is supported from version 1.0.2. SafeSslHandle sslContext = ((SafeDeleteSslContext)context).SslContext; if (done && sslAuthenticationOptions.IsServer && sslAuthenticationOptions.ApplicationProtocols != null && sslContext.AlpnHandle.IsAllocated && sslContext.AlpnHandle.Target == null) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, Interop.OpenSsl.CreateSslException(SR.net_alpn_failed))); } outputBuffer = outputSize == 0 ? null : outputSize == output.Length ? output : new Span <byte>(output, 0, outputSize).ToArray(); return(new SecurityStatusPal(done ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded)); } catch (Exception exc) { // Even if handshake failed we may have Alert to sent. if (outputSize > 0) { outputBuffer = outputSize == output.Length ? output : new Span <byte>(output, 0, outputSize).ToArray(); } return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Debug.Assert(!credential.IsInvalid); try { if ((null == context) || context.IsInvalid) { context = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, sslAuthenticationOptions); } byte[] output = null; int outputSize; bool done; if (null == inputBuffer) { done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, null, 0, 0, out output, out outputSize); } else { done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, out output, out outputSize); } // When the handshake is done, and the context is server, check if the alpnHandle target was set to null during ALPN. // If it was, then that indiciates ALPN failed, send failure. // We have this workaround, as openssl supports terminating handshake only from version 1.1.0, // whereas ALPN is supported from version 1.0.2. SafeSslHandle sslContext = ((SafeDeleteSslContext)context).SslContext; if (done && sslAuthenticationOptions.IsServer && sslAuthenticationOptions.ApplicationProtocols != null && sslContext.AlpnHandle.IsAllocated && sslContext.AlpnHandle.Target == null) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, Interop.OpenSsl.CreateSslException(SR.net_alpn_failed))); } outputBuffer.size = outputSize; outputBuffer.offset = 0; outputBuffer.token = outputSize > 0 ? output : null; return(new SecurityStatusPal(done ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded)); } catch (Exception exc) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials?credentialsHandle, ref SafeDeleteSslContext?context, ReadOnlySpan <byte> inputBuffer, ref byte[]?outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Interop.SspiCli.ContextFlags unusedAttributes = default; InputSecurityBuffers inputBuffers = default; inputBuffers.SetNextBuffer(new InputSecurityBuffer(inputBuffer, SecurityBufferType.SECBUFFER_TOKEN)); inputBuffers.SetNextBuffer(new InputSecurityBuffer(default, SecurityBufferType.SECBUFFER_EMPTY));
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, ReadOnlySpan <byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { return(HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions)); }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags); int errorCode = SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPISecureChannel, credentialsHandle, ref context, ServerRequiredFlags | (sslAuthenticationOptions.RemoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero), Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffers, outputBuffer, ref unusedAttributes); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode)); }
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, ArraySegment <byte> input, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Interop.SspiCli.ContextFlags unusedAttributes = default; ThreeSecurityBuffers threeSecurityBuffers = default; SecurityBuffer? incomingSecurity = input.Array != null ? new SecurityBuffer(input.Array, input.Offset, input.Count, SecurityBufferType.SECBUFFER_TOKEN) : (SecurityBuffer?)null; Span <SecurityBuffer> inputBuffers = MemoryMarshal.CreateSpan(ref threeSecurityBuffers._item0, 3); GetIncomingSecurityBuffers(sslAuthenticationOptions, in incomingSecurity, ref inputBuffers); var resultBuffer = new SecurityBuffer(outputBuffer, SecurityBufferType.SECBUFFER_TOKEN); int errorCode = SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPISecureChannel, ref credentialsHandle, ref context, targetName, RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation, Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffers, ref resultBuffer, ref unusedAttributes); outputBuffer = resultBuffer.token; return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode)); }
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags); int errorCode = SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPISecureChannel, credentialsHandle, ref context, targetName, RequiredFlags | Interop.SspiCli.ContextFlags.InitManualCredValidation, Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP, inputBuffers, outputBuffer, ref unusedAttributes); return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode)); }
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, byte[] inputBuffer, int offset, int count, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { return(HandshakeInternal(credential, ref context, new ReadOnlySpan <byte>(inputBuffer, offset, count), ref outputBuffer, sslAuthenticationOptions)); }
public static SafeFreeCredentials?AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions) { return(null); }
private void ValidateCreateContext(SslAuthenticationOptions sslAuthenticationOptions) { }
private static SecurityStatusPal HandshakeInternal( SecureChannel secureChannel, SafeFreeCredentials credential, ref SafeDeleteSslContext?context, ReadOnlySpan <byte> inputBuffer, ref byte[]?outputBuffer, SslAuthenticationOptions sslAuthenticationOptions) { Debug.Assert(!credential.IsInvalid); try { SafeDeleteSslContext?sslContext = ((SafeDeleteSslContext?)context); if ((null == context) || context.IsInvalid) { sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials) !, sslAuthenticationOptions); context = sslContext; if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer) { Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost); } if (sslAuthenticationOptions.CertificateContext == null && sslAuthenticationOptions.CertSelectionDelegate != null) { // certificate was not provided but there is user callback. We can break handshake if server asks for certificate // and we can try to get it based on remote certificate and trusted issuers. Interop.AppleCrypto.SslBreakOnCertRequested(sslContext.SslContext, true); } if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired) { Interop.AppleCrypto.SslSetAcceptClientCert(sslContext.SslContext); } } if (inputBuffer.Length > 0) { sslContext !.Write(inputBuffer); } SafeSslHandle sslHandle = sslContext !.SslContext; SecurityStatusPal status = PerformHandshake(sslHandle); if (status.ErrorCode == SecurityStatusPalErrorCode.CredentialsNeeded) { X509Certificate2?clientCertificate = secureChannel.SelectClientCertificate(out _); if (clientCertificate != null) { sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(clientCertificate); SafeDeleteSslContext.SetCertificate(sslContext.SslContext, sslAuthenticationOptions.CertificateContext); } // We either got certificate or we can proceed without it. It is up to the server to decide if either is OK. status = PerformHandshake(sslHandle); } outputBuffer = sslContext.ReadPendingWrites(); return(status); } catch (Exception exc) { return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc)); } }