CocoaMQTT iOS client cannot connect to a broker with TLS - swift

CocoaMQTT client is running on iOS15 with the SSL enabled as shown in this example. The cert_key.p12 file was merged from the client.crt and client.key files signed by the same (self-created) CA that was used for the MQTT server/broker certificate generation. The MQTT broker is configured to require client's certificate and use its CN as the username. The handshake does not go well - the log complains about the unknown certificate:
New connection from 192.168.1.87 on port 8883.
OpenSSL Error[0]: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown
Based on the above error research, the broker does not like the client's certificate, right? In fact, looking at the wireshark's log, it seems like the client does not send the certificate to the server. Is that something I need to enable in the App configuration? Does the Swift CocoaMQTT package even support this feature (provide the cert to the broker)?
EDIT:
I tried running a client with the same cert/key with paho mqtt implemented in python, which also allows to provide the client with the CA certificate, and everything runs ok:
Trying using the same client's cert/key in CocoaMQTT implemented in iOS15 shows the MQTT broker log error message as above and the fatal alert shows up the the wireshark log:
Initially, I thought that the sever did not like (or did not receive) the client's certificate, but that fatal alert package destination is port 8883. So now I tend to believe that it's the client, who does not like the server's certificate. This is expected if the client uses the pool of official CAs to verify the certificate instead of recognizing that its own certificate was issued by the same CA as the server's one. This is further confirmed by setting the allowUntrustCACertificate = true and seems like the handshake is suspended and no more communication occurs:
There's also a debug message on the client's side:
Call the SSL/TLS manually validating function
So it looks like the client will not continue the communication until this validation process occurs. As #Brits mentioned in his comment, there's a callback to validate the cert manually but it is implemented as a part of the delegate. I do see that there's a method mqtt.didReceiveTrust which I assume should be used for cert validation, and I wish to use the closures approach as stated on the README page as giving an example for the didReceiveMessage methond:
Now you can use closures instead of CocoaMQTTDelegate:
mqtt.didReceiveMessage = { mqtt, message, id in
print("Message received in topic \(message.topic) with payload \(message.string!)")
}
With a weak understanding of Swift Closures, I am not able to figure out how to make that function all, so the question now becomes: how to convert that function from the delegate definition into the closure?

Related

How can an IMAP connection fail with a certificate error when an SMTP connection with same credentials succeeds?

I am connecting to an HIE in two interfaces using Direct Messaging - one to send messages and one to retrieve messages. The first uses a protocol of SMTP connecting on port 587 without SSL/TLS and then issuing a STARTTLS. All outbound Direct messages goes to this protocol; the HIE forwards the messages to the designated recipient. This works 100% of the time.
The retrieval interface also uses Direct Messaging, but connects with IMAP protocol on port 993. SSL/TLS is used, but there is no STARTTLS issued. This used to work 100% of the time. Now it fails on every connect attempt.
The error message is:
[java:java:ERR /1:fr_RHIO_direct_2:--/--/---- --:--:--] Catch Execption:
[java:java:ERR /1:fr_RHIO_direct_2:--/--/---- --:--:--] javax.mail.MessagingException: com.ibm.jsse2.util.h: PKIX path building failed: com.ibm.security.cert.IBMCertPathBuilderException: unable to find valid certification path to requested target;
Last week both interfaces failed at the same time with this PKIX path building error. The HIE sent us an updated digital certificate. The old one was removed from the keystore and the new one was imported. Upon recycling of the interfaces, the SMTP sending interface was restored to working order. However the retrieving interface is still failing with the same error.
Both interfaces use the same keystore. The configuration screens for both interfaces include a "keystore validation" function - both validate successfully, proving the location of the keystore and its password are correct in both interfaces.
Before last week, both interfaces worked correctly. Now only one works. The HIE uses Mirth Mail.
How is it possible that the same certificate path is correct in one interface but incorrect in another?
That was the right direction. it turns out that we were the only client to use IMAP; everyone else uses XDR. They had forgotten what to do with the IMAP service when a certificate is replaced. They had to restart a service called DOVECOT. Thanks for looking.

Mitmproxy: Certification Errors with Upstream Server

I am trying to split up my Network traffic into two streams using Mitmproxy.
I therefore have one incoming proxy that accepts traffic from my IPhone and I am using two secondary Proxies to which the Traffic is forwarded. I start the three instances like this:
mitmproxy --mode upstream 127.0.0.1:8083 -s mitmRoot.py --ssl-insecure
mitmproxy --listen-port 8083 --ssl-insecure
mitmproxy --listen-port 8082 --ssl-insecure
I am using the following, very simple Python script to route the traffic:
class mitmRoot:
def request(self, flow: mitmproxy.http.HTTPFlow):
if "github.com" in str(flow.request.url):
flow.live.change_upstream_proxy_server(("localhost", 8082))
addons = [
mitmRoot()
]
Now everything works perfectly fine if I am using only one proxy without any upstream Proxy. I have installed the certificate on the Phone and I can open any website in the browser
However if I add the two upstream proxies I see start seeing certification errors,
mostly for IPhone related stuff:
clientdisconnect
clientconnect
Certificate verification error for gateway.icloud.com: self signed certificate in certificate chain (errno: 19, depth: 1)
Ignoring server verification error, continuing with connection
Client Handshake failed. The client may not trust the proxy's certificate for gateway.icloud.com.
Interestingly I can still establish connections to websites except the ones where I am switching the upstream server. So in this example I am not able to open github.com.
The input proxy now throws cert errors for github.com as well, while the upstream proxy that should be getting the traffic (the one on port 8082) does not see any traffic at all I also see some clientconnect/ clientdisconnect messages in the stream:
https://github.com/
clientconnect
clientconnect
Certificate verification error for github.com: self signed certificate in certificate chain (errno: 19, depth: 1)
Ignoring server verification error, continuing with connection
Certificate verification error for keyvalueservice.icloud.com: self signed certificate in certificate chain (errno: 19, depth: 1)
Ignoring server verification error, continuing with connection
Client Handshake failed. The client may not trust the proxy's certificate for keyvalueservice.icloud.com
I have tried different configuration options, for "--set add_upstream_certs_to_client=true" but so far I am not able to set this up right.
It seems like there is some kind of configuration issue but I don't yet see why it is happening.
Thank You for your help!

SSL_accept error in log while using Postfix

So I set up a mail server on my VPS with cyberpanel and I can send emails manually through rainloop. I also have a program based on the lettre crate for Rust which runs perfectly fine on my own devices and correctly sends emails out through code. However when I try to run the program on my VPS, I get the following messages in my syslog.
globalfun postfix/smtps/smtpd[24656]: connect from localhost[::1]
globalfun postfix/smtps/smtpd[24656]: SSL_accept error from localhost[::1]: -1
globalfun postfix/smtps/smtpd[24656]: warning TLS library problem: error 14094418:SSL routines:ssl3_resl3_read_bytes: tlsv1 alert unknown ca:../ssl/rec/layer_s3.c:1543:SSL alert number 48:
globalfun postfix/smtps/smtpd[24656]: lost connection after CONNECT from localhost[::1]
globalfun postfix/smtps/smtpd[24656]: disconnect from localhost[::1] commands=0/0
I don't really understand why I can't send out emails through my program but it seems to have something to do with SSL. For reference, I have two servers on the same domain - one for my website which has an SSL installed through Let's Encrypt and another for the mail server which doesn't have SSL on it. That said, I don't think that's the issue as I can send emails through the mail server manually completely fine. Does anyone have any ideas as to what's wrong? Thanks in advance.
globalfun postfix/smtps/smtpd[24656]: warning TLS library problem: error 14094418:SSL routines:ssl3_resl3_read_bytes: tlsv1 alert unknown ca:../ssl/rec/layer_s3.c:1543:SSL alert number 48:
Your client refuses to connect to your mail server since it does not trust the CA which issued the mail servers certificate. It notifies the server about this problem by sending a unknown ca TLS alert.
There can be various reasons for this. Typically it is either the use of a CA which is not trusted by the client which need to be fixed at the client (trust this CA) or at the server (use a certificate from a CA trusted by the client). Or the root CA is actually trusted but the server is not sending the intermediate certificates needed by the client to build the trust chain to this trusted root CA. This need to be fixed at the server.

SOAP Error "iaik.security.ssl.SSLException: Peer sent alert: Alert Fatal: handshake failure" in webMethods 6.5

I have encountered the below error while executing the pub.client:soapHTTP service that is available in WmPublic.
java.io.IOException: said.security.ssl.SSLException: Peer sent alert: Alert Fatal: handshake failure
On further investigation, I found that TLSv1.2 is being used by the partner server and I believe wM 6.5 only supports TLS v1.0. This might be a TLS version issue.
I am using webMethods 6.5.
Trusted Certificates > CA Certificate Directory is unspecified and watt.security.cert.wmChainVerifier.trustByDefault is set as TRUE for my server. Therefore, all CAs should be trusted.
Is there any way to make this work as upgrading wM is not an option, unfortunately?
I found this page (link PFB) where there is a section called TLS/SSL Handshake Issues & Debugging. There my handshake issue is mentioned and as a solution, it said:
handshake failed as Integration Server using Entrust IAIK connects to a TLS 1.2 enabled server. In this case, change from IAIK to JSSE option and set "watt.net.jsse.client.enabledProtocols=TLSv1.2"
I tried the above way but it did not work and yes, I restarted the server after changing the configuration.
Moreover, it also stated that
For outbound SSL connection (i.e. Integration Server is acting as SSL client), the following watt properties control the protocol version and ciphersuites:
IAIK:watt.net.ssl.client.handshake.minVersion,watt.net.ssl.client.handshake.maxVersion, watt.net.ssl.client.strongcipheronly,watt.net.ssl.client.cipherSuiteList
JSSE:watt.net.jsse.client.enabledProtocols,watt.net.jsse.client.enabledCipherSuiteList.
But I don't have any of those parameters configured in server.cnf and even if I had to I don't know what values I should configure them with. I'd like some help with those if it'll help with the situation.
https://techcommunity.softwareag.com/pwiki/-/wiki/Main/Debugging%20TLS%20SSL%20connections%20in%20Integration%20Server
try to set in extended settings
watt.net.ssl.client.useJSSE=true
i dont know the old version but it could be that the useJsse parameter that normally is set on the .http and .soapClient service is just taken from the default properties

Handling self-signed certificate errors when using chrome.sockets.tcp.secure

I am using chrome.sockets.tcp API to create a secure connection. No errors are being encountered when connecting using a trusted certificate.
However, I'm facing error -202 (CERT_AUTHORITY_INVALID) (among other possible [certificate errors][2]) when trying to connect to a server with a self-signed/untrusted certificate.
Is it possible to warn the user about the invalid certificate and provide the option to continue with the connection? (similar to the way Chrome handles such situations)
Seeing nothing on the topic in the docs (and SocketsTcpSecureFunction::AsyncWorkStart(), the source code of chrome.sockets.tcp.secure, only verifies the certificate but doesn't try to handle the errors, it would only report them back) I'd conclude there's no way to interactively handle this predicament.
Maybe you can import the certificate on the client machine but it won't help other users of the site unless they're willing to do the same.