xref: /inferno-os/module/spki.m (revision d6b4eae8eb0a5ca3119414005e483fedd63a62d6)
1Rawsexprs: module
2{
3	PATH:	con "rawsexprs.dis";
4
5	Sexp: adt {
6		pick {
7		String =>
8			s: string;
9			hint:	string;
10		Binary =>
11			data:	array of byte;
12			hint: string;
13		List =>
14			l:	cyclic list of ref Sexp;
15		}
16
17		unpack:	fn(a: array of byte): (ref Sexp, array of byte, string);
18		text:	fn(e: self ref Sexp): string;
19		packedsize:	fn(e: self ref Sexp): int;
20		pack:	fn(e: self ref Sexp): array of byte;
21	};
22
23	init:	fn();
24};
25
26SPKI: module
27{
28	PATH: con "/dis/lib/spki/spki.dis";
29
30	Hash: adt {
31		alg:	string;
32		hash:	array of byte;
33
34		sexp:	fn(h: self ref Hash): ref Sexprs->Sexp;
35		text:	fn(h: self ref Hash): string;
36		eq:	fn(h1: self ref Hash, h2: ref Hash): int;
37	};
38
39	Key: adt {
40		pk:	ref Keyring->PK;	# either pk/sk or hash might be nil
41		sk:	ref Keyring->SK;
42		nbits:	int;
43		halg:	string;	# basic signature hash algorithm
44		henc:	string;	# pre-signature encoding
45		hash:	list of ref Hash;
46
47		hashed:	fn(k: self ref Key, alg: string): array of byte;
48		hashexp:	fn(k: self ref Key, alg: string): ref Hash;
49		ishash:	fn(k: self ref Key): int;
50		public:	fn(k: self ref Key): ref Key;
51		sigalg:	fn(k: self ref Key): string;
52		text:	fn(k: self ref Key): string;
53		sexp:	fn(k: self ref Key): ref Sexprs->Sexp;
54		eq:	fn(k1: self ref Key, k2: ref Key): int;
55	};
56
57	Name: adt {
58		principal:	ref Key;
59		names:	list of string;
60
61		isprincipal:	fn(n: self ref Name): int;
62		local:	fn(n: self ref Name): ref Name;
63		islocal:	fn(n: self ref Name): int;
64		isprefix:	fn(n1: self ref Name, n2: ref Name): int;
65		text:	fn(n: self ref Name): string;
66		sexp:	fn(n: self ref Name): ref Sexprs->Sexp;
67		eq:	fn(n1: self ref Name, n2: ref Name): int;
68	};
69
70	Cert: adt {
71		e:	ref Sexprs->Sexp;	# S-expression, if originally parsed
72		issuer:	ref Name;
73		subject:	ref Subject;
74		valid:	ref Valid;
75		pick {
76		A or KH or O =>	# auth, keyholder or object
77			delegate:	int;
78			tag:	ref Sexprs->Sexp;
79		N =>	# name
80		}
81
82		text:	fn(c: self ref Cert): string;
83		sexp:	fn(c: self ref Cert): ref Sexprs->Sexp;
84	};
85
86	# the pick might move to a more general `Principal' structure,
87	# allowing compound and quoting principals
88	Subject: adt {
89		pick{
90		P =>
91			key:	ref Key;
92		N =>
93			name:	ref Name;
94		O =>
95			hash:	ref Hash;
96		KH =>
97			holder:	ref Name;
98		T =>
99			k, n:	int;
100			subs:	cyclic list of ref Subject;
101		}
102
103		eq:	fn(s1: self ref Subject, s2: ref Subject): int;
104		principal:	fn(s: self ref Subject): ref Key;
105		text:	fn(s: self ref Subject): string;
106		sexp:	fn(s: self ref Subject): ref Sexprs->Sexp;
107	};
108
109	Principal: adt[T] {
110		pick{
111		N =>
112			name:	ref Name;
113		Q =>
114			quoter:	T;
115			quotes:	cyclic ref Principal;
116		}
117	};
118
119	Signature: adt {
120		hash:	ref Hash;
121		key:	ref Key;	# find by hash if necessary
122		sa:	string;	# alg[-[encoding-]hash]
123		sig:	list of (string, array of byte);
124
125		algs:	fn(s: self ref Signature): (string, string, string);
126		sexp:	fn(s: self ref Signature): ref Sexprs->Sexp;
127		text:	fn(s: self ref Signature): string;
128	};
129
130	Seqel: adt {
131		pick{
132		C =>
133			c: ref Cert;
134		K =>
135			k: ref Key;
136		O =>
137			op: string;
138			args: list of ref Sexprs->Sexp;
139		S =>
140			sig: ref Signature;
141		RV =>	# <reval>
142			ok:	list of (string, string);
143			onetime:	array of byte;
144			valid:	ref Valid;
145		CRL =>
146			bad:	list of (string, string);
147			valid:	ref Valid;
148		Delta =>
149			hash:	string;
150			bad:	list of (string, string);
151			valid:	ref Valid;
152		E =>
153			exp:	ref Sexprs->Sexp;
154		}
155
156		sexp:	fn(se: self ref Seqel): ref Sexprs->Sexp;
157		text:	fn(se: self ref Seqel): string;
158	};
159
160	Valid: adt {
161		notbefore:	string;
162		notafter:	string;
163
164		intersect:	fn(a: self Valid, b: Valid): (int, Valid);
165		text:	fn(a: self Valid): string;
166		sexp:	fn(a: self Valid): ref Sexprs->Sexp;
167	};
168
169	Toplev: adt {
170		pick {
171		C =>
172			v:	ref Cert;
173		Sig =>
174			v:	ref Signature;
175		K =>
176			v:	ref Key;
177		Seq =>
178			v:	list of ref Seqel;
179		}
180
181		sexp:	fn(t: self ref Toplev): ref Sexprs->Sexp;
182		text:	fn(t: self ref Toplev): string;
183	};
184
185	init:	fn();
186
187	# parse structures
188	parse:	fn(s: ref Sexprs->Sexp): (ref Toplev, string);
189	parseseq:	fn(s: ref Sexprs->Sexp): list of ref Seqel;
190	parsecert:	fn(s: ref Sexprs->Sexp): ref Cert;
191	parsesig:	fn(s: ref Sexprs->Sexp): ref Signature;
192	parsename:	fn(s: ref Sexprs->Sexp): ref Name;
193	parsekey:	fn(s: ref Sexprs->Sexp): ref Key;
194	parsehash:	fn(s: ref Sexprs->Sexp): ref Hash;
195	parsecompound:	fn(s: ref Sexprs->Sexp): ref Name;
196	parsevalid:	fn(s: ref Sexprs->Sexp): ref Valid;
197
198	# signature checking
199	checksig:	fn(c: ref Cert, sig: ref Signature): string;
200	sig2icert:	fn(sig: ref Signature, signer: string, exp: int): ref Keyring->Certificate;
201
202	# signature making
203	signcert:	fn(c: ref Cert, sigalg: string, key: ref Key): (ref Signature, string);
204	signbytes:	fn(a: array of byte, sigalg: string, key: ref Key): (ref Signature, string);
205
206	# tags
207	maketag:	fn(e: ref Sexprs->Sexp): ref Sexprs->Sexp;
208	tagintersect:	fn(t1: ref Sexprs->Sexp, t2: ref Sexprs->Sexp): ref Sexprs->Sexp;
209	tagimplies:	fn(t1: ref Sexprs->Sexp, t2: ref Sexprs->Sexp): int;
210
211	# hash canonical s-expression
212	hashbytes:	fn(a: array of byte, alg: string): array of byte;
213	hashexp:	fn(e: ref Sexprs->Sexp, alg: string): array of byte;
214
215	# convert between date and time strings and Inferno form
216	date2epoch:	fn(s: string): int;	# YYYY-MM-DD_HH:MM:SS
217	epoch2date:	fn(t: int): string;
218	time2secs:	fn(s: string): int;	# HH:MM:SS
219	secs2time:	fn(t: int): string;
220
221	# misc
222	sigalgs:	fn(algs: string): (string, string, string);
223
224	# debugging
225	dump:	fn(s: string, a: array of byte);
226};
227
228Proofs: module
229{
230	Proof: adt {
231		n:	int;
232
233		parse:	fn(s: string): ref Proof;
234		sexp:	fn(p: self ref Proof): ref Sexprs->Sexp;
235		text:	fn(p: self ref Proof): string;
236	};
237
238	init:	fn(): string;
239};
240
241Verifier: module
242{
243	PATH:	con "/dis/lib/spki/verifier.dis";
244
245	Speaksfor: adt {
246		subject:	ref SPKI->Subject;
247		name:	ref SPKI->Name;
248		regarding:	ref Sexprs->Sexp;
249		valid:	ref SPKI->Valid;
250	};
251
252	init:	fn();
253	verify:	fn(seq: list of ref SPKI->Seqel): (ref Speaksfor, list of ref SPKI->Seqel, string);
254};
255