Secure WebSocket fails CBLite C# .NET

Hi!

I have my sync_gateway set up properly with an SSL certificate here:

https://flashtothetop.com:4984/prodigy/

However, my Xamarin app won’t connect to the gateway via secure Websockets. Here is the relevant code:

 public CouchbaseRepository (string Login = null, string Password = null)
        {
            var defaultDirectory = Service.GetInstance<IDefaultDirectoryResolver>().DefaultDirectory() ;
            var databaseConfig = new DatabaseConfiguration
            {
                Directory = defaultDirectory
            } ;
            _db = new Database("prodigy", databaseConfig) ;

// THE CONNECTION LINE
            var targetUrlEndpoint = new URLEndpoint(new System.Uri("wss://flashtothetop.com:4984/prodigy/"));
// *******************
            var configuration = new ReplicatorConfiguration(_db, targetUrlEndpoint)
            {
                ReplicatorType = ReplicatorType.PushAndPull,
                Continuous = true
            };

            if (Login != null && Password != null)
            {
                configuration.Authenticator = new BasicAuthenticator(Login, Password);
Console.WriteLine($"Couchbase Login: {Login}   Password: {Password}");
            }
            _replicator = new Replicator(configuration);
            _replicatorListenerToken = _replicator.AddChangeListener(OnReplicatorUpdate);
            _InitialReplicationComplete = false;
            _replicator.Start();
            InitialReplication = Task.Run(() =>
            {
Console.WriteLine($"Couchbase InitialReplication Start");
                while (_InitialReplicationComplete == false) { ; }
Console.WriteLine($"Couchbase InitialReplication Done");
            });
        }



And here this is the console output:

CouchbaseLite: All documents synced
Couchbase InitialReplication Start
Thread finished:  #4
Thread started:  #9
Thread started: <Thread Pool> #10
Loaded assembly: /data/data/com.davidbergan.flashtothetop/files/.__override__/System.Xml.dll [External]
The thread 0x4 has exited with code 0 (0x0).
The thread 0x9 has exited with code 0 (0x0).
Thread finished:  #9
Thread started: <Thread Pool> #11
Thread started: <Thread Pool> #12
Thread started: <Thread Pool> #13
Thread started:  #14
Thread started:  #15
Thread started:  #16
Thread started:  #17
Loaded assembly: /data/data/com.davidbergan.flashtothetop/files/.__override__/System.Runtime.Serialization.dll [External]
Loaded assembly: /data/data/com.davidbergan.flashtothetop/files/.__override__/System.ServiceModel.Internals.dll [External]
Thread finished:  #14
The thread 0xe has exited with code 0 (0x0).
[CouchbaseLite] [Thread Pool Worker]| [Replicator] (WebSocketWrapper) [Thread Pool Worker (15)] Error validating TLS chain: RemoteCertificateChainErrors
Thread started:  #18
Thread started:  #19
Thread finished:  #18
[CouchbaseLite] [21]| [Network] {N8litecore4repl12C4SocketImplE#1} WebSocket failed to connect! (reason=Network error 8)
Thread started:  #20
[CouchbaseLite] [22]| [Replicator] {Repl#2} Got LiteCore error: Network error 8 "Certificate verification failed (RemoteCertificateChainErrors)"
Thread finished:  #19
Thread started:  #21
CouchbaseLite: Connecting to Sync Gateway
CouchbaseLite: All documents synced



And here is what the Sync Gateway says:

2021/10/05 21:59:41 http: TLS handshake error from 184.83.42.94:58843: EOF



And here is WireShark:

No.	Time	Source	Destination	Protocol	Length	Info
33	3.333205	192.168.1.4	35.238.130.163	TCP	66	63072 → 4984 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
34	3.371395	35.238.130.163	192.168.1.4	TCP	66	4984 → 63072 [SYN, ACK] Seq=0 Ack=1 Win=65320 Len=0 MSS=1420 SACK_PERM=1 WS=128
35	3.371474	192.168.1.4	35.238.130.163	TCP	54	63072 → 4984 [ACK] Seq=1 Ack=1 Win=262656 Len=0
36	3.385335	192.168.1.4	35.238.130.163	TLSv1.2	241	Client Hello
37	3.422390	35.238.130.163	192.168.1.4	TCP	60	4984 → 63072 [ACK] Seq=1 Ack=188 Win=65152 Len=0
38	3.424809	35.238.130.163	192.168.1.4	TLSv1.2	1474	Server Hello
39	3.424809	35.238.130.163	192.168.1.4	TCP	1474	4984 → 63072 [ACK] Seq=1421 Ack=188 Win=65152 Len=1420 [TCP segment of a reassembled PDU]
40	3.424853	192.168.1.4	35.238.130.163	TCP	54	63072 → 4984 [ACK] Seq=188 Ack=2841 Win=262656 Len=0
41	3.425632	35.238.130.163	192.168.1.4	TLSv1.2	1474	Certificate [TCP segment of a reassembled PDU]
42	3.425632	35.238.130.163	192.168.1.4	TLSv1.2	197	Server Key Exchange, Server Hello Done
43	3.425671	192.168.1.4	35.238.130.163	TCP	54	63072 → 4984 [ACK] Seq=188 Ack=4404 Win=262656 Len=0
44	3.433165	192.168.1.4	35.238.130.163	TCP	54	63072 → 4984 [FIN, ACK] Seq=188 Ack=4404 Win=262656 Len=0
45	3.471369	35.238.130.163	192.168.1.4	TCP	60	4984 → 63072 [FIN, ACK] Seq=4404 Ack=189 Win=65152 Len=0
46	3.471426	192.168.1.4	35.238.130.163	TCP	54	63072 → 4984 [ACK] Seq=189 Ack=4405 Win=262656 Len=0
69	5.762030	192.168.1.4	35.238.130.163	TCP	66	63075 → 4984 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
70	5.798553	35.238.130.163	192.168.1.4	TCP	66	4984 → 63075 [SYN, ACK] Seq=0 Ack=1 Win=65320 Len=0 MSS=1420 SACK_PERM=1 WS=128
71	5.798615	192.168.1.4	35.238.130.163	TCP	54	63075 → 4984 [ACK] Seq=1 Ack=1 Win=262656 Len=0
72	5.810263	192.168.1.4	35.238.130.163	TLSv1	241	Client Hello
73	5.849598	35.238.130.163	192.168.1.4	TCP	60	4984 → 63075 [ACK] Seq=1 Ack=188 Win=65152 Len=0
74	5.851545	35.238.130.163	192.168.1.4	TLSv1.2	1474	Server Hello
75	5.851613	35.238.130.163	192.168.1.4	TCP	1474	4984 → 63075 [ACK] Seq=1421 Ack=188 Win=65152 Len=1420 [TCP segment of a reassembled PDU]
76	5.851641	192.168.1.4	35.238.130.163	TCP	54	63075 → 4984 [ACK] Seq=188 Ack=2841 Win=262656 Len=0
77	5.852151	35.238.130.163	192.168.1.4	TLSv1.2	1474	Certificate [TCP segment of a reassembled PDU]
78	5.852151	35.238.130.163	192.168.1.4	TLSv1.2	197	Server Key Exchange, Server Hello Done
79	5.852187	192.168.1.4	35.238.130.163	TCP	54	63075 → 4984 [ACK] Seq=188 Ack=4404 Win=262656 Len=0
80	5.856790	192.168.1.4	35.238.130.163	TCP	54	63075 → 4984 [FIN, ACK] Seq=188 Ack=4404 Win=262656 Len=0
81	5.894193	35.238.130.163	192.168.1.4	TCP	60	4984 → 63075 [FIN, ACK] Seq=4404 Ack=189 Win=65152 Len=0
82	5.894239	192.168.1.4	35.238.130.163	TCP	54	63075 → 4984 [ACK] Seq=189 Ack=4405 Win=262656 Len=0
93	6.977324	35.238.130.163	192.168.1.4	TCP	1474	443 → 57829 [ACK] Seq=1 Ack=1 Win=737 Len=1420 [TCP segment of a reassembled PDU]
94	6.977324	35.238.130.163	192.168.1.4	TCP	1474	443 → 57829 [ACK] Seq=1421 Ack=1 Win=737 Len=1420 [TCP segment of a reassembled PDU]
95	6.977436	192.168.1.4	35.238.130.163	TCP	54	57829 → 443 [ACK] Seq=1 Ack=2841 Win=1026 Len=0
96	6.977448	35.238.130.163	192.168.1.4	TCP	1474	443 → 57829 [ACK] Seq=2841 Ack=1 Win=737 Len=1420 [TCP segment of a reassembled PDU]
97	6.977448	35.238.130.163	192.168.1.4	TLSv1.2	827	Application Data
98	6.977478	192.168.1.4	35.238.130.163	TCP	54	57829 → 443 [ACK] Seq=1 Ack=5034 Win=1026 Len=0
99	6.980382	192.168.1.4	35.238.130.163	TLSv1.2	890	Application Data
102	7.017850	35.238.130.163	192.168.1.4	TCP	60	443 → 57829 [ACK] Seq=5034 Ack=837 Win=750 Len=0



End result: because of this error, there’s no replication between the Android device and Couchbase Server.

My C# code used to work before the SSL certificates (the connection line was ws:// instead of wss://), however, the Android SDK now requires that all transactions go through SSL. As far as I can tell, my certificate is set up correctly since it works just with https:// from a browser or Postman.

What does “WebSocket failed to connect! (reason=Network error 8)” refer to and how can I fix it?

Kind regards,
David

As for “what does it mean?” that part is in the output you shared:

[CouchbaseLite] [Thread Pool Worker]| [Replicator] (WebSocketWrapper) [Thread Pool Worker (15)] Error validating TLS chain: RemoteCertificateChainErrors

The first thing that comes to mind is that your Android device doesn’t have enough information to reconstruct the chain of trust (i.e. it is receiving a certificate that doesn’t map back in some way to one of its trusted CA). I also notice that you are using Let’s Encrypt and if you don’t already know, one of their roots expired at the end of September 2021, so that’s also something to double check on your device.

Thanks Jim!

However, I’m still banging my head against this error… I don’t see any reason for the Android device to close off the connection during the handshake. Attached is a zip with a successful handshake (https, TLS 1.3) and the unsuccessful (wss, TLS 1.2).

Is it possible that this has something to do with my .Net target framework or another setting? I’m using

.NET Standard 2.0
Android 11.0 (API Level 30 - R)
Couchbase.Lite 2.8.6

Another reason why I ask is because when I tried Certificate Pinning I couldn’t get my code to compile with either AcceptOnlySelfSignedServerCertificate or PinnedServerCertificate.

Kind regards,
David

FlashToTheTop TLS packets.zip (10.4 KB)

The packet trace is what I would expect if your Android side is not satisfied with the certificate. After the server finishes its hello, it moves to validate the certificate and finds that it cannot. I still think that your Android CA needs to be refreshed somehow though I am not familiar with the details of how to do that.

Is the fault in Android code or CB lite code? When it says “Got LiteCore error” it makes me think that CB Lite is the part that’s denying a valid certificate. What am I missing?

Kind regards,
David