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
//! **The operator's act, performed by the suite** (yog's `docs/REMOTE.md`
//! §1.4).
//!
//! The seat mints nothing. A certificate and its key are issued by the
//! operator's own CA on the box that holds it and carried to the seat by hand —
//! so there is no production caller here, and there must never be one: a seat
//! that could provision itself over the wire would be a seat any wire could
//! provision. What the suite needs is a channel to test, and the honest way to
//! get one is to do out of band exactly what the operator does out of band.
//!
//! It shells to `openssl`, which is the tool an operator uses and the tool yog's
//! own mint recipe uses. **This file is the crate's one spawn site**
//! (`rules/no-bare-command.yml`, `rules/no-bare-fork.yml`): the seat forks
//! nothing in production, so the confinement rules name the one place that
//! does. Nothing is committed — a fixture key in a tree is a private key in a
//! repository.
//!
//! **What each leaf says**, and every fact here is REMOTE's rather than this
//! file's:
//!
//! - the **engine** leaf carries `serverAuth` and a SAN naming loopback, which
//! is what a client verifies against what it dialled (REMOTE §8: the server
//! leaf always carries `IP:127.0.0.1`, because a window is a client of
//! loopback unconditionally);
//! - the **seat** leaf carries `clientAuth` and no organizational unit, which
//! is operator grade — REMOTE §4.2's default-operator rule, where a subject
//! that says nothing about a grade is the whole boundary.
use Path;
use Command;
/// The CA's own key. It never leaves the scratch directory, and no production
/// path knows the name.
const CA_KEY: &str = "ca.key";
/// The curve every key is drawn on.
const CURVE: &str = "ec_paramgen_curve:P-256";
/// How long a minted certificate is good for. A day, because the longest thing
/// the suite does with one is finish.
const DAYS: &str = "1";
/// The common name the suite's seat presents.
pub const SEAT_NAME: &str = "lernie-test-seat";
/// The engine leaf's basename and common name.
pub const ENGINE: &str = "engine";
/// Mint a CA and both leaves into `dir`, in the layout
/// [`material`](crate::channel::material) reads: the seat's pair is written as
/// `client.pem`/`client.key`, which is the spelling REMOTE §8.2 fixes for a
/// client-side directory.
pub
/// [`material`], plus the address file — the whole of what one provisioned
/// channel holds, answered as the material a channel opens from. The tests that
/// stand an [`Engine`](super::engine::Engine) up do not use it: an engine binds
/// a kernel-chosen port and writes the address itself, because only the
/// listener knows what `:0` became.
pub
/// The self-signed operator CA both ends verify against.
/// One leaf: a key and a bare request, then the signature that carries the two
/// facts the issuer decides — the subject alternative name and the extended key
/// usage.
///
/// The extensions travel in a file rather than through `req -addext` with
/// `x509 -copy_extensions`, which is OpenSSL-only: LibreSSL ships as `openssl`
/// on macOS and refuses that flag outright. `-extfile`/`-extensions` is the
/// spelling both toolsets have, and it is the more honest model besides — what
/// a certificate asserts is decided by whoever signs it, not by whoever asked.
/// **Re-mint this box's own pair as FOOT grade**, over the operator-grade one
/// [`material`] laid down — REMOTE §4.2's misconfiguration, performed the way
/// an operator performs it by accident: one `-subj`, one attribute longer. The
/// word is the CA's here and the reader's in [`leaf`](crate::channel::leaf);
/// they are two parties, and the suite is what proves they agree.
///
/// `named` is whether the subject states a common name at all. A leaf that says
/// foot and names nobody is exactly as wrong, and it is the only way to reach
/// the half of the sentence that has no client to quote.
pub
/// One path, as the string `openssl` takes.
/// One `openssl` run. A failure is the scaffolding's own, so it dies here with
/// the tool's sentence rather than becoming a confusing refusal three layers up.