public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions) : base(credential) { Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { unsafe { _readCallback = ReadFromConnection; _writeCallback = WriteToConnection; } _sslContext = CreateSslContext(credential, sslAuthenticationOptions.IsServer); int osStatus = Interop.AppleCrypto.SslSetIoCallbacks( _sslContext, _readCallback, _writeCallback); if (osStatus != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } }
private static SafeSslHandle CreateSslContext(SafeFreeSslCredentials credential) { if (credential.CertificateContext == null) { return(Interop.AndroidCrypto.SSLStreamCreate()); } SslStreamCertificateContext context = credential.CertificateContext; X509Certificate2 cert = context.Certificate; Debug.Assert(context.Certificate.HasPrivateKey); PAL_KeyAlgorithm algorithm; byte[] keyBytes; using (AsymmetricAlgorithm key = GetPrivateKeyAlgorithm(cert, out algorithm)) { keyBytes = key.ExportPkcs8PrivateKey(); } IntPtr[] ptrs = new IntPtr[context.IntermediateCertificates.Length + 1]; ptrs[0] = cert.Handle; for (int i = 0; i < context.IntermediateCertificates.Length; i++) { ptrs[i + 1] = context.IntermediateCertificates[i].Handle; } return(Interop.AndroidCrypto.SSLStreamCreateWithCertificates(keyBytes, algorithm, ptrs)); }
private static void InitializeSslContext( SafeSslHandle handle, Interop.AndroidCrypto.SSLReadCallback readCallback, Interop.AndroidCrypto.SSLWriteCallback writeCallback, SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions) { bool isServer = authOptions.IsServer; if (authOptions.ApplicationProtocols != null || authOptions.CipherSuitesPolicy != null || credential.Protocols != SslProtocols.None || (isServer && authOptions.RemoteCertRequired)) { // TODO: [AndroidCrypto] Handle non-system-default options throw new NotImplementedException(nameof(SafeDeleteSslContext)); } Interop.AndroidCrypto.SSLStreamInitialize(handle, isServer, readCallback, writeCallback, InitialBufferSize); if (!isServer && !string.IsNullOrEmpty(authOptions.TargetHost)) { Interop.AndroidCrypto.SSLStreamConfigureParameters(handle, authOptions.TargetHost); } }
private unsafe void InitializeSslContext( SafeSslHandle handle, SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions) { switch (credential.Policy) { case EncryptionPolicy.RequireEncryption: #pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete case EncryptionPolicy.AllowNoEncryption: break; #pragma warning restore SYSLIB0040 default: throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, credential.Policy)); } bool isServer = authOptions.IsServer; if (authOptions.CipherSuitesPolicy != null) { // TODO: [AndroidCrypto] Handle non-system-default options throw new NotImplementedException(nameof(SafeDeleteSslContext)); } // Make sure the class instance is associated to the session and is provided // in the Read/Write callback connection parameter IntPtr managedContextHandle = GCHandle.ToIntPtr(GCHandle.Alloc(this, GCHandleType.Weak)); Interop.AndroidCrypto.SSLStreamInitialize(handle, isServer, managedContextHandle, &ReadFromConnection, &WriteToConnection, InitialBufferSize); if (credential.Protocols != SslProtocols.None) { SslProtocols protocolsToEnable = credential.Protocols & s_supportedSslProtocols.Value; if (protocolsToEnable == 0) { throw new PlatformNotSupportedException(SR.Format(SR.net_security_sslprotocol_notsupported, credential.Protocols)); } (int minIndex, int maxIndex) = protocolsToEnable.ValidateContiguous(s_orderedSslProtocols); Interop.AndroidCrypto.SSLStreamSetEnabledProtocols(handle, s_orderedSslProtocols.AsSpan(minIndex, maxIndex - minIndex + 1)); } if (authOptions.ApplicationProtocols != null && authOptions.ApplicationProtocols.Count != 0 && Interop.AndroidCrypto.SSLSupportsApplicationProtocolsConfiguration()) { // Set application protocols if the platform supports it. Otherwise, we will silently ignore the option. Interop.AndroidCrypto.SSLStreamSetApplicationProtocols(handle, authOptions.ApplicationProtocols); } if (isServer && authOptions.RemoteCertRequired) { Interop.AndroidCrypto.SSLStreamRequestClientAuthentication(handle); } if (!isServer && !string.IsNullOrEmpty(authOptions.TargetHost)) { Interop.AndroidCrypto.SSLStreamSetTargetHost(handle, authOptions.TargetHost); } }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions) : base(credential) { Debug.Assert((credential != null) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); _sslContext = new SafeSslHandle(); throw new NotImplementedException(nameof(SafeDeleteSslContext)); }
private static void InitializeSslContext( SafeSslHandle handle, Interop.AndroidCrypto.SSLReadCallback readCallback, Interop.AndroidCrypto.SSLWriteCallback writeCallback, SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions) { switch (credential.Policy) { case EncryptionPolicy.RequireEncryption: case EncryptionPolicy.AllowNoEncryption: break; default: throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, credential.Policy)); } bool isServer = authOptions.IsServer; if (authOptions.CipherSuitesPolicy != null) { // TODO: [AndroidCrypto] Handle non-system-default options throw new NotImplementedException(nameof(SafeDeleteSslContext)); } Interop.AndroidCrypto.SSLStreamInitialize(handle, isServer, readCallback, writeCallback, InitialBufferSize); if (credential.Protocols != SslProtocols.None) { ; SslProtocols protocolsToEnable = credential.Protocols & s_supportedSslProtocols.Value; if (protocolsToEnable == 0) { throw new PlatformNotSupportedException(SR.Format(SR.net_security_sslprotocol_notsupported, credential.Protocols)); } (int minIndex, int maxIndex) = protocolsToEnable.ValidateContiguous(s_orderedSslProtocols); Interop.AndroidCrypto.SSLStreamSetEnabledProtocols(handle, s_orderedSslProtocols.AsSpan(minIndex, maxIndex - minIndex + 1)); } if (authOptions.ApplicationProtocols != null && authOptions.ApplicationProtocols.Count != 0 && Interop.AndroidCrypto.SSLSupportsApplicationProtocolsConfiguration()) { // Set application protocols if the platform supports it. Otherwise, we will silently ignore the option. Interop.AndroidCrypto.SSLStreamSetApplicationProtocols(handle, authOptions.ApplicationProtocols); } if (isServer && authOptions.RemoteCertRequired) { Interop.AndroidCrypto.SSLStreamRequestClientAuthentication(handle); } if (!isServer && !string.IsNullOrEmpty(authOptions.TargetHost)) { Interop.AndroidCrypto.SSLStreamSetTargetHost(handle, authOptions.TargetHost); } }
private static SafeSslHandle CreateSslContext(SafeFreeSslCredentials credential, bool isServer) { switch (credential.Policy) { case EncryptionPolicy.RequireEncryption: #pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete case EncryptionPolicy.AllowNoEncryption: // SecureTransport doesn't allow TLS_NULL_NULL_WITH_NULL, but // since AllowNoEncryption intersect OS-supported isn't nothing, // let it pass. break; #pragma warning restore SYSLIB0040 default: throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, credential.Policy)); } SafeSslHandle sslContext = Interop.AppleCrypto.SslCreateContext(isServer ? 1 : 0); try { if (sslContext.IsInvalid) { // This is as likely as anything. No error conditions are defined for // the OS function, and our shim only adds a NULL if isServer isn't a normalized bool. throw new OutOfMemoryException(); } // Let None mean "system default" if (credential.Protocols != SslProtocols.None) { SetProtocols(sslContext, credential.Protocols); } if (credential.CertificateContext != null) { SetCertificate(sslContext, credential.CertificateContext); } Interop.AppleCrypto.SslBreakOnCertRequested(sslContext, true); Interop.AppleCrypto.SslBreakOnServerAuth(sslContext, true); Interop.AppleCrypto.SslBreakOnClientAuth(sslContext, true); } catch { sslContext.Dispose(); throw; } return(sslContext); }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions) : base(credential) { Debug.Assert((credential != null) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { _sslContext = CreateSslContext(credential); InitializeSslContext(_sslContext, credential, authOptions); } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions) : base(credential) { Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { unsafe { _readCallback = ReadFromConnection; _writeCallback = WriteToConnection; } _sslContext = CreateSslContext(credential, sslAuthenticationOptions.IsServer); int osStatus = Interop.AppleCrypto.SslSetIoCallbacks( _sslContext, _readCallback, _writeCallback); if (osStatus != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } if (sslAuthenticationOptions.ApplicationProtocols != null) { // On OSX coretls supports only client side. For server, we will silently ignore the option. if (!sslAuthenticationOptions.IsServer) { Interop.AppleCrypto.SslCtxSetAlpnProtos(_sslContext, sslAuthenticationOptions.ApplicationProtocols); } } } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions) : base(credential) { Debug.Assert((credential != null) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { unsafe { _readCallback = ReadFromConnection; _writeCallback = WriteToConnection; } _sslContext = CreateSslContext(credential); InitializeSslContext(_sslContext, _readCallback, _writeCallback, credential, authOptions); } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions) : base(credential) { Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { int osStatus; _sslContext = CreateSslContext(credential, sslAuthenticationOptions.IsServer); // Make sure the class instance is associated to the session and is provided // in the Read/Write callback connection parameter SslSetConnection(_sslContext); unsafe { osStatus = Interop.AppleCrypto.SslSetIoCallbacks( _sslContext, &ReadFromConnection, &WriteToConnection); } if (osStatus != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } if (sslAuthenticationOptions.CipherSuitesPolicy != null) { uint[] tlsCipherSuites = sslAuthenticationOptions.CipherSuitesPolicy.Pal.TlsCipherSuites; unsafe { fixed(uint *cipherSuites = tlsCipherSuites) { osStatus = Interop.AppleCrypto.SslSetEnabledCipherSuites( _sslContext, cipherSuites, tlsCipherSuites.Length); if (osStatus != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } } } } if (sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0) { // On OSX coretls supports only client side. For server, we will silently ignore the option. if (!sslAuthenticationOptions.IsServer) { Interop.AppleCrypto.SslCtxSetAlpnProtos(_sslContext, sslAuthenticationOptions.ApplicationProtocols); } } } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } }
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions) : base(credential) { Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext"); try { int osStatus; _sslContext = CreateSslContext(credential, sslAuthenticationOptions.IsServer); // Make sure the class instance is associated to the session and is provided // in the Read/Write callback connection parameter SslSetConnection(_sslContext); unsafe { osStatus = Interop.AppleCrypto.SslSetIoCallbacks( _sslContext, &ReadFromConnection, &WriteToConnection); } if (osStatus != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } if (sslAuthenticationOptions.CipherSuitesPolicy != null) { uint[] tlsCipherSuites = sslAuthenticationOptions.CipherSuitesPolicy.Pal.TlsCipherSuites; unsafe { fixed(uint *cipherSuites = tlsCipherSuites) { osStatus = Interop.AppleCrypto.SslSetEnabledCipherSuites( _sslContext, cipherSuites, tlsCipherSuites.Length); if (osStatus != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } } } } if (sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0) { // On OSX coretls supports only client side. For server, we will silently ignore the option. if (!sslAuthenticationOptions.IsServer) { Interop.AppleCrypto.SslCtxSetAlpnProtos(_sslContext, sslAuthenticationOptions.ApplicationProtocols); } } } catch (Exception ex) { Debug.Write("Exception Caught. - " + ex); Dispose(); throw; } if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer) { Interop.AppleCrypto.SslSetTargetName(_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, true); } if (sslAuthenticationOptions.IsServer) { if (sslAuthenticationOptions.RemoteCertRequired) { Interop.AppleCrypto.SslSetAcceptClientCert(_sslContext); } if (sslAuthenticationOptions.CertificateContext?.Trust?._sendTrustInHandshake == true) { SslCertificateTrust trust = sslAuthenticationOptions.CertificateContext !.Trust !; X509Certificate2Collection certList = (trust._trustList ?? trust._store !.Certificates); Debug.Assert(certList != null, "certList != null"); Span <IntPtr> handles = certList.Count <= 256 ? stackalloc IntPtr[256] : new IntPtr[certList.Count]; for (int i = 0; i < certList.Count; i++) { handles[i] = certList[i].Handle; } Interop.AppleCrypto.SslSetCertificateAuthorities(_sslContext, handles.Slice(0, certList.Count), true); } } }