nordisk-pairing 0.5.25

The boxes of an estate find each other: a seed each box is installed with, a one-time join against the front, a tunnel (WireGuard by default) they meet inside, roles decided once, a pairing loop each box runs itself, and the signal it reports. Shared by gunnar and holger; the laptop's xtask only lays machines, writes seeds and reads the signal. Design: .nornir/pairing-design.md (2026-09-24).
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
//! **The installer's mutual TLS — valid during bootstrap only.**
//!
//! The owner, 2026-09-24: the installer has a temporary mTLS certificate the
//! installing machines know, so they can contact the installer, which feeds
//! them what they need; and it is valid ONLY during bootstrap.
//!
//! One installer CA per MEDIUM (it was per lay until 2026-09-24 evening, and
//! that made every lay a new medium): minted by the laptop when the medium is
//! composed, its key kept beside the medium's receipt on the laptop (0600)
//! and pushed to each new front's door — never onto the medium, never onto a
//! box. It issues exactly three kinds of certificate:
//!
//! * **the door's** — the front's server certificate, for its utility address;
//!   every box PINS the installer CA, so a box talks to this door or to nothing
//!   (the join used to be plain HTTP, and a box believed whatever answered);
//! * **the bootstrap client certificate** — ON THE MEDIUM, with its key, the
//!   same for every box. A key on a medium is only as secret as the medium
//!   (it is uploaded to the cloud's storage), so this certificate is weak on
//!   purpose: it may only JOIN, the door accepts it only for a slot that has
//!   not joined yet, and it is refused outright once every slot has joined;
//! * **a box's own certificate** — signed at the first join from a request for
//!   a key the box minted itself (the private half never leaves the box). From
//!   then on that box speaks with it, and the bootstrap certificate is refused
//!   for its slot.
//!
//! **"Valid during bootstrap only" is the DOOR's rule, not an expiry.** When
//! every slot has joined the door refuses the bootstrap certificate outright
//! (`join-withdrawn`), and a slot that has joined refuses it for good
//! (`join-spent`) — per lay, because each lay's door has its own ledger. The
//! CA's own lifetime is the caller's choice, tied to the medium: long enough
//! that one medium serves many lays, and the medium is recomposed (with a new
//! CA) before it ends ([`cert_left`]). Pairing inside the tunnel then runs on
//! gunnar's own issuer, as it always has.
//!
//! Pure Rust (`rcgen` + `rustls` on `ring`, X25519MLKEM768 first —
//! [`crate::pqtls`]), blocking sockets: an OS-less
//! PID 1 and a laptop both drive it without an async runtime.

use rcgen::{BasicConstraints, CertificateParams, CertificateSigningRequestParams, DistinguishedName, DnType, ExtendedKeyUsagePurpose, IsCa, KeyPair, KeyUsagePurpose, SanType};
use rustls::pki_types::pem::PemObject;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName};
use std::net::{IpAddr, Ipv4Addr};
use std::sync::Arc;
use std::time::Duration;

/// The CN every bootstrap client certificate carries. A box's own certificate
/// carries its NAME; the door tells them apart by this.
pub const BOOTSTRAP_CN: &str = "bootstrap";

/// The CN of the installer's own client certificate — the ONLY client a VM's
/// bootstrap listener serves (0.3.0). A box name can never be this.
pub const INSTALLER_CN: &str = "installer";

/// **The one name every VM's bootstrap listener answers to** — a DNS SAN on
/// the bootstrap certificate and on every box certificate. The installer
/// checks the chain against the installer CA and this name, never the
/// address: the cloud hands the address out after the medium is composed.
pub const VM_SERVER_NAME: &str = "bootstrap.installer";

fn vm_sans() -> Vec<SanType> {
    match VM_SERVER_NAME.to_string().try_into() {
        Ok(n) => vec![SanType::DnsName(n)],
        Err(_) => Vec::new(),
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MtlsError(pub String);

impl std::fmt::Display for MtlsError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "REFUSED [pairing-mtls] {}", self.0)
    }
}

impl std::error::Error for MtlsError {}

fn e(what: &str) -> impl Fn(rcgen::Error) -> MtlsError + '_ {
    move |err| MtlsError(format!("{what}: {err}"))
}

/// A certificate and its private key, both PEM.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Issued {
    pub cert_pem: String,
    pub key_pem: String,
}

/// **The installer CA.** `key_pem` stays on the front.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InstallerCa {
    pub cert_pem: String,
    pub key_pem: String,
}

fn window(valid_for: Duration) -> (time::OffsetDateTime, time::OffsetDateTime) {
    // Five minutes of back-dating: a fresh box's clock is set from the front
    // only after it has joined, and a certificate "not yet valid" by a few
    // seconds of skew would refuse the very join that fixes the clock.
    window_back(valid_for, time::Duration::minutes(5))
}

fn window_back(valid_for: Duration, back: time::Duration) -> (time::OffsetDateTime, time::OffsetDateTime) {
    let now = time::OffsetDateTime::now_utc();
    (now - back, now + time::Duration::seconds(valid_for.as_secs() as i64))
}

/// **How far the DOOR's certificate is back-dated: a day.** The door issues
/// it when it starts, from the front's clock, and the BOX checks it with its
/// own clock — which has not been set yet (it is set from the front AFTER the
/// join, `gunnar-clock` fed by the door). A box whose clock runs behind the
/// front's by more than the five minutes the other certificates allow would
/// refuse the only door that can fix it. Nothing about the door certificate
/// is weaker for it: the CA is pinned, and the address is in the SAN.
pub const DOOR_BACKDATE: Duration = Duration::from_secs(24 * 3600);

/// **How long a certificate (PEM) has left**, from its `notAfter`; zero once
/// it has ended. `now_unix` is injected so a caller's test does not wait. The
/// laptop asks it of a medium's installer CA (re-mint and recompose before it
/// ends), the door of its CA (its own certificate lives as long as the CA).
pub fn cert_left(pem: &str, now_unix: i64) -> Result<Duration, MtlsError> {
    let (_, p) = x509_parser::pem::parse_x509_pem(pem.trim().as_bytes()).map_err(|err| MtlsError(format!("not a PEM certificate: {err}")))?;
    let cert = p.parse_x509().map_err(|err| MtlsError(format!("not an X.509 certificate: {err}")))?;
    let end = cert.validity().not_after.timestamp();
    Ok(Duration::from_secs(end.saturating_sub(now_unix).max(0) as u64))
}

/// Seconds since the epoch, now (for [`cert_left`]).
pub fn now_unix() -> i64 {
    time::OffsetDateTime::now_utc().unix_timestamp()
}

impl InstallerCa {
    /// Mint the CA for one lay of `estate`, valid for `valid_for` (hours).
    pub fn mint(estate: &str, valid_for: Duration) -> Result<InstallerCa, MtlsError> {
        let key = KeyPair::generate().map_err(e("the CA key"))?;
        let mut p = CertificateParams::default();
        let mut dn = DistinguishedName::new();
        dn.push(DnType::CommonName, format!("nordisk-pairing installer CA — {estate}"));
        p.distinguished_name = dn;
        p.is_ca = IsCa::Ca(BasicConstraints::Constrained(0));
        p.key_usages = vec![KeyUsagePurpose::KeyCertSign, KeyUsagePurpose::DigitalSignature];
        (p.not_before, p.not_after) = window(valid_for);
        let cert = p.self_signed(&key).map_err(e("the CA certificate"))?;
        Ok(InstallerCa { cert_pem: cert.pem(), key_pem: key.serialize_pem() })
    }

    /// The CA as an `rcgen` issuer, rebuilt from its PEM and key.
    fn issuer(&self) -> Result<(rcgen::Certificate, KeyPair), MtlsError> {
        let key = KeyPair::from_pem(&self.key_pem).map_err(e("the CA key"))?;
        let params = CertificateParams::from_ca_cert_pem(&self.cert_pem).map_err(e("the CA certificate"))?;
        let cert = params.self_signed(&key).map_err(e("the CA as issuer"))?;
        Ok((cert, key))
    }

    fn leaf(&self, cn: &str, sans: Vec<SanType>, purpose: Vec<ExtendedKeyUsagePurpose>, valid_for: Duration) -> Result<Issued, MtlsError> {
        self.leaf_back(cn, sans, purpose, window(valid_for))
    }

    fn leaf_back(&self, cn: &str, sans: Vec<SanType>, purpose: Vec<ExtendedKeyUsagePurpose>, validity: (time::OffsetDateTime, time::OffsetDateTime)) -> Result<Issued, MtlsError> {
        let (ca, ca_key) = self.issuer()?;
        let key = KeyPair::generate().map_err(e("a leaf key"))?;
        let mut p = CertificateParams::default();
        let mut dn = DistinguishedName::new();
        dn.push(DnType::CommonName, cn);
        p.distinguished_name = dn;
        p.subject_alt_names = sans;
        p.extended_key_usages = purpose;
        (p.not_before, p.not_after) = validity;
        let cert = p.signed_by(&key, &ca, &ca_key).map_err(e("a leaf certificate"))?;
        Ok(Issued { cert_pem: cert.pem(), key_pem: key.serialize_pem() })
    }

    /// The door's server certificate, for the front's utility address —
    /// back-dated by [`DOOR_BACKDATE`], because a box checks it with a clock
    /// nobody has set yet.
    pub fn issue_door(&self, utility: Ipv4Addr, valid_for: Duration) -> Result<Issued, MtlsError> {
        let back = time::Duration::seconds(DOOR_BACKDATE.as_secs() as i64);
        self.leaf_back("nordisk-pairing door", vec![SanType::IpAddress(IpAddr::V4(utility))], vec![ExtendedKeyUsagePurpose::ServerAuth], window_back(valid_for, back))
    }

    /// **The bootstrap certificate the MEDIUM carries** — the same for every
    /// VM of the medium. Since 0.3.0 it is first of all what each VM's
    /// bootstrap listener SERVES the installer with (server auth, the fixed
    /// name [`VM_SERVER_NAME`]). Client auth stays for the 0.2 join against a
    /// front-hosted join service, which holger may still run.
    pub fn issue_bootstrap(&self, valid_for: Duration) -> Result<Issued, MtlsError> {
        self.leaf(BOOTSTRAP_CN, vm_sans(), vec![ExtendedKeyUsagePurpose::ServerAuth, ExtendedKeyUsagePurpose::ClientAuth], valid_for)
    }

    /// **The installer's own certificate** (0.3.0, owner 2026-09-24): the
    /// client certificate the installer on the operator's machine shows every
    /// VM it connects OUT to. CN [`INSTALLER_CN`] — the one role a VM's
    /// bootstrap listener accepts. Minted per medium with the CA and kept
    /// beside it on the operator's machine (0600); it never leaves that
    /// machine. Back-dated a day: a VM checks it with a clock nobody has set.
    pub fn issue_installer(&self, valid_for: Duration) -> Result<Issued, MtlsError> {
        let back = time::Duration::seconds(DOOR_BACKDATE.as_secs() as i64);
        self.leaf_back(INSTALLER_CN, Vec::new(), vec![ExtendedKeyUsagePurpose::ClientAuth], window_back(valid_for, back))
    }

    /// **A box's own certificate**, from its signing request: the CN is the
    /// NAME the door gave the box (whatever the request asked for), the key is
    /// the box's.
    pub fn sign_box(&self, csr_pem: &str, name: &str, valid_for: Duration) -> Result<String, MtlsError> {
        if name == BOOTSTRAP_CN || name == INSTALLER_CN {
            return Err(MtlsError(format!("`{name}` is not a box name")));
        }
        let (ca, ca_key) = self.issuer()?;
        let mut csr = CertificateSigningRequestParams::from_pem(csr_pem).map_err(e("the box's signing request"))?;
        let mut dn = DistinguishedName::new();
        dn.push(DnType::CommonName, name);
        csr.params.distinguished_name = dn;
        // The VM name too: a VM that holds its own certificate serves its
        // bootstrap listener with it after a restart (0.3.0).
        csr.params.subject_alt_names = vm_sans();
        csr.params.is_ca = IsCa::NoCa;
        csr.params.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth, ExtendedKeyUsagePurpose::ClientAuth];
        (csr.params.not_before, csr.params.not_after) = window(valid_for);
        Ok(csr.signed_by(&ca, &ca_key).map_err(e("the box's certificate"))?.pem())
    }
}

impl InstallerCa {
    /// **A box's certificate renewed** (0.5.12): the SAME key and name as `current`, a new
    /// lifetime of `valid_for`, signed by this CA. No request is needed: the key is the box's
    /// own and stays on it.
    pub fn renew_box(&self, current: &str, valid_for: Duration) -> Result<String, MtlsError> {
        let (spki, cn) = key_and_name(current)?;
        if cn == BOOTSTRAP_CN || cn == INSTALLER_CN {
            return Err(MtlsError(format!("`{cn}` is not a box name")));
        }
        let (ca, ca_key) = self.issuer()?;
        let public = rcgen::SubjectPublicKeyInfo::from_der(&spki).map_err(e("the box's public key"))?;
        let mut p = CertificateParams::default();
        let mut dn = DistinguishedName::new();
        dn.push(DnType::CommonName, cn);
        p.distinguished_name = dn;
        p.subject_alt_names = vm_sans();
        p.is_ca = IsCa::NoCa;
        p.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth, ExtendedKeyUsagePurpose::ClientAuth];
        (p.not_before, p.not_after) = window(valid_for);
        Ok(p.signed_by(&public, &ca, &ca_key).map_err(e("the renewed certificate"))?.pem())
    }
}

impl InstallerCa {
    /// **The CA's own certificate renewed** (0.5.13, a planned roll before its end): the SAME
    /// key and name, a new lifetime. Every pin of the old certificate still holds — a trust
    /// anchor is its name and key — so nothing the boxes or the shop hold changes.
    pub fn renew_ca(&self, valid_for: Duration) -> Result<InstallerCa, MtlsError> {
        let key = KeyPair::from_pem(&self.key_pem).map_err(e("the CA key"))?;
        let mut p = CertificateParams::from_ca_cert_pem(&self.cert_pem).map_err(e("the CA certificate"))?;
        p.serial_number = None;
        (p.not_before, p.not_after) = window(valid_for);
        let cert = p.self_signed(&key).map_err(e("the renewed CA certificate"))?;
        Ok(InstallerCa { cert_pem: cert.pem(), key_pem: self.key_pem.clone() })
    }
}

/// Pure: **why `boot` is not a bootstrap pair a VM keeps for its next join** (0.5.13), or
/// `None`: a certificate named [`BOOTSTRAP_CN`] whose key is the one handed with it.
pub fn bootstrap_refusal(boot: &Issued) -> Option<String> {
    let (spki, cn) = match key_and_name(&boot.cert_pem) {
        Ok(v) => v,
        Err(err) => return Some(format!("REFUSED [rebootstrap-unreadable] the bootstrap certificate: {err}")),
    };
    if cn != BOOTSTRAP_CN {
        return Some(format!("REFUSED [rebootstrap-not-bootstrap] the certificate names `{cn}`, not a bootstrap certificate (`{BOOTSTRAP_CN}`)"));
    }
    match KeyPair::from_pem(&boot.key_pem) {
        Ok(k) if k.public_key_der() == spki => None,
        Ok(_) => Some("REFUSED [rebootstrap-other-key] the key handed is not the bootstrap certificate's".into()),
        Err(err) => Some(format!("REFUSED [rebootstrap-unreadable] the bootstrap key: {err}")),
    }
}

/// The DER public key and the CN a certificate (PEM) carries.
fn key_and_name(pem: &str) -> Result<(Vec<u8>, String), MtlsError> {
    let (_, p) = x509_parser::pem::parse_x509_pem(pem.trim().as_bytes()).map_err(|err| MtlsError(format!("not a PEM certificate: {err}")))?;
    let cert = p.parse_x509().map_err(|err| MtlsError(format!("not an X.509 certificate: {err}")))?;
    let cn = cert.subject().iter_common_name().next().and_then(|a| a.as_str().ok()).ok_or_else(|| MtlsError("the certificate names no CN".into()))?;
    Ok((cert.public_key().raw.to_vec(), cn.to_string()))
}

/// (notBefore, notAfter) of a certificate (PEM), unix seconds.
fn life(pem: &str) -> Result<(i64, i64), MtlsError> {
    let (_, p) = x509_parser::pem::parse_x509_pem(pem.trim().as_bytes()).map_err(|err| MtlsError(format!("not a PEM certificate: {err}")))?;
    let cert = p.parse_x509().map_err(|err| MtlsError(format!("not an X.509 certificate: {err}")))?;
    Ok((cert.validity().not_before.timestamp(), cert.validity().not_after.timestamp()))
}

/// The share of a certificate's life after which it is renewed: two thirds.
pub const RENEW_AT: (i64, i64) = (2, 3);

/// Pure: **is a certificate due for renewal at `now_unix`?** At two thirds of its life (or past
/// its end).
pub fn renewal_due(pem: &str, now_unix: i64) -> Result<bool, MtlsError> {
    let (from, to) = life(pem)?;
    let at = from + (to - from).max(0) * RENEW_AT.0 / RENEW_AT.1;
    Ok(now_unix >= at)
}

/// Pure: **why `new` is not a renewal of `current`**, or `None`: the same key, the same name, an
/// end no earlier.
pub fn renewal_refusal(current: &str, new: &str) -> Option<String> {
    let (old_key, old_cn) = match key_and_name(current) {
        Ok(v) => v,
        Err(e) => return Some(format!("REFUSED [renew-unreadable] this VM's own certificate: {e}")),
    };
    let (new_key, new_cn) = match key_and_name(new) {
        Ok(v) => v,
        Err(e) => return Some(format!("REFUSED [renew-unreadable] the renewed certificate: {e}")),
    };
    if new_key != old_key {
        return Some("REFUSED [renew-other-key] the certificate is for another key, not this VM's own".into());
    }
    if new_cn != old_cn {
        return Some(format!("REFUSED [renew-other-name] the certificate names `{new_cn}`, this VM is `{old_cn}`"));
    }
    match (life(current), life(new)) {
        (Ok((_, old_end)), Ok((_, new_end))) if new_end >= old_end => None,
        _ => Some("REFUSED [renew-not-later] the certificate ends before the one this VM holds".into()),
    }
}

/// **The CN of a certificate** (PEM) — what an attached estate's certificate
/// names (`<estate>/<box>`).
pub fn cert_cn(pem: &str) -> Result<String, MtlsError> {
    let (_, p) = x509_parser::pem::parse_x509_pem(pem.trim().as_bytes()).map_err(|err| MtlsError(format!("not a PEM certificate: {err}")))?;
    let cert = p.parse_x509().map_err(|err| MtlsError(format!("not an X.509 certificate: {err}")))?;
    let cn = cert.subject().iter_common_name().next().and_then(|a| a.as_str().ok()).ok_or_else(|| MtlsError("the certificate names no CN".into()))?;
    Ok(cn.to_string())
}

impl InstallerCa {
    /// **An attached estate's certificate** (f-attach-enrol): the central
    /// monetize's ATTACH CA signs the estate's own CSR — CN `cn`
    /// (`<estate>/<box>`), the estate's control-plane host as a SAN (a DNS
    /// name, or an IP), client AND server auth: the estate shows it calling the
    /// central, and the central's dial into it verifies it.
    pub fn sign_attached(&self, csr_pem: &str, cn: &str, host: &str, valid_for: Duration) -> Result<String, MtlsError> {
        let (ca, ca_key) = self.issuer()?;
        let mut csr = CertificateSigningRequestParams::from_pem(csr_pem).map_err(e("the estate's signing request"))?;
        let mut dn = DistinguishedName::new();
        dn.push(DnType::CommonName, cn);
        csr.params.distinguished_name = dn;
        csr.params.subject_alt_names = match host.parse::<IpAddr>() {
            Ok(ip) => vec![SanType::IpAddress(ip)],
            Err(_) => vec![SanType::DnsName(host.try_into().map_err(e("the estate's host name"))?)],
        };
        csr.params.is_ca = IsCa::NoCa;
        csr.params.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth, ExtendedKeyUsagePurpose::ClientAuth];
        (csr.params.not_before, csr.params.not_after) = window(valid_for);
        Ok(csr.signed_by(&ca, &ca_key).map_err(e("the estate's certificate"))?.pem())
    }
}

/// **A box's own key and its signing request.** The key stays on the box.
pub fn box_request() -> Result<(String, String), MtlsError> {
    let key = KeyPair::generate().map_err(e("the box key"))?;
    request_for(key)
}

/// A signing request for a key the box ALREADY holds (PEM) — a box that
/// minted its key on an earlier boot asks for the same key, not a new one.
pub fn box_request_for(key_pem: &str) -> Result<(String, String), MtlsError> {
    request_for(KeyPair::from_pem(key_pem).map_err(e("the box key"))?)
}

fn request_for(key: KeyPair) -> Result<(String, String), MtlsError> {
    let mut p = CertificateParams::default();
    let mut dn = DistinguishedName::new();
    dn.push(DnType::CommonName, "box");
    p.distinguished_name = dn;
    let csr = p.serialize_request(&key).map_err(e("the signing request"))?;
    Ok((csr.pem().map_err(e("the signing request as PEM"))?, key.serialize_pem()))
}

fn certs(pem: &str) -> Result<Vec<CertificateDer<'static>>, MtlsError> {
    let v: Vec<_> = CertificateDer::pem_slice_iter(pem.as_bytes()).collect::<Result<_, _>>().map_err(|err| MtlsError(format!("a certificate PEM: {err:?}")))?;
    if v.is_empty() {
        return Err(MtlsError("a certificate PEM with no certificate in it".into()));
    }
    Ok(v)
}

fn key(pem: &str) -> Result<PrivateKeyDer<'static>, MtlsError> {
    PrivateKeyDer::from_pem_slice(pem.as_bytes()).map_err(|err| MtlsError(format!("a private key PEM: {err:?}")))
}

/// ring, with X25519MLKEM768 offered first ([`crate::pqtls`]): the feed
/// crosses this TLS, and with it the estate's WireGuard pre-shared keys.
fn provider() -> Arc<rustls::crypto::CryptoProvider> {
    Arc::new(crate::pqtls::provider())
}

fn roots(ca_pem: &str) -> Result<rustls::RootCertStore, MtlsError> {
    let mut r = rustls::RootCertStore::empty();
    for c in certs(ca_pem)? {
        r.add(c).map_err(|err| MtlsError(format!("the installer CA as a root: {err}")))?;
    }
    Ok(r)
}

/// **The door's TLS**: its own certificate, and a client certificate from the
/// installer CA REQUIRED on every connection.
pub fn server_config(ca_pem: &str, door: &Issued) -> Result<Arc<rustls::ServerConfig>, MtlsError> {
    let verifier = rustls::server::WebPkiClientVerifier::builder_with_provider(Arc::new(roots(ca_pem)?), provider())
        .build()
        .map_err(|err| MtlsError(format!("the client verifier: {err}")))?;
    let cfg = rustls::ServerConfig::builder_with_provider(provider())
        .with_protocol_versions(&[&rustls::version::TLS13])
        .map_err(|err| MtlsError(format!("TLS 1.3: {err}")))?
        .with_client_cert_verifier(verifier)
        .with_single_cert(certs(&door.cert_pem)?, key(&door.key_pem)?)
        .map_err(|err| MtlsError(format!("the door's certificate: {err}")))?;
    Ok(Arc::new(cfg))
}

/// **A box's TLS**: the installer CA pinned as the ONLY root, and the client
/// certificate it presents (the bootstrap one, or its own after the first join).
pub fn client_config(ca_pem: &str, client: &Issued) -> Result<Arc<rustls::ClientConfig>, MtlsError> {
    let cfg = rustls::ClientConfig::builder_with_provider(provider())
        .with_protocol_versions(&[&rustls::version::TLS13])
        .map_err(|err| MtlsError(format!("TLS 1.3: {err}")))?
        .with_root_certificates(roots(ca_pem)?)
        .with_client_auth_cert(certs(&client.cert_pem)?, key(&client.key_pem)?)
        .map_err(|err| MtlsError(format!("the client certificate: {err}")))?;
    Ok(Arc::new(cfg))
}

/// The server name a box checks the door's certificate against: its address.
pub fn door_name(utility: Ipv4Addr) -> ServerName<'static> {
    ServerName::IpAddress(IpAddr::V4(utility).into())
}

/// The CN of the certificate a client presented — `bootstrap` or a box name.
/// The chain was already verified against the installer CA by the handshake.
pub fn peer_cn(conn: &rustls::ServerConnection) -> Option<String> {
    cn_of(conn.peer_certificates()?.first()?)
}

/// **The name the installer checks a VM's certificate against**
/// ([`VM_SERVER_NAME`]) — never the address it dialled (0.3.0).
pub fn vm_name() -> ServerName<'static> {
    ServerName::try_from(VM_SERVER_NAME).expect("VM_SERVER_NAME is a valid DNS name")
}

/// The CN of the certificate a VM SERVED the installer — `bootstrap`, or the
/// box's own name once it holds one. Verified against the installer CA and
/// [`VM_SERVER_NAME`] by the handshake.
pub fn server_cn(conn: &rustls::ClientConnection) -> Option<String> {
    cn_of(conn.peer_certificates()?.first()?)
}

fn cn_of(der: &CertificateDer<'_>) -> Option<String> {
    let (_, cert) = x509_parser::parse_x509_certificate(der.as_ref()).ok()?;
    let cn = cert.subject().iter_common_name().next()?.as_str().ok()?.to_string();
    Some(cn)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::{Read, Write};

    const H: Duration = Duration::from_secs(3600);

    /// A real TLS 1.3 handshake over loopback: the door sees `bootstrap`, then
    /// the box's own name; a certificate from ANOTHER CA is refused, and a box
    /// that pins the installer CA refuses a door it did not issue.
    #[test]
    fn a_box_joins_with_the_bootstrap_cert_then_speaks_as_itself_and_strangers_are_refused_both_ways() {
        let ca = InstallerCa::mint("fleet.test", H).unwrap();
        let door = ca.issue_door(Ipv4Addr::LOCALHOST, H).unwrap();
        let boot = ca.issue_bootstrap(H).unwrap();
        let (csr, box_key) = box_request().unwrap();
        let mine = Issued { cert_pem: ca.sign_box(&csr, "main", H).unwrap(), key_pem: box_key };
        let other = InstallerCa::mint("another", H).unwrap();
        let stranger = other.issue_bootstrap(H).unwrap();

        let serve = |client: Issued, pin: String| -> Result<String, String> {
            let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
            let addr = l.local_addr().unwrap();
            let scfg = server_config(&ca.cert_pem, &door).unwrap();
            let t = std::thread::spawn(move || {
                let (s, _) = l.accept().unwrap();
                let conn = rustls::ServerConnection::new(scfg).unwrap();
                let mut tls = rustls::StreamOwned::new(conn, s);
                let mut b = [0u8; 5];
                match tls.read_exact(&mut b) {
                    Ok(()) => {
                        let cn = peer_cn(&tls.conn).unwrap_or_default();
                        let _ = tls.write_all(cn.as_bytes());
                        tls.conn.send_close_notify();
                        let _ = tls.flush();
                        Ok(cn)
                    }
                    Err(err) => Err(err.to_string()),
                }
            });
            let ccfg = client_config(&pin, &client).map_err(|e| e.to_string())?;
            let s = std::net::TcpStream::connect(addr).unwrap();
            let conn = rustls::ClientConnection::new(ccfg, door_name(Ipv4Addr::LOCALHOST)).unwrap();
            let mut tls = rustls::StreamOwned::new(conn, s);
            let sent = tls.write_all(b"hello").and_then(|_| tls.flush());
            let mut back = String::new();
            let read = tls.read_to_string(&mut back);
            let server = t.join().unwrap();
            match (sent, read, server) {
                (Ok(()), Ok(_), Ok(cn)) if back == cn => Ok(cn),
                (s, r, sv) => Err(format!("sent {s:?} read {r:?} server {sv:?}")),
            }
        };
        assert_eq!(serve(boot.clone(), ca.cert_pem.clone()), Ok(BOOTSTRAP_CN.to_string()));
        assert_eq!(serve(mine, ca.cert_pem.clone()), Ok("main".to_string()), "the box speaks as the name the door gave it");
        assert!(serve(stranger, ca.cert_pem.clone()).is_err(), "a certificate from another CA is refused by the door");
        assert!(serve(boot, other.cert_pem.clone()).is_err(), "a box that pins the installer CA refuses a door it did not issue");
    }

    /// **The installer's mutual TLS is post-quantum** (2026-10-06): the feed
    /// crosses it — and with the feed every WireGuard pre-shared key of the
    /// estate — so the door and a box negotiate X25519MLKEM768
    /// ([`crate::pqtls`]), and a recording of the link opens for nobody later.
    #[test]
    fn the_door_and_a_box_negotiate_x25519mlkem768() {
        let ca = InstallerCa::mint("fleet.test", H).unwrap();
        let door = ca.issue_door(Ipv4Addr::LOCALHOST, H).unwrap();
        let boot = ca.issue_bootstrap(H).unwrap();
        let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
        let addr = l.local_addr().unwrap();
        let scfg = server_config(&ca.cert_pem, &door).unwrap();
        let t = std::thread::spawn(move || {
            let (s, _) = l.accept().unwrap();
            let mut tls = rustls::StreamOwned::new(rustls::ServerConnection::new(scfg).unwrap(), s);
            let mut b = [0u8; 5];
            tls.read_exact(&mut b).unwrap();
            tls.write_all(b"done!").unwrap();
            tls.flush().unwrap();
            tls.conn.negotiated_key_exchange_group().map(|g| g.name())
        });
        let ccfg = client_config(&ca.cert_pem, &boot).unwrap();
        let conn = rustls::ClientConnection::new(ccfg, door_name(Ipv4Addr::LOCALHOST)).unwrap();
        let mut tls = rustls::StreamOwned::new(conn, std::net::TcpStream::connect(addr).unwrap());
        tls.write_all(b"hello").unwrap();
        tls.flush().unwrap();
        let mut b = [0u8; 5];
        tls.read_exact(&mut b).unwrap();
        let client = tls.conn.negotiated_key_exchange_group().map(|g| g.name());
        assert_eq!((t.join().unwrap(), client), (Some(rustls::NamedGroup::X25519MLKEM768), Some(rustls::NamedGroup::X25519MLKEM768)));
    }

    /// The door's certificate is valid from a day back (a box checks it with
    /// a clock nobody has set yet); the other leaves keep five minutes. And
    /// what a certificate has left is read off it.
    #[test]
    fn the_door_certificate_is_back_dated_a_day_and_what_a_certificate_has_left_is_read_off_it() {
        let ca = InstallerCa::mint("fleet.test", 90 * 24 * H).unwrap();
        let now = now_unix();
        let nb = |pem: &str| {
            let der = certs(pem).unwrap().remove(0);
            let (_, c) = x509_parser::parse_x509_certificate(der.as_ref()).unwrap();
            c.validity().not_before.timestamp()
        };
        let door = ca.issue_door(Ipv4Addr::LOCALHOST, H).unwrap();
        let back = now - nb(&door.cert_pem);
        assert!((24 * 3600 - 60..=24 * 3600 + 60).contains(&back), "the door is back-dated a day, got {back} s");
        let boot = ca.issue_bootstrap(H).unwrap();
        assert!(now - nb(&boot.cert_pem) <= 5 * 60 + 60, "the bootstrap certificate keeps five minutes");
        let left = cert_left(&ca.cert_pem, now).unwrap();
        assert!(left > 89 * 24 * H && left <= 90 * 24 * H, "{left:?}");
        assert_eq!(cert_left(&ca.cert_pem, now + 91 * 24 * 3600).unwrap(), Duration::ZERO, "ended");
        assert!(cert_left("not a pem", now).is_err());
    }

    #[test]
    fn the_box_request_is_signed_with_the_door_given_name_and_bootstrap_is_not_a_name() {
        let ca = InstallerCa::mint("fleet.test", H).unwrap();
        let (csr, _) = box_request().unwrap();
        let pem = ca.sign_box(&csr, "twin", H).unwrap();
        let der = certs(&pem).unwrap().remove(0);
        let (_, cert) = x509_parser::parse_x509_certificate(der.as_ref()).unwrap();
        assert_eq!(cert.subject().iter_common_name().next().unwrap().as_str().unwrap(), "twin");
        assert!(ca.sign_box(&csr, BOOTSTRAP_CN, H).is_err());
        assert!(ca.sign_box("not a csr", "twin", H).is_err());
    }

    /// ★ **The installer CA renews ITSELF before its end** (0.5.13, the 180-day gap): the same
    /// key and name, a later end; a door and a box certificate issued by the RENEWED CA are taken
    /// by peers that still pin the OLD certificate — the boxes' seeds and the shop's custody need
    /// nothing.
    #[test]
    fn a_renewed_ca_keeps_its_key_and_name_and_the_old_pin_still_holds() {
        let ca = InstallerCa::mint("fleet.test", H).unwrap();
        let renewed = ca.renew_ca(180 * 24 * H).unwrap();
        assert_eq!(renewed.key_pem, ca.key_pem, "the same key");
        assert_ne!(renewed.cert_pem, ca.cert_pem);
        assert_eq!(key_and_name(&renewed.cert_pem).unwrap(), key_and_name(&ca.cert_pem).unwrap(), "the same key and name");
        assert!(cert_left(&renewed.cert_pem, 0).unwrap() > cert_left(&ca.cert_pem, 0).unwrap(), "a later end");
        let door = renewed.issue_door(Ipv4Addr::LOCALHOST, H).unwrap();
        let (csr, k) = box_request().unwrap();
        let mine = Issued { cert_pem: renewed.sign_box(&csr, "main", H).unwrap(), key_pem: k };
        let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
        let addr = l.local_addr().unwrap();
        let scfg = server_config(&ca.cert_pem, &door).unwrap();
        let t = std::thread::spawn(move || {
            let (s, _) = l.accept().unwrap();
            let mut tls = rustls::StreamOwned::new(rustls::ServerConnection::new(scfg).unwrap(), s);
            let mut b = [0u8; 5];
            tls.read_exact(&mut b).map(|_| peer_cn(&tls.conn).unwrap_or_default()).map_err(|e| e.to_string())
        });
        let ccfg = client_config(&ca.cert_pem, &mine).unwrap();
        let s = std::net::TcpStream::connect(addr).unwrap();
        let mut tls = rustls::StreamOwned::new(rustls::ClientConnection::new(ccfg, door_name(Ipv4Addr::LOCALHOST)).unwrap(), s);
        tls.write_all(b"hello").and_then(|_| tls.flush()).expect("the box takes the renewed CA's door under the old pin");
        assert_eq!(t.join().unwrap(), Ok("main".to_string()), "the door takes the renewed CA's box under the old pin");
    }

    /// One mTLS handshake: a box holding `mine` dials a door holding `door`, both pinning
    /// `pin`. The door's answer: the box's CN, or why either side refused.
    fn handshake(pin: &str, door: Issued, mine: Issued) -> Result<String, String> {
        let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
        let addr = l.local_addr().unwrap();
        let scfg = server_config(pin, &door).map_err(|e| e.to_string())?;
        let t = std::thread::spawn(move || {
            let (s, _) = l.accept().map_err(|e| e.to_string())?;
            let mut tls = rustls::StreamOwned::new(rustls::ServerConnection::new(scfg).unwrap(), s);
            let mut b = [0u8; 5];
            tls.read_exact(&mut b).map(|_| peer_cn(&tls.conn).unwrap_or_default()).map_err(|e| e.to_string())
        });
        let ccfg = client_config(pin, &mine).map_err(|e| e.to_string())?;
        let s = std::net::TcpStream::connect(addr).unwrap();
        let mut tls = rustls::StreamOwned::new(rustls::ClientConnection::new(ccfg, door_name(Ipv4Addr::LOCALHOST)).unwrap(), s);
        let sent = tls.write_all(b"hello").and_then(|_| tls.flush()).map_err(|e| format!("the box: {e}"));
        drop(tls);
        let heard = t.join().unwrap();
        sent.and(heard)
    }

    /// ★ **S21: day 200 with the original installer CA** (its 180 days are over) — a trust
    /// anchor is its name and key: certificates the EXPIRED CA issues still pass under the pin
    /// both sides hold, so an estate whose front missed the renewal still joins and re-admits;
    /// the CA is due, renews (same key, a later end) and the old pin keeps holding.
    #[test]
    fn day_200_with_the_original_ca_still_joins_and_the_ca_renews_under_the_old_pin() {
        let fresh = InstallerCa::mint("fleet.test", H).unwrap();
        let key = KeyPair::from_pem(&fresh.key_pem).unwrap();
        let mut p = CertificateParams::from_ca_cert_pem(&fresh.cert_pem).unwrap();
        let now = time::OffsetDateTime::now_utc();
        (p.not_before, p.not_after) = (now - time::Duration::days(200), now - time::Duration::days(20));
        let expired = InstallerCa { cert_pem: p.self_signed(&key).unwrap().pem(), key_pem: fresh.key_pem.clone() };
        let now_unix = now.unix_timestamp();
        assert_eq!(cert_left(&expired.cert_pem, now_unix).unwrap(), Duration::ZERO, "the CA certificate is past its end");
        assert!(renewal_due(&expired.cert_pem, now_unix).unwrap(), "and due");
        let issue = |ca: &InstallerCa| {
            let (csr, k) = box_request().unwrap();
            (ca.issue_door(Ipv4Addr::LOCALHOST, H).unwrap(), Issued { cert_pem: ca.sign_box(&csr, "main", H).unwrap(), key_pem: k })
        };
        let (door, mine) = issue(&expired);
        assert_eq!(handshake(&expired.cert_pem, door, mine), Ok("main".to_string()), "an expired anchor still anchors");
        let renewed = expired.renew_ca(180 * 24 * H).unwrap();
        assert!(cert_left(&renewed.cert_pem, now_unix).unwrap() > 170 * 24 * H, "renewed past day 200: a new lifetime");
        assert!(!renewal_due(&renewed.cert_pem, now_unix).unwrap());
        let (door, mine) = issue(&renewed);
        assert_eq!(handshake(&expired.cert_pem, door, mine), Ok("main".to_string()), "the boxes' old pin takes the renewed CA's certificates");
    }

}