Skip to content

IoT Edge 1.5 (Scarthgap) on STM32MP1 - inconsistent certificate timestamp conversion / check #187

@Yo-3k

Description

@Yo-3k

Hi!

I am currently trying to get meta-iotedge running on an STM32MP1 platform. I already have a working iotedge setup for my hardware using a Debian image with the matching derivate of iotedge. However, we are planning to switch long-term to Yocto for flexibility and OS customization possibilities.

For testing I am using a very basic poky-altcfg distro (due to the systemd requirement) with a custom image based on core-image-minimal. The image compiles without errors and iotedge is available in my distro, there are no iotedge related errors printed in dmesg or journalctl.

However, when I try to configure iotedge with my (know working) config.toml, I run into the issue that my aziot-edged-ca certificate instantly expires upon creation:

Jan 14 13:58:17 my-client aziot-edged[1478]: 2026-01-14T13:58:17Z [INFO] - Edge CA was renewed
Jan 14 13:58:17 my-client aziot-edged[1478]: 2026-01-14T13:58:17Z [ERR!] - Cert aziot-edged-ca is expired and could not  be renewed.
Jan 14 13:58:17 my-client aziot-edged[1478]: 2026-01-14T13:58:17Z [ERR!] - failed to configure Edge CA auto renew: Cert aziot-edged-ca is expired and could not be renewed

Using Yocto patches, I have been trying to track down the issue and found that function get_cert_chain() in cert-renewal/src/engine.rs actually reports a date expiration of the certificate! However, after trying to debug the code for a bit I have seen that the certificate timestamp conversion performed by crate::Time::from() seems to be inconsistent and produces bogus dates on the first call?

I added some lines to get_cert_chain() (engine.rs line 343ff):

let not_after = cert_chain[0].not_after();

// First conversion
let expiry1 = crate::Time::from(not_after);
log::error!("First conversion: {}", expiry1);

// Immediate second conversion with same reference
let expiry2 = crate::Time::from(not_after);
log::error!("Second conversion (same ref): {}", expiry2);

// Third conversion with fresh call
let expiry3 = crate::Time::from(cert_chain[0].not_after());
log::error!("Third conversion (fresh call): {}", expiry3);

// Fourth - repeat fresh call
let expiry4 = crate::Time::from(cert_chain[0].not_after());
log::error!("Fourth conversion (fresh call): {}", expiry4);

The resolut is an inconstant timestamp conversion:

Jan 14 14:34:20 my-client  aziot-edged[1170]: 2026-01-14T14:34:20Z [INFO] - Edge CA was renewed
Jan 14 14:34:20 my-client  aziot-edged[1170]: 2026-01-14T14:34:20Z [ERR!] - First conversion: -2330-08-31T06:03:56+00:00
Jan 14 14:34:20 my-client  aziot-edged[1170]: 2026-01-14T14:34:20Z [ERR!] - Second conversion (same ref): 2026-04-14T14:34:19+00:00
Jan 14 14:34:20 my-client  aziot-edged[1170]: 2026-01-14T14:34:20Z [ERR!] - Third conversion (fresh call): 2026-04-14T14:34:19+00:00
Jan 14 14:34:20 my-client  aziot-edged[1170]: 2026-01-14T14:34:20Z [ERR!] - Fourth conversion (fresh call): 2026-04-14T14:34:19+00:00
Jan 14 14:34:20 my-client  aziot-edged[1170]: 2026-01-14T14:34:20Z [ERR!] - Failed to calculate time difference.

With my debug code, the time conversion works from the second call on but then iotedge fails at a later point in time, probably also related to time conversion. I am not quite sure how to further debug this issue, maybe a specific flag is needed for the Rust compiler to properly support my platform?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions