Skip to content

feat: pin HARICA ECC roots, explain the trust model, and fix the autoconnect race - #111

Merged
Stensel8 merged 6 commits into
mainfrom
claude/github-issue-109-review-ckj0ve
Aug 31, 2026
Merged

feat: pin HARICA ECC roots, explain the trust model, and fix the autoconnect race#111
Stensel8 merged 6 commits into
mainfrom
claude/github-issue-109-review-ckj0ve

Conversation

@Stensel8

@Stensel8 Stensel8 commented Aug 31, 2026

Copy link
Copy Markdown
Member

Follow-up to #110. Pins the HARICA ECC roots alongside the RSA pair, documents where every trusted certificate comes from and why, removes the ~32 second stall on first connect.

Type of change

  • feat — new page or feature
  • fix — bug fix (broken link, incorrect command, layout issue)
  • content — update or improve existing content

Details

Autoconnect race (1629ad4)

Measured on a real connection:

16:45:30.700  CTRL-EVENT-EAP-STARTED
              (nothing — no success, no failure)
16:46:02.340  SME: Trying to authenticate    31.6s later, retry
16:46:02.475  CTRL-EVENT-EAP-STARTED
16:46:02.577  CTRL-EVENT-EAP-SUCCESS         102ms

The handshake itself takes ~100 ms including four-deep chain validation. The 32 seconds before it is NetworkManager autoconnecting the moment the profile is added — before the user has typed anything — stalling in EAP-STARTED until it times out, and asking for the password a second time on the way. That was the double keyring prompt users saw.

The profile is now created with connection.autoconnect no so only the script activates it, then autoconnect is restored in a finally so a failed or timed-out activation does not leave a profile that never reconnects on its own.

Self-diagnosis when the pin goes stale (7d362a8)

A stale pin looked like a hang: NetworkManager kept retrying and nothing on screen said the certificate was the problem. On activation failure the script now reads the journal for certificate errors and, if it finds them, prints the error, the chain the server actually served, and what to do about it. Without journal access it falls back to the command the user can run themselves.

Also adopted from the GÉANT CAT installer: connection.permissions so the profile belongs to whoever ran the script rather than every account on the machine, and 802-1x.auth-timeout to bound a stalled EAP exchange.

Trust-on-first-use was considered and rejected: it would make the first connection rely on the system trust store (~150 CAs) where the official CAT method trusts two. Wider than what Saxion prescribes, so it stays out.

HARICA ECC roots (da9569a)

Four pinned roots instead of two. The RSA pair is what the server serves today; the ECC pair covers a move off RSA. All four are HARICA roots, so this remains a single CA operator.

HARICA publishes the cross certificate as expiring 2029-08-31. After that the chain must terminate at the self-signed 2021 root, which is already pinned — that transition is handled, and it is a date rather than a guess.

Dialogs now match the desktop: kdialog on KDE, zenity elsewhere. KDE installs frequently have zenity pulled in as somebody's dependency, which previously produced a GTK dialog on a Qt desktop.

Python requirement raised from 3.10 to 3.11 with a startup check so the stated minimum means something. This is a support decision, not a technical floor — the code runs on older versions.

Provenance of the pinned certificates (ac2d9ce)

All four roots were verified against HARICA's own repository at repo.harica.gr. Every SHA-1 fingerprint matched the bytes in the script.

The comment block now states which source does which job: CAT supplies the connection parameters (verified to agree), the live handshake shows which roots are in use, and HARICA supplies the certificates. None is trusted on its own.

Both guides gained a section letting readers verify this themselves — HARICA's fingerprints next to a command that prints what is actually installed locally. The command was run; it returns exactly the four values in the table.

Checklist

  • PR title follows the commit convention
  • Both EN and NL versions updated
  • No broken image references
  • flake8 and bandit -ll clean; published SHA256 matches the script in both guides

Closes #109

Claude added 4 commits August 31, 2026 17:00
Uit de journal van een echte verbinding:

  16:45:30.700  CTRL-EVENT-EAP-STARTED
                (niets - geen success, geen failure)
  16:46:02.340  SME: Trying to authenticate   (31,6s later, opnieuw)
  16:46:02.475  CTRL-EVENT-EAP-STARTED
  16:46:02.577  CTRL-EVENT-EAP-SUCCESS        (102ms)

De handshake zelf duurt honderd milliseconden, inclusief het valideren
van de vier lagen diepe keten. Die 32 seconden ervoor zijn NetworkManager
die al begint te verbinden zodra het profiel is toegevoegd, nog voordat
de gebruiker iets heeft kunnen typen. Die poging blijft in EAP-STARTED
hangen tot hij verloopt, en vraagt onderweg een tweede keer om het
wachtwoord - de dubbele prompt die gebruikers zagen.

Het profiel wordt nu aangemaakt met autoconnect uit, zodat alleen het
script zelf de verbinding opzet. Daarna gaat autoconnect weer aan, in een
finally, zodat het ook gebeurt als activatie faalt of de timeout raakt.
Anders bleef er een profiel achter dat nooit uit zichzelf verbindt.
Een verouderde pin zag eruit als een vastloper: NetworkManager bleef
proberen en nergens op het scherm stond dat het certificaat de oorzaak
was. Precies waarom #109 zo lang onverklaard bleef.

Faalt de activatie, dan leest het script nu de journal terug op
certificaatfouten. Vindt het die, dan toont het de fout, de keten die de
server werkelijk stuurde, en wat er moet gebeuren: meld de keten, en
gebruik --ignore-certificate om intussen te verbinden. Zonder journal-
toegang valt het terug op het commando dat de gebruiker zelf kan draaien.

Verder twee dingen overgenomen uit het CAT-installatiescript van GEANT:

  connection.permissions  het profiel is van wie het script draaide, niet
                          van elk account op de machine
  802-1x.auth-timeout     begrenst hoelang NetworkManager op een
                          vastgelopen EAP-uitwisseling blijft wachten

Trust-on-first-use is bewust niet gebouwd. Dat zou de eerste verbinding
laten leunen op de systeem-truststore, ongeveer 150 CA's, waar de
officiele CAT-methode er twee vertrouwt. Ruimer dan wat Saxion
voorschrijft, en dat is de grens die we niet overgaan.
Vier roots in plaats van twee. Het RSA-paar is wat de server vandaag
stuurt; het ECC-paar staat er voor als Saxion van RSA afstapt, zodat die
overstap dit script niet breekt. Alle vier komen uit het Mozilla
root-programma en zijn op SHA-256 geidentificeerd, niet op naam - zoals
HARICA TLS RSA Root CA 2021 laat zien, waarvan de self-signed en
cross-signed vorm dezelfde CN dragen maar verschillende certificaten
zijn.

Dialogen kiezen nu de toolkit die bij het bureaublad past. Op KDE staat
vaak zenity geinstalleerd als afhankelijkheid van iets anders, en dan
kreeg je een GTK-venster op een Qt-bureaublad. kdialog gaat daar nu voor,
zenity elders.

Python-eis van 3.10 naar 3.11, met een controle bij het starten zodat de
eis ook echt iets betekent. Dit is een ondersteuningskeuze, geen
technische: de code draait op oudere versies, maar alles wat actueel is
levert 3.11 of nieuwer.

De documentatie klopte op zeven punten niet meer. Belangrijkste: er stond
dat de officiele installer vastloopt door wijzigingen in NetworkManager.
Dat is niet zo, en we weten inmiddels beter - het is de verouderde CA in
hun profiel. Verder de vier roots, de vlaggen, de afhankelijkheden (geen
enkele buiten de standaardbibliotheek), en dat het handmatige nmcli-recept
naar een CA-bestand verwijst dat pas bestaat nadat het script gedraaid
heeft.
De vier gepinde roots zijn geverifieerd tegen HARICA's eigen repository
op repo.harica.gr. Alle vier de SHA-1 fingerprints kwamen overeen met de
bytes in dit script. Daarmee is de keten rond: geen enkele root staat
erin omdat een handshake hem aanbood, maar omdat de CA-operator hem
publiceert.

Het commentaarblok legt nu uit welke bron welke rol speelt. CAT levert de
verbindingsparameters, en die kloppen; alleen hun CA niet, en dat is
precies issue #109. De handshake vertelt welke roots in gebruik zijn.
HARICA levert de certificaten zelf. Geen van drieen wordt op zichzelf
vertrouwd.

Uit HARICA's repository blijkt ook dat het cross-certificaat op
2029-08-31 verloopt. Daarna moet de keten eindigen bij de self-signed
2021-root, die hier al vastligt. Die overgang is dus geregeld, en dat is
geen aanname meer maar een datum.

De documentatie krijgt in beide talen een sectie waarmee lezers dit zelf
kunnen natrekken: de fingerprints van HARICA ernaast, plus een commando
dat toont wat er daadwerkelijk op hun machine staat. Dat commando is
gedraaid en geeft exact de vier waarden uit de tabel.
Copilot AI lite review requested due to automatic review settings August 31, 2026 18:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Stensel8 Stensel8 self-assigned this Aug 31, 2026
Claude added 2 commits August 31, 2026 18:10
Het cross-certificaat verloopt 2029-08-31. Dat is de datum waarop de
keten moet gaan eindigen bij de self-signed 2021-root, en daarmee de
reden dat beide helften van het RSA-paar vastliggen in plaats van alleen
degene die de server nu stuurt. Stond alleen in de code, hoort ook op de
pagina waar mensen kijken als het misgaat.

Ook de datum waarop de fingerprints tegen HARICA's repository zijn
gecontroleerd, zodat de volgende onderhouder weet hoe oud die controle
is.
Vijftien em-dashes op de installatiepagina's, waarvan elf van mij. Het
leest als een tic en niet als de rest van de site. Vervangen door punten,
komma's en dubbele punten, zonder dat er betekenis verandert.

Ook de ene in het script zelf, in de melding dat het profiel bewaard is.
@Stensel8
Stensel8 merged commit 108c4ff into main Aug 31, 2026
7 checks passed
@Stensel8
Stensel8 deleted the claude/github-issue-109-review-ckj0ve branch August 31, 2026 18:51
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.

Bug: Eduroam installer script fails to authenticate

2 participants