https://toitlang.org/ logo
how to use TLS client without any server verificat...
# help
w
Hi, I want to talk to a TLS server in my local network. The server is only able to handle TLS connections but because of the local network I don't need any verification. I tried this code on a ESP32/version :
Copy code
import net
import tls


main:
    tx := #[
        192, 0, 35, 48, 0, 66, 50, 50, 50, 66, 66, 66, 66, 66, 66, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 192
    ]
    net := net.open
    sock := net.tcp-connect "192.168.0.3" 51200
    klf := tls.Socket.client sock 
    print "connected"
    klf.out.write tx // this call fails!
    resp := klf.in.read-bytes 8
    print "RXED: $resp"
    klf.close
but I got this error message:
Copy code
[jaguar] INFO: program f7e0b56b-55f2-5b0a-8e13-fcb04c8802a5 started
connected

******************************************************************************
Decoding by `jag`, device has version <2.0.0-alpha.174>
******************************************************************************
EXCEPTION error. 
Unknown root certificate: 'C=DK, O=VELUX A/S'
Certificate error 0x0008: 'C=DK, O=VELUX A/S'
NOT_TRUSTED
  0: tls-error_                <sdk>/tls/session.toit:1147:3
  1: Session.handshake_        <sdk>/tls/session.toit:338:9
  2: Session.handshake.<block> <sdk>/tls/session.toit:277:7
  3: Session.handshake         <sdk>/tls/session.toit:223:3
  4: Session.ensure-handshaken_ <sdk>/tls/session.toit:462:5
  5: Session.write             <sdk>/tls/session.toit:399:5
  6: Socket.try-write_         <sdk>/tls/socket.toit:122:21
  7: CloseableOut_.try-write_  <sdk>/io/writer.toit:346:19
  8: Writer.try-write          <sdk>/io/writer.toit:110:16
  9: Writer.write              <sdk>/io/writer.toit:51:14
 10: main                      hello.toit:14:13
******************************************************************************

[jaguar] ERROR: program f7e0b56b-55f2-5b0a-8e13-fcb04c8802a5 stopped - exit code 1
Is there a way to communicate with tls without certificates?
f
Currently there isn't any way to disable verification. You should be able to get the public certificate from the server on your local network, though. It doesn't need to be signed by a public root. You can then install just that certificate. Let us know if you need help (more detailed steps) on how to do that.
w
Hi, I'm a little bit lost and don't know what to do. I did
openssl s_client -connect 192.168.0.3:51200
and I got
Copy code
ONNECTED(00000003)
Can't use SSL_get_servername
depth=0 C = DK, O = VELUX A/S
verify error:num=18:self-signed certificate
verify return:1
depth=0 C = DK, O = VELUX A/S
verify return:1
---
Certificate chain
 0 s:C = DK, O = VELUX A/S
   i:C = DK, O = VELUX A/S
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Apr 25 09:38:26 2018 GMT; NotAfter: Jul 12 09:38:26 2026 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAwIBAgIJAJq77rG+ZPdkMA0GCSqGSIb3DQEBCwUAMCExCzAJBgNV
BAYTAkRLMRIwEAYDVQQKDAlWRUxVWCBBL1MwHhcNMTgwNDI1MDkzODI2WhcNMjYw
NzEyMDkzODI2WjAhMQswCQYDVQQGEwJESzESMBAGA1UECgwJVkVMVVggQS9TMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAruJCr/hGF2Vy7h34bZrEs7Te
iGoAEUagvxjxxQ60pXJFwfFmTUwoU10iOyvWf5Ih+UuuJkTKExiQSy5aVxv6TDNq
BxVkAKke+2sqsU49WAPR5xXOv1P2RlCyFAUSZh54XqmA3We/gcqF7DB3L84noXD4
2ga+qdDHqtK9q6Loeh+nCupt9LmXMgEudVS6MSm6DsQfypoO0GgPpblUKXvVIqBi
ap/FlgDUu/QxV+kKtfxNqT6R6FgYHvAaho7KX7ajvNWAR/49VWwwABw9Mne/UGq4
NBF5AAI/kqVFJRHRd8hpP/RX3x6DehRrrabE83Cec7igR/D6WOcSR+4BQHQwjwID
AQABo1AwTjAdBgNVHQ4EFgQU3tvHdagNdZed6UVmjl9gaC9impQwHwYDVR0jBBgw
FoAU3tvHdagNdZed6UVmjl9gaC9impQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEAJYbMGC4T7eH7+eEWDuAduByKJKrfHO9zy+dKRnBM+dADiakWiJ7c
tzwxoWDpH5YPW+KhyUQq+LjotiorMcZlKU/eyfaaaPipd9okc0W23pdnFVZZCVBu
EWwh7Jf9CKg4QpUHl09qr00NHMOVvy2ytUVL+t9mTNCk/YQHen+OkVNAjdtULzr5
dRJpLQXUhTbGbHVqw5X9knxAC9ITOZt6aJNkScV8TL90CzZWOodh5+6AXqywCQMF
3GgH+AaFvwChQ/6O35La5UYzLbcEAHjIWkA31XMybdejZYW3Bzk2oVAPgnOAMgS2
L6owZzkax0jWlxC1CsnbdC32LCdxj4TiUg==
-----END CERTIFICATE-----
Copy code
subject=C = DK, O = VELUX A/S
issuer=C = DK, O = VELUX A/S
---
No client certificate CA names sent
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: DH, 2048 bits
---
SSL handshake has read 2043 bytes and written 651 bytes
Verification error: self-signed certificate
---
New, TLSv1.2, Cipher is DHE-RSA-AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-SHA256
    Session-ID: 5F603931DA2A3D715BA80549CD906E4E78313A42E7A622380CFBC603E74B0118
    Session-ID-ctx: 
    Master-Key: 8C21909C1912F2D15A05D02034D554E2A9B8C84D1D398F95562A707D7584CE890B368F2E26D51C2562991970DFF66CDB
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1738441694
    Timeout   : 7200 (sec)
    Verify return code: 18 (self-signed certificate)
    Extended master secret: no
---
I guess the message between BEGIN CERTIFICATE und END CERTIFICATE is the public key. In my toit program I assigned
Copy code
cert := """
    -----BEGIN CERTIFICATE-----
    MIIDFTCCAf2gAwIBAgIJAJq77rG+ZPdkMA0GCSqGSIb3DQEBCwUAMCExCzAJBgNV
    BAYTAkRLMRIwEAYDVQQKDAlWRUxVWCBBL1MwHhcNMTgwNDI1MDkzODI2WhcNMjYw
    NzEyMDkzODI2WjAhMQswCQYDVQQGEwJESzESMBAGA1UECgwJVkVMVVggQS9TMIIB
    IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAruJCr/hGF2Vy7h34bZrEs7Te
    iGoAEUagvxjxxQ60pXJFwfFmTUwoU10iOyvWf5Ih+UuuJkTKExiQSy5aVxv6TDNq
    BxVkAKke+2sqsU49WAPR5xXOv1P2RlCyFAUSZh54XqmA3We/gcqF7DB3L84noXD4
    2ga+qdDHqtK9q6Loeh+nCupt9LmXMgEudVS6MSm6DsQfypoO0GgPpblUKXvVIqBi
    ap/FlgDUu/QxV+kKtfxNqT6R6FgYHvAaho7KX7ajvNWAR/49VWwwABw9Mne/UGq4
    NBF5AAI/kqVFJRHRd8hpP/RX3x6DehRrrabE83Cec7igR/D6WOcSR+4BQHQwjwID
    AQABo1AwTjAdBgNVHQ4EFgQU3tvHdagNdZed6UVmjl9gaC9impQwHwYDVR0jBBgw
    FoAU3tvHdagNdZed6UVmjl9gaC9impQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
    AQsFAAOCAQEAJYbMGC4T7eH7+eEWDuAduByKJKrfHO9zy+dKRnBM+dADiakWiJ7c
    tzwxoWDpH5YPW+KhyUQq+LjotiorMcZlKU/eyfaaaPipd9okc0W23pdnFVZZCVBu
    EWwh7Jf9CKg4QpUHl09qr00NHMOVvy2ytUVL+t9mTNCk/YQHen+OkVNAjdtULzr5
    dRJpLQXUhTbGbHVqw5X9knxAC9ITOZt6aJNkScV8TL90CzZWOodh5+6AXqywCQMF
    3GgH+AaFvwChQ/6O35La5UYzLbcEAHjIWkA31XMybdejZYW3Bzk2oVAPgnOAMgS2
    L6owZzkax0jWlxC1CsnbdC32LCdxj4TiUg==
    -----END CERTIFICATE-----
    """
But now I don't know how to use variable
cert
in my toit program. Any help is appreciated.
f
I think you can just:
Copy code
import tls

main:
  my-root := tls.RootCertificate CERT  // Where 'CERT' is your "cert".
  my-root.install
w
Ok, thx for the auick answer. I will give it a try
f
I hope that works. If not, let me know.
w
very cool, I works! Thank you. I like the language!
"it work"
f
I will try to add this information to the docs. Where would you have found it the fastest?
w
I have a last tls question: At the end of the program, what I've tot do? a)
klf.close
b)`sock.close` c)
Copy code
klf.close
sock.close
f
What's
klf
here?
w
klf: Just have a look at my first post, it is
klf := tls.Socket.client sock
f
ah.
I would close both. In reverse order of construction. That said: the TLS socket does automatically close the given socket. (I looked at the source). So you can just close the klf.
w
My ranking: The easiest place to find the information is in the dokumentation of the tls package (
https://libs.toit.io/tls/library-summary
). Second best is a small program example in tutorial/network. Third best place is an example under github/toit/examples.
But for future: I would appreciate, to use the tls connection without certificate. The RAM on the ESP32 is so small, every byte counts.
f
Agreed. Establishing the TLS connection is quite expensive... I will add it to my TODO list.
w
Hi again! Now I'm try to access the pcloud, I would like to upload there my sensor values. Unfortunately I've again trouble with trust and certificates. My code:
Copy code
import http
import net
import tls
import certificate-roots
import encoding.json
import .secrets

URL ::= "eapi.pcloud.com"
PATH ::= "userinfo?getauth=1&logout=1&username=$USER&password=$PASS" // encoded mit https://www.utilities-online.info/urlencode


main:

  certificate-roots.install-common-trusted-roots
  network := net.open
  client := http.Client.tls network
  response := client.get URL PATH 
  print response.body
  client.close
The output:
Copy code
EXCEPTION error. 
Unknown root certificate: 'C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2'
Certificate error 0x0008: 'C=CH, O=SwissSign AG, CN=SwissSign RSA TLS Root CA 2022 - 1'
NOT_TRUSTED
  0: tls-error_                <sdk>/tls/session.toit:1147:3
  1: Session.handshake_        <sdk>/tls/session.toit:338:9
  2: Session.handshake.<block> <sdk>/tls/session.toit:277:7
  3: Session.handshake         <sdk>/tls/session.toit:223:3
  4: Socket.handshake          <sdk>/tls/socket.toit:69:14
  5: Client.try-to-reuse_.<block>.<block> <pkg:pkg-http>/client.toit:652:24
  6: catch.<block>             <sdk>/core/exceptions.toit:124:10
  7: catch                     <sdk>/core/exceptions.toit:122:1
  8: catch                     <sdk>/core/exceptions.toit:85:10
  9: Client.try-to-reuse_.<block> <pkg:pkg-http>/client.toit:647:9
 10: Client.try-to-reuse_      <pkg:pkg-http>/client.toit:635:3
 11: Client.get_.<block>       <pkg:pkg-http>/client.toit:305:7
 12: SmallInteger_.repeat      <sdk>/core/numbers.toit:1277:3
 13: Client.get_               <pkg:pkg-http>/client.toit:303:19
 14: Client.get                <pkg:pkg-http>/client.toit:300:12
 15: main                      pcloud.toit:17:22
Any help appreciated.
f
Try with
install-all...
to see if that fixes the problem.
The list of common certificates is just a list we found to be useful. It could miss some important ones.
w
install-all... works, great
f
Great.
I don't think the swiss root is very common, so I don't want to add it yet to the common list...
Adding all roots costs in flash size and maybe also in memory. You could just install that specific root if you want to.
w
I think it's ok as it is. But now I run out of heap. If I would use a board with psram, can toit use the psram to extend the heap space?
f
Yes. It can. But you have to use the SPI envelope: https://github.com/toitlang/envelopes/tree/main/variants/esp32-spiram
w
Cool!
f
For Jaguar it's
jag flash esp32-spiram
That will automatically download that envelope.
w
Thanks a lot. I love this toit stuff.
For me, a great advantage is to test the program (at least the network stuff) first on my laptop and then download it to the esp.
f
We are also writing more and more code in Toit. Some things (like the package manager and Jaguar) are still in Go, but if I had a bit more time, they would have been converted to Toit too...
w
The only thing I miss is a driver for the CAN(TWAI ) peripheral: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/twai.html Is it planned for future?
f
We had a potential customer in the automotive industry and used external CAN chips. According to one of my coworkers, the ESP one wasn't good enough. There are no plans right now to add the esp-idf one, but eventually we would like to support all features. It's mostly a matter of time. We are available for hire to add new drivers, features, or even just consulting on some projects, but otherwise we basically work down our TODOs. Currently CAN isn't too high. It just got a small bump, though 😉
w
The ESP-CAN is not bad. It has the same register set as the SJA1000. Very old, but still ok. With the ESP you can log the traffic and forward it via bluetooth or wlan. The ESP is the only chip that can do this. And the internal peripheral is a lot of faster than a SPI connected external CAN. But of course, I understand your priorities. Maybe I will dig into your code for the SPI driver and maybe it's possible to transform the code to the ESP-CAN.
f
If you do (dig into our code), consider chatting with us first. We would be happy to help/introduce/...
I just looked a bit at the API. I don't see any big challenges. Biggest issue for me would probably be to test it and write tests.
w
I can test it, no problem. I'm working almost every day on CAN.
f
I have started to add tests for hw peripherals to our repository. So that we can have some confidence that things continue to work for new ESP variants (and probably some other chips eventually too). Since I don't know enough about CAN I don't know how hard that would be. (But writing the tests is usually taking me more time than writing the driver).
f
it might. yes.
w
Do you write the tests in toit?
f
yes.
One thing I just noticed about the CAN API: it looks like there isn't any way to get notified when there is an alert. Did I miss something?
f
We can't use functions that block.
If that's the only way to get alerts, then we would need a thread for the CAN. Expensive...
w
I don't think the function blocks. You call it and you get current alerts.
f
Usually, the esp-idf has either a callback, or a freeRTOS queue for these things.
It blocks, but you can set the
ticks_to_wait
to 0. But that still doesn't really help us.
As a user, I would want to be able to
read-alert
(or so), and be blocked until an alert is raised. (Like
read
functions). But we can't implement that (nicely) with this API, as we are not allowed to block.
I'm just noticing: the
can_receive
seems to have the same issue.
There isn't any notification when a new message is available.
That would be another thread...
The frustrating thing is, that the driver uses a queue internally for the receive messages. Apparently not for the alerts, though.
Looks like there is a new drivers version coming. Hopefully that will fix the issue: https://github.com/espressif/esp-idf/issues/15182#issuecomment-2586134572
> As you may find a good new is a new twai driver is coming, although it already long long ago, but it is now has initially version, believe it will avaiable soon.
w
If it must be non blocking and threads are expensive: I think its ok to call receive or transmit functions with ticks_to_wait := 0 and evaluate the return code. In case of an error I would call then twai_read_alerts (ticks_to_wait := 0) to get more detailed information. The important alerts are: RX- or TX queue is full. Or the controller went "bus off" because of hardware-issues. If it is bus off it remains bus off until you request a recover. So nothing will be lost. But of course, a new api with callback would fit better for you. In the past, I only programmed the ESP-CAN registers directly from FreeRTOS without the Espressif-API.
f
Not bad.. (using the registers) Ideally we would like to use the high level APIs. Makes it more likely that it will work on different variants. Also, the TWAI has a lot of errata that are taken into account by their driver.
Finally found the time to write the documentation for the TLS library. https://github.com/toitlang/toit/pull/2715
w
Thx a lot. Nice examples. Better than thousand words.
2 Views