Unable to verify server SSL certificate

Hello,

I’m trying to verify server certificate in SSL connection on BG96. For some reason it works without certificate checking (seclevel 0), but doesn’t on higher seclevels. Here is example session:

AT
OK

ATI
Quectel
BG96
Revision: BG96MAR02A08M1G
OK

ATE1
OK

ATV1
OK

AT+QFLST
+QFLST: "ca-mq.pem",1078
+QFLST: "camq.pem",1078
OK

AT+QICSGP=1,1,"internet","","",0
OK

AT+QIACT=1
OK

AT+QIACT?
+QIACT: 1,1,1,"100.95.169.24"
OK

AT+QISTATE=0,1
OK

AT+QSSLCFG="seclevel",1,0
OK

AT+QSSLCFG="cacert",1,"camq.pem"
OK

AT+QSSLCFG="ciphersuite",1,0XFFFF
OK

AT+QSSLOPEN=1,1,4,"test.mosquitto.org",8883
OK

+QSSLOPEN: 4,0

AT+QSSLCLOSE=4
OK

AT+QSSLCFG="seclevel",1,1
OK

AT+QSSLOPEN=1,1,4,"test.mosquitto.org",8883
OK

+QSSLOPEN: 4,552

AT+QFDWL="camq.pem"
CONNECT

-----BEGIN CERTIFICATE-----
MIIC8DCCAlmgAwIBAgIJAOD63PlXjJi8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD
VQQGEwJHQjEXMBUGA1UECAwOVW5pdGVkIEtpbmdkb20xDjAMBgNVBAcMBURlcmJ5
MRIwEAYDVQQKDAlNb3NxdWl0dG8xCzAJBgNVBAsMAkNBMRYwFAYDVQQDDA1tb3Nx
dWl0dG8ub3JnMR8wHQYJKoZIhvcNAQkBFhByb2dlckBhdGNob28ub3JnMB4XDTEy
MDYyOTIyMTE1OVoXDTIyMDYyNzIyMTE1OVowgZAxCzAJBgNVBAYTAkdCMRcwFQYD
VQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwGA1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1v
c3F1aXR0bzELMAkGA1UECwwCQ0ExFjAUBgNVBAMMDW1vc3F1aXR0by5vcmcxHzAd
BgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hvby5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAMYkLmX7SqOT/jJCZoQ1NWdCrr/pq47m3xxyXcI+FLEmwbE3R9vM
rE6sRbP2S89pfrCt7iuITXPKycpUcIU0mtcT1OqxGBV2lb6RaOT2gC5pxyGaFJ+h
A+GIbdYKO3JprPxSBoRponZJvDGEZuM3N7p3S/lRoi7G5wG5mvUmaE5RAgMBAAGj
UDBOMB0GA1UdDgQWBBTad2QneVztIPQzRRGj6ZHKqJTv5jAfBgNVHSMEGDAWgBTa
d2QneVztIPQzRRGj6ZHKqJTv5jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
A4GBAAqw1rK4NlRUCUBLhEFUQasjP7xfFqlVbE2cRy0Rs4o3KS0JwzQVBwG85xge
REyPOFdGdhBY2P1FNRy0MDr6xr+D2ZOwxs63dG1nnAnWZg7qwoLgpZ4fESPD3PkA
1ZgKJc2zbSQ9fCPxt2W3mdVav66c6fsb7els2W2Iz7gERJSX
-----END CERTIFICATE-----


+QFDWL: 1078,6e2f
OK

AT+QSSLCFG="sslversion",1,4
OK

AT+QSSLOPEN=1,1,4,"test.mosquitto.org",8883
OK

+QSSLOPEN: 4,552

AT+QSSLCFG="ignorelocaltime",1
+QSSLCFG: "ignorelocaltime",1,1
OK

AT+QSSLCFG="ignorelocaltime",1,0
OK

AT+QSSLCFG="ignorelocaltime",1
+QSSLCFG: "ignorelocaltime",1,0
OK

AT+QSSLOPEN=1,1,4,"test.mosquitto.org",8883
OK
+QSSLOPEN: 4,552

For verify you need ca-root

I know, I’ve set it via

AT+QSSLCFG="cacert",1,"camq.pem"

and it was obtained from test.mosquitto.org. When I do verify it with openssl, the CN, issuer, validity and other params seem to be OK. When I’m using the same file to connect from PC, it connects properly. But, for some reason BG96 does not connect.

Also, when I add clientcert and clientkey, situation is the same.

PC … use default stored CA

The CA file can be downloaded here: http://test.mosquitto.org/ssl/mosquitto.org.crt

Yes, I know. By ‘on PC it was OK’ I meant, that this command:

openssl s_client -connect test.mosquitto.org:8883 -key priv_key_np.pem  -CAfile mosquitto.org.crt to.org:8883 -key priv_key_np.pem  -CAfile mosquitto.org.crt

said:

Verify return code: 0 (ok)

and did not throw any problems on the cert validation. Using the same files on BG96 does not pass the cert validation.

Is it possible that you can try to test the same situation? I pasted the full session content above, except file upload. I.e. camq.pem is the certificate downloaded from test.mosquitto.org.

You should use port 8883, as 8884 requires client certificate as well.

CA is OK

# pip install paho-mqtt
# https://test.mosquitto.org/ssl/mosquitto.org.crt

import os, sys, time, ssl
from os.path import join
from datetime import datetime
import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt

DIR  = os.path.dirname(os.path.realpath(__file__))
HOST = "test.mosquitto.org"
PORT = 8883

TLS = {
    'ca_certs' : join(DIR, "mosquitto.org.crt"), 
    'tls_version' : ssl.PROTOCOL_TLSv1_2
}

print ("---BEGIN---")
publish.single( 'wizio', 
    payload = "Hello world:" + str(datetime.now()),
    hostname = HOST, port = PORT, 
    protocol  = mqtt.MQTTv311,
    client_id = "CLIENT_ID_" + str( time.time() ),
    tls = TLS
)
print ("----END----")

if skip line

#‘ca_certs’ : join(DIR, “mosquitto.org.crt”),

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed …

So? Why BG96 fails, when I do set cacert like above?

TRY
delete all stored certs
upload CA_ROOT

make empty private key and upload
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

make empty cert and upload
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

ATcommands select CA_FILE, CERT_FILE and KEY_FILE
connect …

or upload CA_ROOT
ATcommands select CA_ROOT_FILE, CERT_FILE_NON_EXISTENT and KEY_FILE_NON_EXISTENT

And what you’re trying to prove? If I will provide invalid settings, I will get errors. My problem is that I’m providing apparently valid settings and still have errors. There might be mistake in parameters I provide, yet I’m not seeing it, after multiple verifications I still don’t see the problem on my side. I do provide valid cacert, etc. Hence this thread - to ask how others do the same thing, what is different?

Are you try ???
Nothing to prove … BG96 MQTT over TLS have bugs
if ( any_certificate_file_name == NULL ) return -1;
… is the Quectel logic …
CA_ROOT, PRIV_CERT and PRIV_KEY file names must be not null … tested with ThreadX SDK v2
MQTT port is the same for ThreadX and for AT commands

Yes, I tried to set all certificate names (cacert, clientcert, clientkey), to various values (non-existent files, empty files, valid files, etc.) - no change.

Did you tried to make BG96 connect to any SSL server with cert verification? Does it work at all?

Over ThreadX I try MQTT to Eclipse, Azure, Google, Amazon - work fine

Right, thanks. Is there any chance to see the actual sequence of AT commands and/or download the public certificates used in the example? (I probably wont be able to connect without private key, but I least I could inspect them with openssl).

I not use AT commands - ThreadX application inside module ( movie - Arduino app )

Hi Kami!
pls try two things:

  1. Why do you use a “AT+QSSLOPEN=1,1,4,“test.mosquitto.org”,8883” instead of QMTOPEN? -> you must config mqtt befor.
  2. I had problems with the format of the cert: there must be a \r\n in the bytestream, if you send it via a uart like: -----BEGIN CERTIFICATE-----\r\nMIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\nRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYD