Skip to content

Consolidate Randnum hex/key parsing helpers #2996

Description

@rdmark

Summary

The Randnum key-file parsing logic is currently duplicated between:

  • bin/afppasswd/afppasswd.c
  • etc/uams/uams_randnum.c

Both files need to parse the same <afppasswd>.key format: exactly 16 hexadecimal characters representing an 8-byte DES key, with one optional trailing newline.

Recent hardening fixed both copies independently, but the duplication makes future drift likely. We should consolidate the shared parsing/validation logic into a common helper.

Background

Randnum uses a companion key file named <afppasswd>.key. The key file is read by both:

  • afppasswd, when creating/updating Randnum password entries
  • uams_randnum, when authenticating users or changing passwords at runtime

The logic now needs to enforce the same contract in both places:

  • Accept exactly 16 hex characters
  • Allow one optional trailing newline
  • Reject short, long, non-hex, or otherwise malformed files
  • Decode the hex into 8 bytes
  • Wipe temporary buffers that may contain key material
  • Avoid undefined behavior when using ctype(3) helpers

Problem

The implementation currently has two near-identical parser paths. This creates a maintenance risk:

  • A validation bug may be fixed in one copy but not the other.
  • Security cleanup such as explicit_bzero() on error paths must be remembered twice.
  • Small C correctness details, such as casting before isdigit() / toupper(), can diverge.
  • Future format changes would need duplicated edits and duplicated review.

This is especially undesirable because the parser handles secret key material.

Proposed Fix

Add a shared helper in libatalk for fixed-size hex decoding, then use it from both Randnum callers.

A general helper is preferable to exporting a Randnum-specific helper unless we want to encode the key-file newline policy there too.

Possible API shape:

int atalk_hex_decode_fixed(const unsigned char *hex,
                           size_t hexlen,
                           uint8_t *out,
                           size_t outlen);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions