Ken Johnson 05de2b430b v0.3.0: vendor fpc-crypto, drop in-tree bp.* crypto units
Five units move out of src/ to vendored copies of
fpc-crypto:
  bp.sha         -> cr.sha
  bp.ed25519*    -> cr.ed25519*

And -- bigger deal than it looks -- bp.cram's CRAM-MD5
and bp.des's key-check MD5 swap from stock FPC RTL md5 to
cr.md5.  The RTL md5.ppu has a sysutils-checksum bug that
corrupts MD5 output on i386-go32v2; consumers building
fpc-binkp for DOS would have hit it the moment CRAM-MD5
auth happened over a live socket.  cr.md5 is the go32v2-
safe standalone implementation.

API rename drops MDInit/MDUpdate/MDFinal/MDString/MDBuffer
+ TMDContext/TMDDigest in favour of the MD5-prefixed
names from cr.md5 (TMD5Context, TMD5Digest, MD5Init/etc.).
bp.cram's public surface (BPHmacMd5, BPMd5DigestHex,
BPCramComputeResponse, ...) is unchanged -- callers see no
diff.

bp.des stays in-tree.  Single consumer (Argus DES-CBC wire
extension), same discipline that kept X25519/ChaCha20 in
cm.crypto until a second consumer appeared.

Verified:
  - 7/7 local test suite PASS (same as baseline)
  - RFC 2202 HMAC-MD5 vectors in test_cram still green
    (confirms cr.md5 byte-identical to stock RTL md5 on
    the exercised inputs)
  - 6-target cross-build clean incl. i386-go32v2

Rationale + ecosystem context: MSGS Messages 48-53.
2026-04-24 12:11:12 -07:00
2026-04-21 12:45:41 -07:00
2026-04-21 12:45:41 -07:00
2026-04-21 12:45:41 -07:00
2026-04-21 12:45:41 -07:00

fpc-binkp

A Free Pascal library for the BinkP/1.1 mailer protocol (FTS-1026, FTS-1027) with support for the widely-deployed vendor extensions (NR, ND, MBT, PLZ, CRYPT, DES-CBC, ED25519).

Sibling library to fpc-msgbase (message storage), fpc-ftn-transport (PKT, ArcMail, queues), and comet (the mailer daemon that consumes all three). Same vendoring model: each library is its own repo with its own tests; consumers cp / rsync units from units/ into their build; bug fix → commit here → consumers pull at their own cadence → rebuild → deploy.

Scope

Concern Owned by
BinkP/1.1 wire protocol (frames, commands, state machine) fpc-binkp
CRAM-MD5, CRYPT, DES-CBC, ED25519 auth fpc-binkp
PLZ (zlib per-frame) compression fpc-binkp
NR (resume), ND (non-destructive), MBT (multi-batch) fpc-binkp
PKT / ArcMail / BSO queue fpc-ftn-transport
Message storage (JAM, Squish, ...) fpc-msgbase
Session dispatch, config, UI, logging backends consumer
Dialup / EMSI / modem framing out of scope — separate library

The library handles the wire. Consumers own everything above and below: the socket, the filesystem, the logging sink, the decision of which file to send next, what "secure" means for an inbound directory.

Status

Current: 0.1.0 — initial release. Core library compiles on all five targets (Linux, FreeBSD, Windows, OS/2, DOS go32v2). Reference TCP transport is UNIX-only; DOS has a dedicated Watt-32 transport; Windows / OS/2 consumers plug in their own IBPTransport.

Seven test programs green including a full two-session round-trip self-test. End-to-end smoke-tested on localhost (outbound ↔ inbound, 10 KB binary transferred with identical SHA-256, full CRAM-MD5 + CRYPT + MBT).

Naming

Unit prefix: bp.<category>.<name>.pasbp = "binkp". All units use {$mode objfpc}{$H+}{$modeswitch advancedrecords}.

Architecture

Step-based engine (modeled on Argus, not binkd):

Session := TBPSession.Create(bpsOutbound, Transport, Provider, Events);
Session.Config.LocalAddress := FTNAddr('1:218/720');
Session.Config.Advertise    := [bpOptNR, bpOptND, bpOptPLZ, bpOptMBT];
Session.Config.OnPostAuth   := @MyPostAuthHook;

while Session.NextStep do
begin
  // embedder is in control between every tick.
  // can cancel, inspect state, swap provider, etc.
end;

writeln('Result: ', Session.Result.Description);
Session.Free;

The embedder drives the loop. Each call to NextStep does a bounded unit of I/O + state-machine work and returns. This gives:

  • Testability. Replace Transport with a TMemoryStream- backed mock; feed in canned bytes; assert on emitted frames. No sockets required.
  • Cancellation. Stop calling NextStep; free the session.
  • Multiplexing. An event loop can drive N sessions on a single thread if the Transport implementation supports non-blocking I/O.
  • Observability. Inspect Session.Phase, Session.RemoteInfo between ticks. Hooks fire at every policy decision.

See docs/architecture.md for the full design, docs/api.md for the consumer-facing API reference, and docs/spec.md for the FTSC / FSP spec cheat sheet and wire-format notes.

Building

Once units land:

./build.sh                # all targets
./build.sh x86_64-linux   # just one
./run_tests.sh            # run test suite

Supported targets (matches fpc-ftn-transport): x86_64-linux, i386-go32v2, i386-os2, i386-win32, i386-linux, i386-freebsd.

License

GPL-2.0 — same as comet.

Layout

fpc-binkp/
├── build.sh              — multi-target build driver
├── CHANGELOG.md          — release notes, tagged vX.Y.Z
├── README.md             — this file
├── run_tests.sh          — test runner
├── fpc.cfg               — FPC search paths
├── docs/
│   ├── architecture.md   — engine design, hook taxonomy
│   ├── api.md            — public API reference
│   └── spec.md           — FTS-1026/1027 + FSP cheat sheet
├── examples/
│   ├── example_outbound.pas    — embed as originator
│   ├── example_inbound.pas     — embed as answerer
│   ├── example_mock.pas        — replay a captured session
│   └── example_multiplex.pas   — N sessions one thread
├── src/
│   ├── bp.version.pas         — BP_VERSION constant
│   ├── bp.types.pas           — enums, records, forward decls
│   ├── bp.frame.pas           — TBPFrame, read/write helpers
│   ├── bp.opt.pas             — OPT keyword parser / builder
│   ├── bp.cram.pas            — CRAM-MD5 (HMAC-MD5 RFC 2104)
│   ├── bp.crypt.pas           — FSP-1037 password-derived cipher
│   ├── bp.des.pas             — Argus DES-CBC stream
│   ├── bp.plz.pas             — zlib per-frame compression
│   ├── bp.transport.pas       — IBPTransport interface
│   ├── bp.provider.pas        — IBPFileProvider interface
│   ├── bp.events.pas          — IBPEventSink, event records
│   ├── bp.config.pas          — TBPSessionConfig record
│   └── bp.session.pas         — TBPSession engine (NextStep)
├── tests/
│   ├── test_frame.pas
│   ├── test_cram.pas
│   ├── test_crypt.pas
│   ├── test_des.pas
│   ├── test_plz.pas
│   ├── test_opt.pas
│   ├── test_session_outbound.pas
│   ├── test_session_inbound.pas
│   ├── vectors/               — captured traffic, one file per case
│   └── testutil.pas           — test harness helpers
└── units/                    — compiled output (.ppu/.o), per target
Description
FPC/FreePascal BinkP (FTS-1026/1027) library — Argus/binkd-compatible mailer protocol
Readme 706 KiB
Languages
Pascal 98.4%
Shell 1.6%