Skip to content

Feature/asn#425

Open
SteveSyfuhs wants to merge 7 commits intofeature/iakerb2from
feature/asn
Open

Feature/asn#425
SteveSyfuhs wants to merge 7 commits intofeature/iakerb2from
feature/asn

Conversation

@SteveSyfuhs
Copy link
Copy Markdown
Collaborator

@SteveSyfuhs SteveSyfuhs commented Apr 22, 2026

What's the problem?

The existing ASN code generation is janky and relies on converting an existing well-known schema to an arbitrary XML format which passes through XSLT. We should just generate the C# directly from the ASN1.
1

  • Bugfix
  • New Feature

What's the solution?

Build an ASN.1 schema parser and use it as the basis for a source generator.

  • Includes unit tests
  • Requires manual test

What issue is this related to, if any?

#426

SteveSyfuhs and others added 7 commits April 21, 2026 14:29
- Make optional BitStringFlagsEnum fields nullable (TicketFlags?, S4uOptions?)
  so .Value access is valid in encode methods
- Make CHOICE value-type alternatives nullable (ReadOnlyMemory<byte>?) so
  HasValue<T>(T?) struct overload is matched correctly
- Use wrapper class type for collection references with @cs-class + @cs-name
  (e.g., METHOD-DATA resolves to KrbMethodData instead of KrbPaData[])
- Use CSharpType nullability instead of IsOptional flag for .Value generation
  in EmitFieldValueEncode to handle both optional and CHOICE nullable fields
- Fix TicketCacheEntry to handle nullable TicketFlags? from KrbCredInfo
- Remove invalid AuthorizationData property from DelegationTests (KrbCredInfo
  has no such field in the ASN.1 spec)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replaces the old pipeline of 79 XML descriptors + XSLT transform with a modern
C# incremental source generator that reads .asn schema files directly.

New source generator (Tools/Asn1SourceGenerator/):
- ASN.1 tokenizer and recursive descent parser
- Type resolver with alias chain following
- C# emitter supporting SEQUENCE, CHOICE, InheritedSequence, and
  CollectionWrapper patterns
- Comment-based annotations (@cs-class, @cs-name, @cs-type, @cs-enum,
  @cs-flags-enum) for C# metadata in .asn files

Schema files:
- kerberos.asn: Annotated RFC 4120, 4178, 4556 types
- kerberos-extensions.asn: FAST, S4U, PAC, KKDCP, IAKerb types

Removed:
- 79 XML descriptor files
- asn.xslt, AsnXml.targets, asn.xsd
- 71 .generated.cs files (now generated in-memory by source generator)

All 441 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 98 tests verifying the source-generated API surface matches expectations:

- GeneratedApiSurfaceTests: reflection-based verification of type existence,
  property types/names, enum mappings, nullable correctness, inheritance
  hierarchy, collection wrappers, and encode/decode method signatures
- GeneratedRoundtripTests: pattern-specific encode/decode roundtrips for
  APPLICATION-tagged sequences, plain sequences, inherited sequences,
  collection wrappers, CHOICE types, optional field omission, and
  ENUMERATED enum mapping

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 120 unit tests for the ASN.1 source generator components:

- TokenizerTests (20): symbol/keyword/number/comment/annotation tokenization,
  line tracking, peek behavior, error handling
- ParserTests (28): module structure, type aliases, SEQUENCE/CHOICE/SEQUENCE OF
  parsing, tags, OPTIONAL/DEFAULT, imports, annotations, recovery, ENUMERATED
- TypeResolverTests (35): class naming, alias resolution, field type mapping,
  enum/flags-enum annotations, nullable handling, obsolete aliases, alias chains,
  transparent vs wrapper collections, inherited sequences, CHOICE, tag defaults,
  cross-module resolution, ToPascalCase utility
- EmitterTests (37): all 4 code generation patterns (Sequence, Choice,
  InheritedSequence, CollectionWrapper), APPLICATION tags, obsolete aliases,
  optional fields, extensibility, full pipeline smoke tests including real
  kerberos.asn schema

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace all internal usages of source-generator-generated [Obsolete] property
aliases with their new canonical names:

- KrbKdcRep.EncPart -> EncryptedPart (8 library + 6 test locations)
- KrbPriv.EncPart -> EncryptedPart (2 library locations)
- KrbEncKrbPrivPart.SeqNumber -> SequenceNumber (1 location)

The obsolete aliases remain available for external consumers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Only declare the explicitReader variable in Decode methods when the type
actually has fields with explicit (non-implicit) context-specific tags.
Previously it was always declared, causing warnings for types like
KrbAlgorithmIdentifier, KrbSubjectPublicKeyInfo, GssapiToken, etc.
where all fields use implicit tags.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@SteveSyfuhs SteveSyfuhs marked this pull request as ready for review April 22, 2026 17:37
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

Successfully merging this pull request may close these issues.

1 participant