Add support for version 1 (0x501) keytab files (#5)#6
Open
p0dalirius wants to merge 1 commit into
Open
Conversation
The (de)serialization code only implemented version 2: it hardcoded big-endian byte order, always read/wrote a 32-bit name_type, and never adjusted the component count. Version-1 files, which use native (little-endian) byte order, count the realm in num_components, and omit name_type, were therefore mis-parsed and could not be produced. Derive the byte order and the version-specific layout from the file format version and thread it through the entry, key block, and counted-octet-string (de)serialization. Version-1 reads now decode little-endian integers, subtract 1 from the component count, and default name_type to KRB5_NT_PRINCIPAL; writes emit the matching layout. The version/byte-order parameters are optional and default to version 2, so existing callers are unaffected. Fixes #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked Issue
Closes #5Root Cause
The keytab (de)serialization was written for version 2 only. Every integer read and write used
binary.BigEndian, thename_type32-bit field was always present, and the component count was used verbatim. Version 1 of the format differs in exactly three ways — it uses native (little-endian) byte order, its component count includes the realm, and it has noname_typefield — and none of these were derived fromFileFormatVersion. As a result version-1 files were parsed with the wrong byte order and a phantomname_type, desynchronizing every field, and the writer could only emit version-2 layout.Fix Description
src/keytab/FileFormatVersion.gowith the version constants, abyteOrderForVersionhelper (version 1 → little-endian, otherwise big-endian), and small resolvers for the optional parameters.CountedOctetStringandKeyBlockFromBytes/ToBytestake an optionalbinary.ByteOrderand use it for all integer fields.KeytabEntry.FromBytes/ToBytes/UpdateSizetake an optionalversion; they derive the byte order, subtract 1 from the on-disk component count for version 1 (and add it back when writing), and skip thename_typefield for version 1, defaulting it in memory toKRB5_NT_PRINCIPAL.Keytab.FromBytes/ToBytes/UpdateEntriesSizespassFileFormatVersiondown to the entries. The 2-byte version header itself is unchanged (always0x05followed by the version byte).All new parameters are variadic and default to version 2 / big-endian, so the change is backward compatible: existing call sites (and all existing tests) behave exactly as before.
Note on byte order: the spec says version 1 uses "native" byte order. Since a reader cannot know the producing host's endianness, this implementation assumes little-endian, which is the conventional interpretation (version 1 predates the big-endian convention that version 2 introduced to remove the ambiguity).
How Verified
go test ./...andgo vet ./keytab/pass.keytab describe -f example.kt(version 2) is unchanged.name_typeare all handled, then confirm byte-exact round-trips.Test Coverage
src/keytab/Keytab_version1_test.go:Test_KeytabEntry_Version1_Parse— a hand-built little-endian record decodes correctly (realm subtracted from the count,name_typedefaulted, all fields little-endian).Test_KeytabEntry_Version1_RoundTrip— that record serializes back to identical bytes.Test_Keytab_Version1_FileRoundTrip— a full version-1 keytab round-trips and emits the0x05 0x01header with a little-endian, realm-inclusive component count.Test_KeytabEntry_Version1_OmitsNameType— a version-1 entry is exactly 4 bytes shorter than the version-2 encoding of the same entry.Scope of Change
src/keytab/FileFormatVersion.go(new),src/keytab/CountedOctetString.go,src/keytab/KeyBlock.go,src/keytab/KeytabEntry.go,src/keytab/Keytab.go,src/keytab/Keytab_version1_test.go(new)Risk and Rollout
The optional-parameter defaults preserve all version-2 behavior, so the blast radius is limited to the new version-1 path. Safe to merge directly.
Notes
This branch is based on
mainand touches the same (de)serialization methods as the open PRs for #1 (parser robustness) and #2 (kvno round-trip); whichever merges first, the others will need a straightforward rebase.