@andrewheberle/serverless-ssh-ca 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -1
- package/dist/api/operations.d.ts +49 -0
- package/dist/api/operations.d.ts.map +1 -0
- package/dist/api/operations.js +175 -0
- package/dist/api/operations.js.map +1 -0
- package/dist/api/schema.d.ts +71 -0
- package/dist/api/schema.d.ts.map +1 -0
- package/dist/api/schema.js +107 -0
- package/dist/api/schema.js.map +1 -0
- package/dist/api/v3/index.d.ts.map +1 -1
- package/dist/api/v3/index.js +13 -202
- package/dist/api/v3/index.js.map +1 -1
- package/dist/api/v3/schema.d.ts +23 -68
- package/dist/api/v3/schema.d.ts.map +1 -1
- package/dist/api/v3/schema.js +10 -100
- package/dist/api/v3/schema.js.map +1 -1
- package/dist/api/v4/index.d.ts +8 -0
- package/dist/api/v4/index.d.ts.map +1 -0
- package/dist/api/v4/index.js +155 -0
- package/dist/api/v4/index.js.map +1 -0
- package/dist/api/v4/schema.d.ts +268 -0
- package/dist/api/v4/schema.d.ts.map +1 -0
- package/dist/api/v4/schema.js +182 -0
- package/dist/api/v4/schema.js.map +1 -0
- package/dist/certificate.d.ts +9 -6
- package/dist/certificate.d.ts.map +1 -1
- package/dist/certificate.js +55 -99
- package/dist/certificate.js.map +1 -1
- package/dist/db/index.d.ts +17 -5
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +39 -23
- package/dist/db/index.js.map +1 -1
- package/dist/krl.d.ts +1 -1
- package/dist/krl.d.ts.map +1 -1
- package/dist/krl.js +9 -163
- package/dist/krl.js.map +1 -1
- package/dist/proof.d.ts +36 -7
- package/dist/proof.d.ts.map +1 -1
- package/dist/proof.js +53 -21
- package/dist/proof.js.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +3 -1
- package/dist/router.js.map +1 -1
- package/dist/ssh/certificate.d.ts +93 -0
- package/dist/ssh/certificate.d.ts.map +1 -0
- package/dist/ssh/certificate.js +178 -0
- package/dist/ssh/certificate.js.map +1 -0
- package/dist/ssh/encoding.d.ts +41 -0
- package/dist/ssh/encoding.d.ts.map +1 -0
- package/dist/ssh/encoding.js +70 -0
- package/dist/ssh/encoding.js.map +1 -0
- package/dist/ssh/keys.d.ts +80 -0
- package/dist/ssh/keys.d.ts.map +1 -0
- package/dist/ssh/keys.js +249 -0
- package/dist/ssh/keys.js.map +1 -0
- package/dist/ssh/signer.d.ts +35 -0
- package/dist/ssh/signer.d.ts.map +1 -0
- package/dist/ssh/signer.js +99 -0
- package/dist/ssh/signer.js.map +1 -0
- package/dist/types.d.ts +12 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +40 -21
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +87 -54
- package/dist/utils.js.map +1 -1
- package/openapi.json +1542 -1
- package/package.json +4 -3
- package/src/api/operations.ts +211 -0
- package/src/api/schema.ts +137 -0
- package/src/api/v3/index.ts +20 -248
- package/src/api/v3/schema.ts +26 -125
- package/src/api/v4/index.ts +265 -0
- package/src/api/v4/schema.ts +235 -0
- package/src/certificate.ts +62 -123
- package/src/db/index.ts +41 -26
- package/src/krl.ts +10 -195
- package/src/proof.ts +65 -31
- package/src/router.ts +3 -1
- package/src/ssh/certificate.ts +236 -0
- package/src/ssh/encoding.ts +81 -0
- package/src/ssh/keys.ts +294 -0
- package/src/ssh/signer.ts +129 -0
- package/src/types.ts +12 -18
- package/src/utils.ts +99 -69
package/README.md
CHANGED
|
@@ -239,12 +239,66 @@ sequenceDiagram
|
|
|
239
239
|
deactivate Client
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
+
## API
|
|
243
|
+
|
|
244
|
+
The CA serves two versions of its API, which are documented in OpenAPI
|
|
245
|
+
format at `/docs` and in [openapi.json](openapi.json):
|
|
246
|
+
|
|
247
|
+
| Action | v3 | v4 |
|
|
248
|
+
|--------------------------|---------------------------------|-------------------------------------------------|
|
|
249
|
+
| Get the CA public key | `GET /api/v3/ca` | `GET /api/v4/ca` |
|
|
250
|
+
| Request user certificate | `POST /api/v3/user/certificate` | `POST /api/v4/user/certificates` |
|
|
251
|
+
| Revoke user certificate | `POST /api/v3/user/revoke` | `DELETE /api/v4/user/certificates/{serial}` |
|
|
252
|
+
| Get user KRL | `GET /api/v3/user/krl` | `GET /api/v4/user/krl` |
|
|
253
|
+
| Request host certificate | `POST /api/v3/host/certificate` | `POST /api/v4/host/certificates` |
|
|
254
|
+
| Renew host certificate | `POST /api/v3/host/renew` | `POST /api/v4/host/certificates/{serial}/renew` |
|
|
255
|
+
| Revoke host certificate | `POST /api/v3/host/revoke` | `DELETE /api/v4/host/certificates/{serial}` |
|
|
256
|
+
| Get host KRL | `GET /api/v3/host/krl` | `GET /api/v4/host/krl` |
|
|
257
|
+
|
|
258
|
+
### Proof of Possession
|
|
259
|
+
|
|
260
|
+
Requests that use an SSH key prove possession of its private key by including
|
|
261
|
+
a proof of the form `${timestamp}.${fingerprint}.${signature}`, where
|
|
262
|
+
`timestamp` is the time in milliseconds since the Unix epoch, `fingerprint` is
|
|
263
|
+
the SHA256 fingerprint of the public key (for example
|
|
264
|
+
`SHA256:79mq0wtpQMTvS4+Of8VzLN0qmYWNUyTXYmqKwhEgSLs`) and `signature` is the
|
|
265
|
+
BASE64 encoded armored SSHSIG signature (as produced by `ssh-keygen -Y sign`)
|
|
266
|
+
of the signed data. The proof is rejected if the timestamp is outside of
|
|
267
|
+
`CERTIFICATE_REQUEST_TIME_SKEW_MAX` of the time on the CA.
|
|
268
|
+
|
|
269
|
+
In v3 the proof is sent as the `proof` property of the request body and the
|
|
270
|
+
signed data is `${timestamp}.${fingerprint}` using the
|
|
271
|
+
`proof-of-possession@com.github.serverless-ssh-ca.andrewheberle` namespace.
|
|
272
|
+
As this does not say which request the proof is for, a proof captured from one
|
|
273
|
+
request may be replayed against another endpoint while it is valid.
|
|
274
|
+
|
|
275
|
+
In v4 the proof is sent in the `Proof-Of-Possession` header and is bound to
|
|
276
|
+
the request it is made for. The signed data is
|
|
277
|
+
`${timestamp}.${fingerprint}.${METHOD} ${path}` using the
|
|
278
|
+
`request-proof-of-possession@com.github.serverless-ssh-ca.andrewheberle`
|
|
279
|
+
namespace, where `${METHOD} ${path}` is the request as documented in the
|
|
280
|
+
OpenAPI schema with any parameters filled in, for example:
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
1765696780805.SHA256:79mq0wtpQMTvS4+Of8VzLN0qmYWNUyTXYmqKwhEgSLs.DELETE /api/v4/user/certificates/12345678901234567890
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Only `${timestamp}.${fingerprint}.${signature}` is sent, as the CA rebuilds
|
|
287
|
+
the request part from the request it receives. The path does not change if
|
|
288
|
+
the CA is served behind a proxy under another path, and serials in the path
|
|
289
|
+
are written in decimal without leading zeros.
|
|
290
|
+
|
|
291
|
+
In v4 the public key for a revocation or renewal is taken from the proof and
|
|
292
|
+
the certificate respectively, so it is not sent separately.
|
|
293
|
+
|
|
242
294
|
## Configuration
|
|
243
295
|
|
|
244
296
|
### CA Private Key
|
|
245
297
|
|
|
246
298
|
The CA private key is read from the `PRIVATE_KEY` Secrets Store binding and
|
|
247
|
-
must be an Ed25519 or ECDSA (`nistp256`, `nistp384` or
|
|
299
|
+
must be an unencrypted Ed25519 or ECDSA (`nistp256`, `nistp384` or
|
|
300
|
+
`nistp521`) key in OpenSSH format, which is what `ssh-keygen` creates by
|
|
301
|
+
default:
|
|
248
302
|
|
|
249
303
|
```sh
|
|
250
304
|
ssh-keygen -t ed25519 -N "" -C "" -f ssh-ca
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Logger } from "@andrewheberle/ts-slog";
|
|
2
|
+
import type { AppContext } from "../router.js";
|
|
3
|
+
import type { SshCertificate } from "../ssh/certificate.js";
|
|
4
|
+
import { type PublicKey } from "../ssh/keys.js";
|
|
5
|
+
import { CertificateType } from "../db/types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Returns the public key of the CA in OpenSSH format.
|
|
8
|
+
*
|
|
9
|
+
* @param c The request context
|
|
10
|
+
* @param l The logger for the request
|
|
11
|
+
* @returns The response containing the CA public key
|
|
12
|
+
*/
|
|
13
|
+
export declare const caPublicKey: (c: AppContext, l: Logger) => Promise<Response>;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the signed Key Revocation List for a type of certificate.
|
|
16
|
+
*
|
|
17
|
+
* @param c The request context
|
|
18
|
+
* @param l The logger for the request
|
|
19
|
+
* @param certificateType The type of certificate to return the KRL for
|
|
20
|
+
* @returns The response containing the KRL and its signature
|
|
21
|
+
*/
|
|
22
|
+
export declare const revocationList: (c: AppContext, l: Logger, certificateType: CertificateType) => Promise<Response>;
|
|
23
|
+
/**
|
|
24
|
+
* Signs a certificate, records it so it can later be revoked and returns it
|
|
25
|
+
* as the response to a certificate request or renewal.
|
|
26
|
+
*
|
|
27
|
+
* These are the steps shared by every API version once a request has been
|
|
28
|
+
* validated and authorised.
|
|
29
|
+
*
|
|
30
|
+
* @param c The request context
|
|
31
|
+
* @param l The logger for the request
|
|
32
|
+
* @param sign Signs and returns the certificate
|
|
33
|
+
* @param certificateType The type of certificate being issued
|
|
34
|
+
* @returns The response containing the issued certificate
|
|
35
|
+
*/
|
|
36
|
+
export declare const issueCertificate: (c: AppContext, l: Logger, sign: () => Promise<SshCertificate>, certificateType: CertificateType) => Promise<Response>;
|
|
37
|
+
/**
|
|
38
|
+
* Revokes a certificate once the requester has proven possession of the
|
|
39
|
+
* private key for the public key it was issued for.
|
|
40
|
+
*
|
|
41
|
+
* @param c The request context
|
|
42
|
+
* @param l The logger for the request
|
|
43
|
+
* @param serial The serial of the certificate to revoke
|
|
44
|
+
* @param publicKey The public key the requester has proven possession of
|
|
45
|
+
* @param certificateType The type of certificate being revoked
|
|
46
|
+
* @returns The response containing the time of revocation
|
|
47
|
+
*/
|
|
48
|
+
export declare const revoke: (c: AppContext, l: Logger, serial: bigint, publicKey: PublicKey, certificateType: CertificateType) => Promise<Response>;
|
|
49
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/api/operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAQtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAG9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAgChD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,MAAa,UAAU,KAAK,MAAM,KAAG,OAAO,CAAC,QAAQ,CAQ5E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,MAAa,UAAU,KAAK,MAAM,mBAAmB,eAAe,KAAG,OAAO,CAAC,QAAQ,CAkCjH,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,MAAa,UAAU,KAAK,MAAM,QAAQ,MAAM,OAAO,CAAC,cAAc,CAAC,mBAAmB,eAAe,KAAG,OAAO,CAAC,QAAQ,CAuCxJ,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,MAAa,UAAU,KAAK,MAAM,UAAU,MAAM,aAAa,SAAS,mBAAmB,eAAe,KAAG,OAAO,CAAC,QAAQ,CAsC/I,CAAA"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { group } from "@andrewheberle/ts-slog";
|
|
2
|
+
import { ApiException, ConflictException, InternalServerErrorException, NotFoundException, UnprocessableEntityException, } from "chanfana";
|
|
3
|
+
import { BadIssuerError } from "../certificate.js";
|
|
4
|
+
import { KeyParseError } from "../ssh/keys.js";
|
|
5
|
+
import { getPrivateKey, getPublic, UnsupportedKeyError } from "../utils.js";
|
|
6
|
+
import { KRLBuilder } from "../krl.js";
|
|
7
|
+
import { getKrlVersion, getRevocationList, recordCertificate, RevocationStatus, revocationStatus, revokeCertificate, } from "../db/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Maps an error from an operation that uses the CA key to an API error.
|
|
10
|
+
*/
|
|
11
|
+
const caKeyError = (l, err) => {
|
|
12
|
+
switch (true) {
|
|
13
|
+
case (err instanceof UnsupportedKeyError):
|
|
14
|
+
l.error(err.message);
|
|
15
|
+
return new InternalServerErrorException(err.message);
|
|
16
|
+
case (err instanceof KeyParseError):
|
|
17
|
+
l.error("error parsing private key");
|
|
18
|
+
return new InternalServerErrorException("error parsing private key");
|
|
19
|
+
case (err instanceof ApiException):
|
|
20
|
+
// re-throw any exisiting chanfana error
|
|
21
|
+
return err;
|
|
22
|
+
default:
|
|
23
|
+
// otherwise throw as InternalServerErrorException
|
|
24
|
+
l.error("unhandled error", "error", err);
|
|
25
|
+
return new InternalServerErrorException("internal server error");
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Returns the public key of the CA in OpenSSH format.
|
|
30
|
+
*
|
|
31
|
+
* @param c The request context
|
|
32
|
+
* @param l The logger for the request
|
|
33
|
+
* @returns The response containing the CA public key
|
|
34
|
+
*/
|
|
35
|
+
export const caPublicKey = async (c, l) => {
|
|
36
|
+
try {
|
|
37
|
+
const pub = await getPublic(c.env);
|
|
38
|
+
return c.text(`${pub.toString()}\n`);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
throw caKeyError(l, err);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Returns the signed Key Revocation List for a type of certificate.
|
|
46
|
+
*
|
|
47
|
+
* @param c The request context
|
|
48
|
+
* @param l The logger for the request
|
|
49
|
+
* @param certificateType The type of certificate to return the KRL for
|
|
50
|
+
* @returns The response containing the KRL and its signature
|
|
51
|
+
*/
|
|
52
|
+
export const revocationList = async (c, l, certificateType) => {
|
|
53
|
+
try {
|
|
54
|
+
// get revoked serials
|
|
55
|
+
const serials = (await getRevocationList(c.env, certificateType)).map(v => BigInt(v));
|
|
56
|
+
// grab private key from secret store
|
|
57
|
+
const key = await getPrivateKey(c.env);
|
|
58
|
+
// generate KRL
|
|
59
|
+
const krl = new KRLBuilder(key)
|
|
60
|
+
.addSerials(serials);
|
|
61
|
+
// the version only changes when the content of the KRL does
|
|
62
|
+
const version = await getKrlVersion(c.env, certificateType, await krl.digest());
|
|
63
|
+
const krlBytes = krl.generate(version);
|
|
64
|
+
// convert to base64
|
|
65
|
+
const bytes = new Uint8Array(krlBytes);
|
|
66
|
+
let binary = "";
|
|
67
|
+
for (const byte of bytes) {
|
|
68
|
+
binary += String.fromCharCode(byte);
|
|
69
|
+
}
|
|
70
|
+
const base64Krl = btoa(binary);
|
|
71
|
+
const signature = await krl.signature();
|
|
72
|
+
return c.json({
|
|
73
|
+
krl: base64Krl,
|
|
74
|
+
signature: signature,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
throw caKeyError(l, err);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Signs a certificate, records it so it can later be revoked and returns it
|
|
83
|
+
* as the response to a certificate request or renewal.
|
|
84
|
+
*
|
|
85
|
+
* These are the steps shared by every API version once a request has been
|
|
86
|
+
* validated and authorised.
|
|
87
|
+
*
|
|
88
|
+
* @param c The request context
|
|
89
|
+
* @param l The logger for the request
|
|
90
|
+
* @param sign Signs and returns the certificate
|
|
91
|
+
* @param certificateType The type of certificate being issued
|
|
92
|
+
* @returns The response containing the issued certificate
|
|
93
|
+
*/
|
|
94
|
+
export const issueCertificate = async (c, l, sign, certificateType) => {
|
|
95
|
+
try {
|
|
96
|
+
const certificate = await sign();
|
|
97
|
+
const response = {
|
|
98
|
+
certificate: btoa(certificate.toString())
|
|
99
|
+
};
|
|
100
|
+
try {
|
|
101
|
+
await recordCertificate(c.env, certificate, certificate.keyId, certificateType);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
// a certificate that is not recorded cannot be revoked, so do not issue it
|
|
105
|
+
l.error("there was a problem adding issued certificate to database", "error", err);
|
|
106
|
+
throw new InternalServerErrorException("there was a problem recording the issued certificate");
|
|
107
|
+
}
|
|
108
|
+
l.info("completed issuing certificate", ...group("certificate", "principals", certificate.principals.join(","), "serial", certificate.serial));
|
|
109
|
+
return c.json(response);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
switch (true) {
|
|
113
|
+
case (err instanceof UnsupportedKeyError):
|
|
114
|
+
l.error(err.message);
|
|
115
|
+
throw new InternalServerErrorException(err.message);
|
|
116
|
+
case (err instanceof ApiException):
|
|
117
|
+
// re-throw any exisiting chanfana error
|
|
118
|
+
throw err;
|
|
119
|
+
case (err instanceof BadIssuerError):
|
|
120
|
+
throw new UnprocessableEntityException(err.message);
|
|
121
|
+
default:
|
|
122
|
+
// otherwise throw as InternalServerErrorException
|
|
123
|
+
l.error("unhandled error", "error", err);
|
|
124
|
+
throw new InternalServerErrorException("internal server error");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Revokes a certificate once the requester has proven possession of the
|
|
130
|
+
* private key for the public key it was issued for.
|
|
131
|
+
*
|
|
132
|
+
* @param c The request context
|
|
133
|
+
* @param l The logger for the request
|
|
134
|
+
* @param serial The serial of the certificate to revoke
|
|
135
|
+
* @param publicKey The public key the requester has proven possession of
|
|
136
|
+
* @param certificateType The type of certificate being revoked
|
|
137
|
+
* @returns The response containing the time of revocation
|
|
138
|
+
*/
|
|
139
|
+
export const revoke = async (c, l, serial, publicKey, certificateType) => {
|
|
140
|
+
// ensure certificate can be revoked
|
|
141
|
+
const status = await revocationStatus(c.env, serial, publicKey, certificateType);
|
|
142
|
+
switch (status) {
|
|
143
|
+
case RevocationStatus.Revoked:
|
|
144
|
+
l.warn("certificate is already revoked");
|
|
145
|
+
throw new ConflictException("certificate is already revoked");
|
|
146
|
+
case RevocationStatus.NotFound:
|
|
147
|
+
l.warn("certificate not found");
|
|
148
|
+
throw new NotFoundException("certificate not found");
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const res = await revokeCertificate(c.env, serial);
|
|
152
|
+
if (res.length === 0) {
|
|
153
|
+
throw new InternalServerErrorException("no results were returned for revocation");
|
|
154
|
+
}
|
|
155
|
+
if (res.length > 1) {
|
|
156
|
+
l.warn("more than one revocation result was returned", "count", res.length);
|
|
157
|
+
}
|
|
158
|
+
l.info("completed revocation");
|
|
159
|
+
return c.json({
|
|
160
|
+
revoked_at: res[0].revoked_at
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
switch (true) {
|
|
165
|
+
case (err instanceof ApiException):
|
|
166
|
+
// re-throw any exisiting chanfana error
|
|
167
|
+
throw err;
|
|
168
|
+
default:
|
|
169
|
+
// otherwise throw as InternalServerErrorException
|
|
170
|
+
l.error("unhandled error", "error", err);
|
|
171
|
+
throw new InternalServerErrorException("internal server error");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/api/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import type { SshCaBindings } from "../types.js";
|
|
3
|
+
import { CertificateType } from "../db/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Returns the name of a {@link CertificateType} as used in API paths and logs
|
|
6
|
+
* @param certificateType The type of certificate
|
|
7
|
+
* @returns "user" or "host"
|
|
8
|
+
*/
|
|
9
|
+
export declare const certificateTypeName: (certificateType: CertificateType) => "user" | "host";
|
|
10
|
+
/**
|
|
11
|
+
* Returns the OpenAPI tag that groups the endpoints for a {@link CertificateType}
|
|
12
|
+
* @param certificateType The type of certificate
|
|
13
|
+
* @returns "User" or "Host"
|
|
14
|
+
*/
|
|
15
|
+
export declare const certificateTypeTag: (certificateType: CertificateType) => "User" | "Host";
|
|
16
|
+
export declare const openapiStringByte: z.ZodPipe<z.ZodBase64, z.ZodTransform<Buffer<ArrayBuffer>, string>>;
|
|
17
|
+
export declare const proofOfPossession: z.ZodString;
|
|
18
|
+
export declare const publicKey: z.ZodPipe<z.ZodPipe<z.ZodBase64, z.ZodTransform<Buffer<ArrayBuffer>, string>>, z.ZodTransform<import("../ssh/keys.js").PublicKey, Buffer<ArrayBuffer>>>;
|
|
19
|
+
export declare const createIdentityTokenSchema: (env: SshCaBindings) => z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
20
|
+
sub: string;
|
|
21
|
+
principals: string[];
|
|
22
|
+
}, string>>;
|
|
23
|
+
export declare const createAccessTokenSchema: (env: SshCaBindings) => z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
24
|
+
email: string;
|
|
25
|
+
sub: string;
|
|
26
|
+
}, string>>;
|
|
27
|
+
export declare const krl: z.ZodPipe<z.ZodBase64, z.ZodTransform<Buffer<ArrayBuffer>, string>>;
|
|
28
|
+
export declare const createHeaderSchema: (env: SshCaBindings) => z.ZodObject<{
|
|
29
|
+
Authorization: z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
30
|
+
email: string;
|
|
31
|
+
sub: string;
|
|
32
|
+
}, string>>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export declare const certificate: z.ZodPipe<z.ZodBase64, z.ZodTransform<Buffer<ArrayBuffer>, string>>;
|
|
35
|
+
export declare const CaPublicKeyEndpointSchema: {
|
|
36
|
+
tags: string[];
|
|
37
|
+
summary: string;
|
|
38
|
+
description: string;
|
|
39
|
+
responses: {
|
|
40
|
+
"200": {
|
|
41
|
+
content: {
|
|
42
|
+
"text/plain": {
|
|
43
|
+
schema: z.ZodString;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export declare const createRevocationListEndpointSchema: (certificateType: CertificateType) => {
|
|
51
|
+
tags: ("Host" | "User")[];
|
|
52
|
+
summary: string;
|
|
53
|
+
description: string;
|
|
54
|
+
responses: {
|
|
55
|
+
"200": {
|
|
56
|
+
content: {
|
|
57
|
+
"application/json": {
|
|
58
|
+
schema: z.ZodType<{
|
|
59
|
+
krl: Buffer<ArrayBuffer>;
|
|
60
|
+
signature: string;
|
|
61
|
+
}, unknown, z.core.$ZodTypeInternals<{
|
|
62
|
+
krl: Buffer<ArrayBuffer>;
|
|
63
|
+
signature: string;
|
|
64
|
+
}, unknown>>;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
description: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/api/schema.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAUhD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,oBAAqB,eAAe,KAAG,MAAM,GAAG,MAW/E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,oBAAqB,eAAe,KAAG,MAAM,GAAG,MAW9E,CAAA;AAED,eAAO,MAAM,iBAAiB,qEASD,CAAA;AAE7B,eAAO,MAAM,iBAAiB,aAI3B,CAAA;AAEH,eAAO,MAAM,SAAS,yJAKnB,CAAA;AAEH,eAAO,MAAM,yBAAyB,QAAS,aAAa;;;WAO3D,CAAA;AAED,eAAO,MAAM,uBAAuB,QAAS,aAAa;;;WAOzD,CAAA;AAED,eAAO,MAAM,GAAG,qEAC8B,CAAA;AAE9C,eAAO,MAAM,kBAAkB,QAAS,aAAa;;;;;iBAIpD,CAAA;AAED,eAAO,MAAM,WAAW,qEACqB,CAAA;AAE7C,eAAO,MAAM,yBAAyB;;;;;;YAMnC,OAAO;gBACN,YAAY;oBACX,MAAM;;;YAGR,WAAW;;;CAIb,CAAA;AAED,eAAO,MAAM,kCAAkC,oBAAqB,eAAe;;;;;;;;;;;;;;;;;;;;CAgBjF,CAAA"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { transformAuthorizationHeader, transformPublicKey, transformIdentityToken, } from "../utils.js";
|
|
3
|
+
import { contentJson, InternalServerErrorException, } from "chanfana";
|
|
4
|
+
import { CertificateType } from "../db/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Returns the name of a {@link CertificateType} as used in API paths and logs
|
|
7
|
+
* @param certificateType The type of certificate
|
|
8
|
+
* @returns "user" or "host"
|
|
9
|
+
*/
|
|
10
|
+
export const certificateTypeName = (certificateType) => {
|
|
11
|
+
switch (certificateType) {
|
|
12
|
+
case CertificateType.User:
|
|
13
|
+
return "user";
|
|
14
|
+
case CertificateType.Host:
|
|
15
|
+
return "host";
|
|
16
|
+
default: {
|
|
17
|
+
const unknownType = certificateType;
|
|
18
|
+
throw new Error(`unknown certificate type: ${String(unknownType)}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Returns the OpenAPI tag that groups the endpoints for a {@link CertificateType}
|
|
24
|
+
* @param certificateType The type of certificate
|
|
25
|
+
* @returns "User" or "Host"
|
|
26
|
+
*/
|
|
27
|
+
export const certificateTypeTag = (certificateType) => {
|
|
28
|
+
switch (certificateType) {
|
|
29
|
+
case CertificateType.User:
|
|
30
|
+
return "User";
|
|
31
|
+
case CertificateType.Host:
|
|
32
|
+
return "Host";
|
|
33
|
+
default: {
|
|
34
|
+
const unknownType = certificateType;
|
|
35
|
+
throw new Error(`unknown certificate type: ${String(unknownType)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
export const openapiStringByte = z.base64()
|
|
40
|
+
.transform((v) => {
|
|
41
|
+
const a = z.util.base64ToUint8Array(v);
|
|
42
|
+
return Buffer.from(a.buffer, a.byteOffset, a.length);
|
|
43
|
+
})
|
|
44
|
+
.openapi({ format: "byte" });
|
|
45
|
+
export const proofOfPossession = z.string()
|
|
46
|
+
.meta({
|
|
47
|
+
description: "Proof of possession comprising of ${timestamp}.${fingerprint}.${signature}",
|
|
48
|
+
example: "1765696780805.SHA256:79mq0wtpQMTvS4+Of8VzLN0qmYWNUyTXYmqKwhEgSLs.LS0tLS1CRUdJTiBTU0ggU0lHTkFUVVJFLS0tLS0KVTFOSVUwbEhBQUFBQVFBQUFHZ0FBQUFUWldOa2MyRXRjMmhoTWkxdWFYTjBjREkxTmdBQUFBaHVhWE4wY0RJMQpOZ0FBQUVFRUR6Ymk4OE10alBYSDFCb1JURU9HaS96aEc4QnhQNVZUUW5OQkFNMGZtMExtekErUUZkUlNVYVRFCkdNN2l0QjhINmZNZFAydlAxcElQcGUyOWVLQkJZd0FBQUFSbWFXeGxBQUFBQUFBQUFBWnphR0UxTVRJQUFBQmsKQUFBQUUyVmpaSE5oTFhOb1lUSXRibWx6ZEhBeU5UWUFBQUJKQUFBQUlHdmZVZGNDQkRXa3ZwL0ZHS3NkakgrRQpKZzZXN0EvWUJVZng2Z0srQ01raEFBQUFJUUQxOFd5cDNZejZ0eXNvdllXbEJHTXprRnlYbFRrSHM5blVVRXJqCkczNWVPQT09Ci0tLS0tRU5EIFNTSCBTSUdOQVRVUkUtLS0tLQo="
|
|
49
|
+
});
|
|
50
|
+
export const publicKey = openapiStringByte
|
|
51
|
+
.transform(transformPublicKey)
|
|
52
|
+
.meta({
|
|
53
|
+
description: "SSH public key to sign",
|
|
54
|
+
example: "ZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkdNcFNKdHRmMEl0dE5DVmMyOFR6WEZSMUQweHZPM25wNjdWemVBUXNiZFpza3JEY1lqU2x3SjZIUERtVHBYYVUwbEVhWDlMNFloYy9jQ2YxTWU5RlRrPQo="
|
|
55
|
+
});
|
|
56
|
+
export const createIdentityTokenSchema = (env) => (z.string()
|
|
57
|
+
.meta({
|
|
58
|
+
description: "Identity Token JWT from OIDC IdP",
|
|
59
|
+
example: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZW1haWwiOiJ1c2VyQGV4YW1wbGUuY29tIiwiaWF0IjoxNzc1NzAzMDk1fQ.ri_neAWnhMNK3LzlsrBcQYymSM4yRjmNSZZSeZiXhrEqtEz6c3cXk0Esq765umGjpUsWcosL-OFrDJlyAjTDnhrd9oV08uc_CW0rQRsJIGEuRo3ryxkLdVu9mGoZWEUb9KwjGJrwxvr-0cPWx5jaDyKwJcqMvtV_bEITUD51sDB1Vm89QfYRO_pGJo2vrRzSvMjpUenRpwPay4lYIBxl41_4YpR9Rc6VrIZuYsjV2iqEZ4eBrygMA7zPR_hN7l7s95FddLOzj5NsK57VT4uLHwYohx2oqMzw3M-B9HsZIQin_9q61pZFQXepzJth0woXiZheU27llnfHX967PhNQyg"
|
|
60
|
+
})
|
|
61
|
+
.transform((val, ctx) => transformIdentityToken(env, val, ctx)));
|
|
62
|
+
export const createAccessTokenSchema = (env) => (z.string()
|
|
63
|
+
.meta({
|
|
64
|
+
description: "Access Token JWT from OIDC IdP",
|
|
65
|
+
example: "Bearer eyJ..."
|
|
66
|
+
})
|
|
67
|
+
.transform((val, ctx) => transformAuthorizationHeader(env, val, ctx)));
|
|
68
|
+
export const krl = openapiStringByte
|
|
69
|
+
.meta({ description: "Key Revocation List" });
|
|
70
|
+
export const createHeaderSchema = (env) => (z.object({
|
|
71
|
+
"Authorization": createAccessTokenSchema(env)
|
|
72
|
+
}));
|
|
73
|
+
export const certificate = openapiStringByte
|
|
74
|
+
.meta({ description: "Issued Certificate" });
|
|
75
|
+
export const CaPublicKeyEndpointSchema = {
|
|
76
|
+
tags: ["CA"],
|
|
77
|
+
summary: "Get the CA public key",
|
|
78
|
+
description: "Returns the public key of the SSH Certificate Authority in OpenSSH format, for use in `TrustedUserCAKeys` on SSH servers or `@cert-authority` entries in `known_hosts` on SSH clients.",
|
|
79
|
+
responses: {
|
|
80
|
+
"200": {
|
|
81
|
+
content: {
|
|
82
|
+
"text/plain": {
|
|
83
|
+
schema: z.string()
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
description: "Returns SSH Certificate Authority Public Key",
|
|
87
|
+
},
|
|
88
|
+
...InternalServerErrorException.schema(),
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
export const createRevocationListEndpointSchema = (certificateType) => ({
|
|
92
|
+
tags: [certificateTypeTag(certificateType)],
|
|
93
|
+
summary: `Get the Key Revocation List for ${certificateTypeName(certificateType)} certificates`,
|
|
94
|
+
description: `Returns the OpenSSH Key Revocation List (KRL) of revoked ${certificateTypeName(certificateType)} certificates issued by this CA, along with an SSHSIG signature made by the CA key so the KRL can be verified before use.`,
|
|
95
|
+
responses: {
|
|
96
|
+
"200": {
|
|
97
|
+
description: `Returns an Open SSH Key Revocation List of revoked ${certificateTypeName(certificateType)} certificates as BASE64 and an SSHSIG signature for verification`,
|
|
98
|
+
...contentJson(z.object({
|
|
99
|
+
krl: krl,
|
|
100
|
+
signature: z.string()
|
|
101
|
+
})
|
|
102
|
+
.openapi("Key Revocation List Response"))
|
|
103
|
+
},
|
|
104
|
+
...InternalServerErrorException.schema(),
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/api/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/v3/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/v3/index.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AA0KnD,eAAO,MAAM,SAAS,QAAS,aAAa,mHAa3C,CAAA"}
|