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

Migration Payload.batch_id should be int32 #15

Closed
tc287 opened this issue Jun 3, 2021 · 3 comments
Closed

Migration Payload.batch_id should be int32 #15

tc287 opened this issue Jun 3, 2021 · 3 comments

Comments

@tc287
Copy link

tc287 commented Jun 3, 2021

a2c0a3f changes a bunch of protobuf fields from int32 to uint32; I assume this was in due to the discussion around google/google-authenticator-android#118 (comment) (batch_id sometimes being negative).

I believe this is incorrect! After figuring out how to generate batched migration codes (an Android-only feature), the first batch_id I see is 18446744073509271282 (0xfffffffff40ff6f2), which indicates that the type is a negative int32 ("if you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes long"). This shows up as "%2F%2F%2F%2F" in the otpauth-migration URL, making it easy to spot.

(I agree that uint32 would have been a more sensible type, but it is not the type they used.)

If you want to dig deeper, you can look at the generated code's dynamicMethod(): For BUILD_MESSAGE_INFO, it returns a RawMessageInfo which encodes a bunch more information from the source proto (including the "FieldType"). But given that batch_id is int32, it seems reasonable to assume that integer fields are int32 by default.

@dim13
Copy link
Owner

dim13 commented Jun 13, 2021

You may be right, but I could not deduce it with certainly now.

Here are encoded message info definitions. I see some patterns here, but I'm not quite sure, how to decode 'em:

Main Payload message:

01 05 00 01 01 05 05 00 01 00
01 1b          # otpParameters_
02 e1 80 84 00 # version_ (u?int32) → 4: int32
03 e1 80 84 01 # batchSize_ (u?int32) → 4: int32
04 e1 80 84 02 # batchIndex_ (u?int32) → 4: int32
05 e1 80 84 03 # batchId_ (u?int32) → 4: int32

And embedded OtpParams message:

01 07 00 01 01 07 07 00 00 00
01 e1 80 8a 00 # secret_ (bytes)
02 e1 80 88 01 # name_ (string)
03 e1 80 88 02 # issuer_ (string)
04 e1 80 8c 03 # algorithm_ (enum)
05 e1 80 8c 04 # digits_ (enum)
06 e1 80 8c 05 # type_ (enum)
07 e1 80 83 06 # counter_ (u?int64) → 3: uint64

Would love to hear, if you know more.

@tc287
Copy link
Author

tc287 commented Jun 16, 2021

The encoding is described in RawMessageInfo.java and encodes integers using 1-3 UTF-16 "chars". Fortunately, most numbers are small enough to be encoded in a single char, so the only thing you need to worry about is U+0000 encoding as c0 80 due to "modified UTF-8" (depending on the tool you use to view the strings).

In the above, e1 80 84 represents 0x1004, e1 80 83 represents 0x1003, etc. This is the "field type with extra bits"; the lower 8 bits are the field type from FieldType.java: 4 is int32, 3 is uint64, 8 is string, 0xA (10) is bytes, 0xC (12) is enum.

@dim13 dim13 closed this as completed in 6ce98b4 Jun 17, 2021
@dim13
Copy link
Owner

dim13 commented Jun 17, 2021

Thanks! That helped.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants