Skip to content

minorbug/certainly

Repository files navigation

Certainly

Modern TLS 1.3 for classic Mac OS 9.

Postman example making a POST to api.anthropic.com/v1/messages over TLS 1.3, running in SheepShaver on Mac OS 9

The Postman example app, running on Mac OS 9 in SheepShaver. The connection worked BTW, I'm not screenshotting my API key :)

Certainly is a static C library that bridges BearSSL to Open Transport and exposes a non-blocking, pump-loop API designed for the cooperative Mac OS 9 Toolbox event model. It ships with a hand-picked set of modern root CAs (ISRG, Google, DigiCert, Amazon, Starfield), validates certificates against them, and negotiates TLS 1.3 (X25519, AES-GCM / ChaCha20-Poly1305) with a TLS 1.2 fallback for servers that don't yet speak 1.3. Built with Retro68 (GCC 12, C99).

MIT License


Is this safe?

God no.

This is a hobby and research project. I have decades of coding experience but I am not a security expert, and this has not been audited by anyone who is. It exists because writing a TLS 1.3 stack for a 27-year-old operating system is genuinely interesting — not because the world needs another way to put Mac OS 9 on the internet.

Mac OS 9.2.2 predates most of the security hardening modern operating systems take for granted — no enforced memory protection between applications, no address space layout randomization, no privilege separation, and a network stack written long before the modern threat landscape existed. Even with TLS 1.3 working correctly at the library level, the broader environment is almost certainly soft in ways nobody has catalogued. Please don't use this for anything you'd regret losing.

Research software, no warranty. Certainly is provided "as is," without warranty of any kind — no guarantee that it works, that it's secure, or that it's fit for any particular purpose. The authors are not liable for any claims or damages arising from its use. This is the standard MIT bargain, spelled out here so it isn't a surprise. The full legal text:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

See LICENSE for the full MIT terms.

Quick start

#include <certainly.h>

MacTLS_Init();
MacTLS_Context *ctx = MacTLS_Create("api.example.com", 443);

while (running) {
    EventRecord ev;
    WaitNextEvent(everyEvent, &ev, 1, NULL);
    /* ... handle ev ... */

    switch (MacTLS_Pump(ctx)) {
    case kMacTLS_Connected:
        MacTLS_Write(ctx, request, strlen(request));
        n = MacTLS_Read(ctx, buf, sizeof(buf));
        break;
    case kMacTLS_Closed:
    case kMacTLS_Error:
        running = 0;
        break;
    default: break;
    }
}

MacTLS_Close(ctx);
MacTLS_Shutdown();

The contract is the pump loop: call MacTLS_Pump from your WaitNextEvent loop, react to the state it returns. The library never blocks and never spins; every operation yields before the next one begins.

After kMacTLS_Connected, MacTLS_GetVersion returns kMacTLS_Version12 or kMacTLS_Version13 so you can show users which protocol was negotiated.


How it works

TLS 1.3 first, BearSSL as fallback.

MacTLS_Create starts with a handwritten TLS 1.3 ClientHello that also advertises TLS 1.2 cipher suites. If the server responds with TLS 1.3, the custom handshake in tls13_handshake.c drives the connection — HKDF key schedule, X25519 key exchange, and AEAD-only record layer (tls13_keysched.c, tls13_record.c). If the server selects TLS 1.2, the connection is reset and BearSSL's T0 engine takes over for the full handshake.

SHA-384 cipher suites are explicitly rejected. Keeping a single 256-bit transcript hash (SHA-256) lets the key schedule fit in the memory budget of a cooperative Mac OS 9 app without resorting to dynamic allocation tricks.

Open Transport async TCP, no threads.

ot_transport.c drives Open Transport's async notifier model. Every OT call that can yield does so; completion is polled from MacTLS_Pump without requiring the Thread Manager or any blocking calls. This is the only way to do non-blocking network I/O on Mac OS 9 without breaking the cooperative scheduler.

Trust anchors baked in at build time.

ca_roots.c is generated by tools/generate_ca_roots.sh, which downloads ten root CA certificates directly from their issuers (Let's Encrypt / ISRG, Google Trust Services, DigiCert, Amazon Trust Services, and Starfield) and feeds them through brssl ta to produce the C trust anchor structures. Certificate chain validation runs through BearSSL's X.509 engine in both the TLS 1.2 and TLS 1.3 paths.


Examples

simple_get — Sweeps a list of public HTTPS endpoints, prints the HTTP status and negotiated TLS version ([1.2] / [1.3]) for each, and writes a log to certainly.log on the host filesystem. Useful for regression testing after transport or handshake changes.

postman — A full-featured HTTPS request builder with a platinum-theme Toolbox UI: method picker, editable URL / headers / body fields, a Send button, status line (shows the negotiated TLS version), and a scrollable response pane. Handles chunked transfer encoding. Defaults to the Anthropic Messages API. See the screenshot above.


Building

Requirements

  • Retro68 on PATH
  • CMake 3.12 or newer
  • BearSSL sources under bearssl/

Library and examples

mkdir -p build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=$RETRO68/cmake/retro68.toolchain.cmake ..
make

Produces libcertainly.a and a .dsk disk image for each example. Mount the images in SheepShaver, QEMU, or a real PowerMac.

Host-side tests

cd tests/host && make test

Runs the TLS 1.3 key schedule tests against RFC 8448 vectors and the HTTP request/response unit tests on the developer machine — no emulator needed. Run these before committing any change to the key schedule or HTTP parser.


Running on Mac OS 9

See docs/EMULATORS.md for step-by-step setup of SheepShaver (recommended) and QEMU, including ROM and disk image sources, networking configuration, and the launch scripts (run-sheepshaver.sh, run-macos9.sh).


Repository layout

include/certainly.h        Public API — source of truth for callers
src/
  certainly.c              Public-API entry points + BearSSL/OT glue
  ot_transport.c           Open Transport async TCP
  tls13_handshake.c        TLS 1.3 handshake state machine
  tls13_keysched.c         TLS 1.3 HKDF key schedule
  tls13_record.c           TLS 1.3 record layer (AEAD)
  ca_roots.c               Mozilla trust anchors (generated — do not edit)
  entropy.c                Entropy collection for PRNG seeding
bearssl/                   Vendored BearSSL
examples/
  simple_get/              HTTPS GET sweep across many endpoints
  postman/                 Interactive HTTPS request builder (UI app)
tests/host/                Host-side unit tests (native cc, not Retro68)
docs/                      Design notes and emulator setup
tools/                     CA bundle regeneration script

Security notes

  • AEAD-only cipher suites. No RSA key exchange, no static DH, no CBC, no SHA-1.
  • ChaCha20-Poly1305 is preferred over AES-GCM on PowerPC hardware, where AES has no hardware acceleration.
  • Trust anchors are baked in at build time. The regeneration script is in tools/.
  • Client-only. Not a general-purpose TLS toolkit, not security-audited. Use it to connect to well-known HTTPS endpoints — not to build a server.
  • No session resumption; every connection performs a full handshake.

Credits

Certainly is built on the shoulders of a lot of generous open-source work. The interesting parts of this project are all downstream of these people and projects.

Cryptography

  • BearSSL by Thomas Pornin — the underlying TLS engine. Certainly's TLS 1.2 path runs BearSSL's T0 engine end-to-end, and the TLS 1.3 path borrows BearSSL's X.509 validator, AEAD primitives (AES-GCM, ChaCha20-Poly1305), HKDF/HMAC/SHA-256, and the X25519 implementation. The entire library is essentially a thin Mac OS 9 transport wrapper around BearSSL. (MIT)

Toolchain

  • Retro68 by Wolfgang Thaller and contributors — the GCC 12 cross-compiler, linker, and resource tooling that makes it possible to build classic Mac OS PPC binaries on a modern host. Without Retro68 this project simply does not exist. (Various OSS licenses; see Retro68 for details.)
  • Apple Universal Interfaces 3.4 — the canonical Mac OS Toolbox headers (Quickdraw, Open Transport, Files, Events, etc.), redistributed via Retro68.

Trust anchors

Root certificates downloaded directly from each CA, then converted to BearSSL br_x509_trust_anchor structs via brssl ta:

Standards

  • RFC 8446 — TLS 1.3 protocol specification
  • RFC 8448 — Example handshake traces, used as test vectors in tests/host/test_keysched.c
  • RFC 7748 — X25519 key exchange
  • RFC 5869 — HKDF

Emulation and disk images

For developing without real hardware:

  • SheepShaver — PowerPC Mac emulator, originally by Christian Bauer and Gwenolé Beauchesne, now maintained as part of the macemu repo by kanjitalk755 and contributors. (GPL)
  • QEMU — system emulator, used here in qemu-system-ppc / mac99 mode. (GPL) Mac OS 9, the Mac Toolbox, Open Transport, and the Old World ROM are trademarks and copyrights of Apple Inc. Nothing in this repo is distributed by Apple or endorsed by Apple, and this project intentionally does not mirror, link to, or otherwise redistribute any Apple-owned binaries. You'll need to bring your own legally obtained Mac OS 9 install media and ROM file to actually run anything — ideally from a real Mac or a CD you own.

License

Certainly itself is MIT — see LICENSE.

Vendored and referenced components keep their own licenses; BearSSL is MIT, Retro68 is a mix of GPL/BSD/MIT (component-by-component, see its repository), and the emulators (SheepShaver, QEMU) are GPL. None of those licenses are inherited by Certainly because Certainly does not vendor or statically link those projects — BearSSL is the only third-party code included in this repository's build output, and it is MIT-compatible.

About

Modern TLS 1.3 for classic Mac OS 9

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages