IronCoreLabs / ironhide

Tool to easily encrypt and decrypt files to users and groups. Similar to GPG, but usable at scale.
GNU Affero General Public License v3.0
44 stars 6 forks source link

Usage of `local_offset()` seems to ignore DST changes #82

Closed Kijewski closed 1 year ago

Kijewski commented 1 year ago

E.g.

let created_dt = device.created().to_offset(util::local_offset());

does not look correct to me. I only gave it a cursory glace, though. If the user's time zone changed since the device was created, e.g. because the clocks clocks were change, or the user traveled into another time zone, the information will be bogus.

coltfred commented 1 year ago

@Kijewski The time that the device was created is in UTC and the adjustment made by util::local_offset() should match the offset of the system that ironhide is being run on. I think this is what I would expect to be the case.

Can you provide a clarifying example if you do not agree?

Kijewski commented 1 year ago

util::local_offset() returns the current offset. For me right now that is UTC+1 (CET), before 2022-10-30 it was UTC+2 (CEST). So for any device created on 2022-10-29 the time will be off by an hour, right?

cjyar commented 1 year ago

Playing with this issue a little bit, we ended up in C. This code:

#include <stdio.h>
#include <time.h>

int main()
{
    struct tm *ptr;
    struct tm *ptr_t;

    /* Nov 5, midnight, GMT */
    time_t t = 1667606400;
    ptr = localtime(&t);
    printf("%s", asctime(ptr));

    /* Nov 7, midnight, GMT */
    time_t tt = 1667779200;
    ptr_t = localtime(&tt);
    printf("%s", asctime(ptr_t));
    return 0;
}

produces this output when run on a laptop in MST currently:

Fri Nov  4 18:00:00 2022
Sun Nov  6 17:00:00 2022
skeet70 commented 1 year ago

So yes, we should do this. In addition to #83 I think that means using find_local_time_type to get the offset for the created timestamp.

Kijewski commented 1 year ago

You can use tz::DateTime::from_total_nanoseconds() + tzdb::local_tz() to convert a unix timestamp into a timestamp in the correct time zone, and let from_total_nanoseconds() accurately tell if it's DST or not.