-
Notifications
You must be signed in to change notification settings - Fork 43
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
Introduce version 0x81, including microsecond timestamps #13
Conversation
Given that the timestamp is already a 64-bit unsigned big-endian integer, the spec will remain viable for over 500,000 years. This allows us to more precisely compare token creation timestamps against revocation event timestamps (which already have microsecond precision). This helps us avoid a race condition wherein a token can be created *after* a revocation event, but appear to be created *before* it, thus matching the revocation event and being considered invalid. After this change, the specification is still vulnerable to this race condition, but the time window to reproduce it is narrowed to a single microsecond, instead of a single second. Closes fernet#12
the token. Currently there is only one version defined, with the | ||
value 128 (0x80). | ||
This field denotes which version of the format is being used by the token. | ||
Currently there is only one version defined, with the value 128 (0x80). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit is adding a second version. Or are we just noting changes from the original document with Changed in version 0x81
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, I totally missed this as I was focused on the timestamp field. Will revise.
This is mostly intended to further explain the change in version 0x81.
This will ensure that Github will render the spec on the repository's homepage (the repo is already called "spec", after all!).
I think I wrote this thinking there was only one difference between the two versions, my grammar followed suit, but the statement should be more generic to handle more than just two versions and more than just one difference between the existing two versions.
TODOs are serving as placeholders for actual 0x81 tokens, which I've neither created by hand nor written an implementation to produce, yet.
I accidentally put them in the TZ, whoops!
I rebuilt the valid 0x80 tokens in the acceptance tests manually using the following function to convert them. This explicitly illustrates the differences between 0x80 and 0x81. import base64 import hashlib import hmac import struct def upgrade_to_81(x80_token, secret): """Upgrade an 0x80 token to 0x81 given a new timestamp and secret.""" # Decode the 0x80 version token. x80_bytes = base64.urlsafe_b64decode(x80_token) # Unpack the timestamp so we can manipulate it. seconds = struct.unpack('>Q', x80_bytes[1:9]) # Convert seconds to microseconds, and add some microseconds. microseconds = int(seconds * 1e6) + 123456 x81_bytes = '\x81' # New version identifier. x81_bytes += struct.pack(">Q", microseconds) x81_bytes += x80_bytes[9:-32] x81_bytes += hmac.new( base64.b64decode(secret)[16:], x81_bytes, hashlib.sha256).digest() return base64.urlsafe_b64encode(x81_bytes)
Test cases with microsecond data are in I'm not sure what you mean by the "or do we wait ..." (this is already a pull request against fernet/spec). And no, I haven't written any sort of real implementation yet. |
Closing and abandoning this, as I'm no longer a stakeholder. |
This change introduces a second version of the specification (0x81), and asserts that timestamps in tokens versioned as 0x81 be evaluated as microseconds since the epoch. The timestamp is still a 64-bit unsigned integer, which I believe is still totally sufficient.