Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unclear timestamp type returned from AcceptSecurityContext #3413

Closed
2ndDerivative opened this issue Jan 4, 2025 · 6 comments
Closed

Unclear timestamp type returned from AcceptSecurityContext #3413

2ndDerivative opened this issue Jan 4, 2025 · 6 comments
Labels
question Further information is requested

Comments

@2ndDerivative
Copy link

2ndDerivative commented Jan 4, 2025

Summary

Hello!
AcceptSecurityContext returns an expiry time in i64 format and between the documentation and the actual implementation it's not clear how you would have to transmute or interpret that. I assume you just have to transmute it, but it should probably just return FILETIME directly.

On that front, I noticed that SystemTime from the Rust standard library (!) uses a FILETIME handle internally, so you could actually transmute to that directly from this library to return a safe SystemTime instance for Rust. That might be worth looking into directly with the std guys, as now these types from windows_sys and std are incompatible but implemented pretty much the same.

Using windows crate version 0.58

@2ndDerivative 2ndDerivative added the bug Something isn't working label Jan 4, 2025
@tim-weis
Copy link
Contributor

tim-weis commented Jan 4, 2025

The reference documentation describes ptsExpiry as

A pointer to a TimeStamp structure that receives the expiration time of the context.

The TimeStamp documentation further elaborates that

The format of the value of the TimeStamp data type is the same as that of the FILETIME structure.

With that, you can safely transmute() the i64 returned to a FILETIME. Technically, that is. There's still an issue regarding the interpretation of the value. FILETIME

Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).

whereas ptsExpiry has this note:

We recommend that the security package always return this value in local time.

While the i64 and FILETIME are interchangeable at the binary level, the interpretation may need to be adjusted (from local time to UTC). I don't know why the SSPI recommends using an ambiguous time system.

@tim-weis
Copy link
Contributor

tim-weis commented Jan 5, 2025

As for changing the signature of the Rust bindings to the API call to return a SystemTime, that's not easily doable, for two reasons:

  1. The bindings are generated from metadata. The metadata is derived from the platform SDK header files. The sspi.h header introduces TimeStamp as an alias for __int64 and that's what ultimately winds up in the metadata. Changing that requires special-casing, either here or in the win32metadata repo; neither is a scalable solution.
  2. The layout of the SystemTime structure is unspecified. It happens to be a wrapper for FILETIME (or timespec) today, but that could eventually change. Besides, even if represented as a FILETIME, it's most likely interpreted relative to the UNIX epoch (not the Windows epoch).

I don't believe anything can be done to change the current situation.

@2ndDerivative
Copy link
Author

2ndDerivative commented Jan 5, 2025

Thank you!
Yeah, I figured there might be an opportunity here for cross-pollinating std and the supported Microsoft implementation, but maybe that's a bit of a pipe dream.

The FILETIME as I see it in the std seems to refer to the windows epoch actually, it just translates on the external API of the type

@2ndDerivative
Copy link
Author

Would it be possible/advisable to make something like a LOCALFILETIME to make the struct properly marked as a FILETIME format?

@kennykerr kennykerr added question Further information is requested and removed bug Something isn't working labels Jan 5, 2025
@riverar
Copy link
Collaborator

riverar commented Jan 6, 2025

Each security package is able to return a LARGE_INTEGER representing time in any way it sees fit. Some security packages return local time, UTC/FILETIME time (e.g., SChannel), GMT-relative NT system times, or even near-u64::MAX sentinel values (to ensure conversion to UTC does not yield a time in the past!)

@kennykerr
Copy link
Collaborator

Closing for now but feel free to keep the discussion going. If there's an API change to be made you'd need to pick up the conversation over at https://github.com/microsoft/win32metadata

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants