@andrewheberle/serverless-ssh-ca 0.21.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 +25 -212
- package/dist/api/v3/index.js.map +1 -1
- package/dist/api/v3/schema.d.ts +30 -74
- package/dist/api/v3/schema.d.ts.map +1 -1
- package/dist/api/v3/schema.js +18 -73
- 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 +32 -24
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +101 -28
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations/0002_krl_version.d.ts +3 -0
- package/dist/db/migrations/0002_krl_version.d.ts.map +1 -0
- package/dist/db/migrations/0002_krl_version.js +15 -0
- package/dist/db/migrations/0002_krl_version.js.map +1 -0
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +3 -1
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/types.d.ts +37 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +13 -0
- package/dist/db/types.js.map +1 -0
- package/dist/krl.d.ts +9 -1
- package/dist/krl.d.ts.map +1 -1
- package/dist/krl.js +22 -162
- 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 +1960 -82
- package/package.json +5 -17
- package/src/api/operations.ts +211 -0
- package/src/api/schema.ts +137 -0
- package/src/api/v3/index.ts +32 -259
- package/src/api/v3/schema.ts +34 -96
- 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 +113 -49
- package/src/db/migrations/0002_krl_version.ts +16 -0
- package/src/db/migrations/index.ts +3 -1
- package/src/db/types.ts +40 -0
- package/src/krl.ts +32 -194
- 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
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as P from "micro-packed";
|
|
2
|
+
/**
|
|
3
|
+
* Coders for the SSH wire format (RFC 4251 section 5)
|
|
4
|
+
*/
|
|
5
|
+
/** A string of bytes, prefixed by its length as a uint32 */
|
|
6
|
+
export const SSHBytes = P.bytes(P.U32BE);
|
|
7
|
+
/** A UTF-8 string, prefixed by its length as a uint32 */
|
|
8
|
+
export const SSHText = P.string(P.U32BE);
|
|
9
|
+
/** A list of strings packed into a string, as used for certificate principals */
|
|
10
|
+
export const SSHTextList = P.prefix(P.U32BE, P.array(null, SSHText));
|
|
11
|
+
/**
|
|
12
|
+
* A list of named options packed into a string, as used for certificate
|
|
13
|
+
* critical options and extensions
|
|
14
|
+
*/
|
|
15
|
+
export const SSHOptions = P.prefix(P.U32BE, P.array(null, P.struct({
|
|
16
|
+
name: SSHText,
|
|
17
|
+
data: SSHBytes,
|
|
18
|
+
})));
|
|
19
|
+
/**
|
|
20
|
+
* An mpint holding an unsigned integer, decoded to and encoded from its
|
|
21
|
+
* big-endian bytes without leading zeros.
|
|
22
|
+
*
|
|
23
|
+
* An mpint has no leading zero bytes, other than one to keep the value
|
|
24
|
+
* positive when the high bit of the first byte is set.
|
|
25
|
+
*/
|
|
26
|
+
export const SSHUnsignedMpint = P.apply(SSHBytes, {
|
|
27
|
+
encode: (mpint) => {
|
|
28
|
+
let start = 0;
|
|
29
|
+
while (start < mpint.length && mpint[start] === 0) {
|
|
30
|
+
start++;
|
|
31
|
+
}
|
|
32
|
+
return mpint.subarray(start);
|
|
33
|
+
},
|
|
34
|
+
decode: (value) => {
|
|
35
|
+
let start = 0;
|
|
36
|
+
while (start < value.length && value[start] === 0) {
|
|
37
|
+
start++;
|
|
38
|
+
}
|
|
39
|
+
const trimmed = value.subarray(start);
|
|
40
|
+
return trimmed.length > 0 && trimmed[0] & 0x80
|
|
41
|
+
? P.utils.concatBytes(new Uint8Array([0]), trimmed)
|
|
42
|
+
: trimmed;
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
/** The number of fields that follow the type in the wire encoding of a public key of each type */
|
|
46
|
+
export const PublicKeyFieldCounts = {
|
|
47
|
+
"ssh-ed25519": 1, // public key
|
|
48
|
+
"ecdsa-sha2-nistp256": 2, // curve, public key
|
|
49
|
+
"ecdsa-sha2-nistp384": 2,
|
|
50
|
+
"ecdsa-sha2-nistp521": 2,
|
|
51
|
+
"ssh-rsa": 2, // e, n
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Splits the wire encoding of a public key into its type and the encoded
|
|
55
|
+
* fields that follow it
|
|
56
|
+
*
|
|
57
|
+
* @param blob The wire encoding of the public key
|
|
58
|
+
* @returns The key type and its fields
|
|
59
|
+
* @throws Error when the key type is not supported or the encoding is invalid
|
|
60
|
+
*/
|
|
61
|
+
export const decodePublicKey = (blob) => {
|
|
62
|
+
const type = SSHText.decode(blob, { allowUnreadBytes: true });
|
|
63
|
+
const count = PublicKeyFieldCounts[type];
|
|
64
|
+
if (count === undefined) {
|
|
65
|
+
throw new Error(`unsupported public key type: ${type}`);
|
|
66
|
+
}
|
|
67
|
+
const { fields } = P.struct({ type: SSHText, fields: P.array(count, SSHBytes) }).decode(blob);
|
|
68
|
+
return { type, fields };
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=encoding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/ssh/encoding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown when a key cannot be parsed
|
|
3
|
+
*/
|
|
4
|
+
export declare class KeyParseError extends Error {
|
|
5
|
+
constructor(message: string, cause?: unknown);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Thrown when a private key is of a type that cannot be used to sign
|
|
9
|
+
*/
|
|
10
|
+
export declare class UnsupportedKeyError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* An SSH public key
|
|
15
|
+
*/
|
|
16
|
+
export declare class PublicKey {
|
|
17
|
+
/** The key type, for example "ssh-ed25519" */
|
|
18
|
+
readonly type: string;
|
|
19
|
+
/** The wire encoding of the key (RFC 4253 section 6.6) */
|
|
20
|
+
readonly blob: Uint8Array;
|
|
21
|
+
/** The comment of the key, if any */
|
|
22
|
+
readonly comment: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* @param blob The wire encoding of the key
|
|
25
|
+
* @param comment The comment of the key
|
|
26
|
+
* @throws {@link KeyParseError} when the key cannot be decoded or its type is not supported
|
|
27
|
+
*/
|
|
28
|
+
constructor(blob: Uint8Array, comment?: string);
|
|
29
|
+
/**
|
|
30
|
+
* Parses a public key in OpenSSH format, `${type} ${base64}[ ${comment}]`
|
|
31
|
+
*
|
|
32
|
+
* @param text The public key
|
|
33
|
+
* @throws {@link KeyParseError} when the key cannot be parsed or its type is not supported
|
|
34
|
+
*/
|
|
35
|
+
static parse(text: string): PublicKey;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the SHA256 fingerprint of the key, as shown by `ssh-keygen -l`,
|
|
38
|
+
* for example "SHA256:79mq0wtpQMTvS4+Of8VzLN0qmYWNUyTXYmqKwhEgSLs"
|
|
39
|
+
*/
|
|
40
|
+
fingerprint(): string;
|
|
41
|
+
/**
|
|
42
|
+
* Returns whether this is the same key as another, ignoring comments
|
|
43
|
+
*/
|
|
44
|
+
equals(other: PublicKey): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Returns a copy of the key with a different comment
|
|
47
|
+
*/
|
|
48
|
+
withComment(comment: string | undefined): PublicKey;
|
|
49
|
+
/**
|
|
50
|
+
* Returns the key in OpenSSH format, `${type} ${base64}[ ${comment}]`
|
|
51
|
+
*/
|
|
52
|
+
toString(): string;
|
|
53
|
+
}
|
|
54
|
+
/** The ECDSA curves that can be used to sign */
|
|
55
|
+
export type EcdsaCurve = "nistp256" | "nistp384" | "nistp521";
|
|
56
|
+
/**
|
|
57
|
+
* A private key that can be used to sign, with its key material as a JWK for
|
|
58
|
+
* WebCrypto
|
|
59
|
+
*/
|
|
60
|
+
export type PrivateKey = {
|
|
61
|
+
readonly type: "ed25519";
|
|
62
|
+
readonly publicKey: PublicKey;
|
|
63
|
+
readonly jwk: JsonWebKey;
|
|
64
|
+
} | {
|
|
65
|
+
readonly type: "ecdsa";
|
|
66
|
+
readonly curve: EcdsaCurve;
|
|
67
|
+
readonly publicKey: PublicKey;
|
|
68
|
+
readonly jwk: JsonWebKey;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Parses an unencrypted Ed25519 or ECDSA private key in OpenSSH format, as
|
|
72
|
+
* created by `ssh-keygen`
|
|
73
|
+
*
|
|
74
|
+
* @param text The private key, starting with `-----BEGIN OPENSSH PRIVATE KEY-----`
|
|
75
|
+
* @returns The private key
|
|
76
|
+
* @throws {@link KeyParseError} when the key cannot be parsed or is encrypted
|
|
77
|
+
* @throws {@link UnsupportedKeyError} when the key is not an Ed25519 or ECDSA key
|
|
78
|
+
*/
|
|
79
|
+
export declare const parsePrivateKey: (text: string) => PrivateKey;
|
|
80
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/ssh/keys.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAM3C;CACD;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAK1B;CACD;AAMD;;GAEG;AACH,qBAAa,SAAS;IACrB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAEpC;;;;OAIG;IACH,YAAY,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,EAQ7C;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAmBpC;IAED;;;OAGG;IACH,WAAW,IAAI,MAAM,CAEpB;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEhC;IAED;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAElD;IAED;;OAEG;IACH,QAAQ,IAAI,MAAM,CAIjB;CACD;AAED,gDAAgD;AAChD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAA;AAQ7D;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;CACxB,GAAG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;CACxB,CAAA;AAkDD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,UA2F9C,CAAA"}
|
package/dist/ssh/keys.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
2
|
+
import { base64, base64nopad, base64urlnopad } from "@scure/base";
|
|
3
|
+
import * as P from "micro-packed";
|
|
4
|
+
import { toFixedWidth } from "../sshsig/sig_parser.js";
|
|
5
|
+
import { decodePublicKey, SSHBytes, SSHText } from "./encoding.js";
|
|
6
|
+
/**
|
|
7
|
+
* Thrown when a key cannot be parsed
|
|
8
|
+
*/
|
|
9
|
+
export class KeyParseError extends Error {
|
|
10
|
+
constructor(message, cause) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "KeyParseError";
|
|
13
|
+
this.cause = cause;
|
|
14
|
+
Object.setPrototypeOf(this, KeyParseError.prototype);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Thrown when a private key is of a type that cannot be used to sign
|
|
19
|
+
*/
|
|
20
|
+
export class UnsupportedKeyError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "UnsupportedKeyError";
|
|
24
|
+
Object.setPrototypeOf(this, UnsupportedKeyError.prototype);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const equalBytes = (a, b) => {
|
|
28
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* An SSH public key
|
|
32
|
+
*/
|
|
33
|
+
export class PublicKey {
|
|
34
|
+
/** The key type, for example "ssh-ed25519" */
|
|
35
|
+
type;
|
|
36
|
+
/** The wire encoding of the key (RFC 4253 section 6.6) */
|
|
37
|
+
blob;
|
|
38
|
+
/** The comment of the key, if any */
|
|
39
|
+
comment;
|
|
40
|
+
/**
|
|
41
|
+
* @param blob The wire encoding of the key
|
|
42
|
+
* @param comment The comment of the key
|
|
43
|
+
* @throws {@link KeyParseError} when the key cannot be decoded or its type is not supported
|
|
44
|
+
*/
|
|
45
|
+
constructor(blob, comment) {
|
|
46
|
+
try {
|
|
47
|
+
this.type = decodePublicKey(blob).type;
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
throw new KeyParseError(err instanceof Error ? err.message : "public key could not be decoded", err);
|
|
51
|
+
}
|
|
52
|
+
this.blob = blob;
|
|
53
|
+
this.comment = comment === "" ? undefined : comment;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parses a public key in OpenSSH format, `${type} ${base64}[ ${comment}]`
|
|
57
|
+
*
|
|
58
|
+
* @param text The public key
|
|
59
|
+
* @throws {@link KeyParseError} when the key cannot be parsed or its type is not supported
|
|
60
|
+
*/
|
|
61
|
+
static parse(text) {
|
|
62
|
+
const [type, data, ...comment] = text.trim().split(/\s+/);
|
|
63
|
+
if (type === undefined || type === "" || data === undefined) {
|
|
64
|
+
throw new KeyParseError("public key was not in OpenSSH format");
|
|
65
|
+
}
|
|
66
|
+
let blob;
|
|
67
|
+
try {
|
|
68
|
+
blob = base64.decode(data);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
throw new KeyParseError("public key was not valid base64", err);
|
|
72
|
+
}
|
|
73
|
+
const key = new PublicKey(blob, comment.join(" "));
|
|
74
|
+
if (key.type !== type) {
|
|
75
|
+
throw new KeyParseError(`public key type ${type} did not match encoded type ${key.type}`);
|
|
76
|
+
}
|
|
77
|
+
return key;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the SHA256 fingerprint of the key, as shown by `ssh-keygen -l`,
|
|
81
|
+
* for example "SHA256:79mq0wtpQMTvS4+Of8VzLN0qmYWNUyTXYmqKwhEgSLs"
|
|
82
|
+
*/
|
|
83
|
+
fingerprint() {
|
|
84
|
+
return `SHA256:${base64nopad.encode(sha256(this.blob))}`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns whether this is the same key as another, ignoring comments
|
|
88
|
+
*/
|
|
89
|
+
equals(other) {
|
|
90
|
+
return equalBytes(this.blob, other.blob);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Returns a copy of the key with a different comment
|
|
94
|
+
*/
|
|
95
|
+
withComment(comment) {
|
|
96
|
+
return new PublicKey(this.blob, comment);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Returns the key in OpenSSH format, `${type} ${base64}[ ${comment}]`
|
|
100
|
+
*/
|
|
101
|
+
toString() {
|
|
102
|
+
const key = `${this.type} ${base64.encode(this.blob)}`;
|
|
103
|
+
return this.comment === undefined ? key : `${key} ${this.comment}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const EcdsaCurves = {
|
|
107
|
+
nistp256: { namedCurve: "P-256", size: 32 },
|
|
108
|
+
nistp384: { namedCurve: "P-384", size: 48 },
|
|
109
|
+
nistp521: { namedCurve: "P-521", size: 66 },
|
|
110
|
+
};
|
|
111
|
+
// "openssh-key-v1\0"
|
|
112
|
+
const AUTH_MAGIC = new TextEncoder().encode("openssh-key-v1\0");
|
|
113
|
+
/** The container of an OpenSSH private key (PROTOCOL.key) */
|
|
114
|
+
const OpenSshPrivateKey = P.struct({
|
|
115
|
+
magic: P.magicBytes(AUTH_MAGIC),
|
|
116
|
+
cipherName: SSHText,
|
|
117
|
+
kdfName: SSHText,
|
|
118
|
+
kdfOptions: SSHBytes,
|
|
119
|
+
publicKeys: P.array(P.U32BE, SSHBytes),
|
|
120
|
+
privateKeys: SSHBytes,
|
|
121
|
+
});
|
|
122
|
+
/** The start of the (decrypted) private section of an OpenSSH private key */
|
|
123
|
+
const PrivateSectionStart = P.struct({
|
|
124
|
+
check1: P.U32BE,
|
|
125
|
+
check2: P.U32BE,
|
|
126
|
+
type: SSHText,
|
|
127
|
+
});
|
|
128
|
+
const Ed25519PrivateKey = P.struct({
|
|
129
|
+
check1: P.U32BE,
|
|
130
|
+
check2: P.U32BE,
|
|
131
|
+
type: SSHText,
|
|
132
|
+
publicKey: SSHBytes,
|
|
133
|
+
// the seed followed by the public key
|
|
134
|
+
privateKey: SSHBytes,
|
|
135
|
+
comment: SSHText,
|
|
136
|
+
});
|
|
137
|
+
const EcdsaPrivateKey = P.struct({
|
|
138
|
+
check1: P.U32BE,
|
|
139
|
+
check2: P.U32BE,
|
|
140
|
+
type: SSHText,
|
|
141
|
+
curve: SSHText,
|
|
142
|
+
publicKey: SSHBytes,
|
|
143
|
+
// an mpint
|
|
144
|
+
privateKey: SSHBytes,
|
|
145
|
+
comment: SSHText,
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Returns a short name for the type of a key, for example "rsa" for "ssh-rsa"
|
|
149
|
+
*/
|
|
150
|
+
const keyTypeName = (type) => {
|
|
151
|
+
return type.replace(/^ssh-/, "").replace(/^ecdsa-sha2-.*$/, "ecdsa");
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Parses an unencrypted Ed25519 or ECDSA private key in OpenSSH format, as
|
|
155
|
+
* created by `ssh-keygen`
|
|
156
|
+
*
|
|
157
|
+
* @param text The private key, starting with `-----BEGIN OPENSSH PRIVATE KEY-----`
|
|
158
|
+
* @returns The private key
|
|
159
|
+
* @throws {@link KeyParseError} when the key cannot be parsed or is encrypted
|
|
160
|
+
* @throws {@link UnsupportedKeyError} when the key is not an Ed25519 or ECDSA key
|
|
161
|
+
*/
|
|
162
|
+
export const parsePrivateKey = (text) => {
|
|
163
|
+
const match = /-----BEGIN OPENSSH PRIVATE KEY-----([\s\S]*?)-----END OPENSSH PRIVATE KEY-----/.exec(text);
|
|
164
|
+
if (match === null) {
|
|
165
|
+
throw new KeyParseError("private key was not in OpenSSH format, as created by ssh-keygen (starting with -----BEGIN OPENSSH PRIVATE KEY-----)");
|
|
166
|
+
}
|
|
167
|
+
let container;
|
|
168
|
+
try {
|
|
169
|
+
container = OpenSshPrivateKey.decode(base64.decode(match[1].replace(/\s+/g, "")));
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
throw new KeyParseError("private key could not be decoded", err);
|
|
173
|
+
}
|
|
174
|
+
if (container.cipherName !== "none" || container.kdfName !== "none") {
|
|
175
|
+
throw new KeyParseError("encrypted private keys are not supported");
|
|
176
|
+
}
|
|
177
|
+
if (container.publicKeys.length !== 1) {
|
|
178
|
+
throw new KeyParseError(`private key must contain one key, not ${container.publicKeys.length}`);
|
|
179
|
+
}
|
|
180
|
+
// the private section is padded to a block size, so may have trailing bytes
|
|
181
|
+
const options = { allowUnreadBytes: true };
|
|
182
|
+
let start;
|
|
183
|
+
try {
|
|
184
|
+
start = PrivateSectionStart.decode(container.privateKeys, options);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
throw new KeyParseError("private key could not be decoded", err);
|
|
188
|
+
}
|
|
189
|
+
if (start.check1 !== start.check2) {
|
|
190
|
+
throw new KeyParseError("private key check values did not match");
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
if (start.type === "ssh-ed25519") {
|
|
194
|
+
const key = Ed25519PrivateKey.decode(container.privateKeys, options);
|
|
195
|
+
if (key.publicKey.length !== 32 || key.privateKey.length !== 64) {
|
|
196
|
+
throw new KeyParseError("Ed25519 private key was an unexpected length");
|
|
197
|
+
}
|
|
198
|
+
const publicKey = new PublicKey(container.publicKeys[0], key.comment);
|
|
199
|
+
if (!equalBytes(P.struct({ type: SSHText, key: SSHBytes }).encode({ type: start.type, key: key.publicKey }), publicKey.blob)) {
|
|
200
|
+
throw new KeyParseError("private key did not match its public key");
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
type: "ed25519",
|
|
204
|
+
publicKey,
|
|
205
|
+
jwk: {
|
|
206
|
+
kty: "OKP",
|
|
207
|
+
crv: "Ed25519",
|
|
208
|
+
d: base64urlnopad.encode(key.privateKey.subarray(0, 32)),
|
|
209
|
+
x: base64urlnopad.encode(key.publicKey),
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (start.type.startsWith("ecdsa-sha2-")) {
|
|
214
|
+
const key = EcdsaPrivateKey.decode(container.privateKeys, options);
|
|
215
|
+
const curve = EcdsaCurves[key.curve];
|
|
216
|
+
if (curve === undefined || start.type !== `ecdsa-sha2-${key.curve}`) {
|
|
217
|
+
throw new UnsupportedKeyError(`ECDSA curve ${key.curve} is not supported`);
|
|
218
|
+
}
|
|
219
|
+
if (key.publicKey.length !== 1 + curve.size * 2 || key.publicKey[0] !== 0x04) {
|
|
220
|
+
throw new KeyParseError(`unexpected ECDSA public key encoding for ${key.curve}`);
|
|
221
|
+
}
|
|
222
|
+
const publicKey = new PublicKey(container.publicKeys[0], key.comment);
|
|
223
|
+
if (!equalBytes(P.struct({ type: SSHText, curve: SSHText, key: SSHBytes }).encode({ type: start.type, curve: key.curve, key: key.publicKey }), publicKey.blob)) {
|
|
224
|
+
throw new KeyParseError("private key did not match its public key");
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
type: "ecdsa",
|
|
228
|
+
curve: key.curve,
|
|
229
|
+
publicKey,
|
|
230
|
+
jwk: {
|
|
231
|
+
kty: "EC",
|
|
232
|
+
crv: curve.namedCurve,
|
|
233
|
+
// d is an mpint, so may be short or have a leading sign byte
|
|
234
|
+
d: base64urlnopad.encode(toFixedWidth(key.privateKey, curve.size)),
|
|
235
|
+
x: base64urlnopad.encode(key.publicKey.subarray(1, 1 + curve.size)),
|
|
236
|
+
y: base64urlnopad.encode(key.publicKey.subarray(1 + curve.size)),
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
if (err instanceof KeyParseError || err instanceof UnsupportedKeyError) {
|
|
243
|
+
throw err;
|
|
244
|
+
}
|
|
245
|
+
throw new KeyParseError("private key could not be decoded", err);
|
|
246
|
+
}
|
|
247
|
+
throw new UnsupportedKeyError(`CA key type ${keyTypeName(start.type)} is not supported, the CA key must be Ed25519 or ECDSA`);
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/ssh/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PrivateKey, PublicKey } from "./keys.js";
|
|
2
|
+
/**
|
|
3
|
+
* Signs data with a CA key using WebCrypto, returning signatures in the SSH
|
|
4
|
+
* wire format
|
|
5
|
+
*/
|
|
6
|
+
export interface Signer {
|
|
7
|
+
/** The wire encoding of the public key of the signer */
|
|
8
|
+
readonly publicKey: Uint8Array;
|
|
9
|
+
/**
|
|
10
|
+
* Signs data
|
|
11
|
+
*
|
|
12
|
+
* @param data The data to sign
|
|
13
|
+
* @returns The signature in the SSH wire format (RFC 4253 section 6.6)
|
|
14
|
+
*/
|
|
15
|
+
sign(data: Uint8Array<ArrayBuffer>): Promise<Uint8Array>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a {@link Signer} for an Ed25519 or ECDSA (P-256, P-384 or P-521)
|
|
19
|
+
* private key
|
|
20
|
+
*
|
|
21
|
+
* @param key The private key to sign with
|
|
22
|
+
* @returns The signer
|
|
23
|
+
*/
|
|
24
|
+
export declare const createSigner: (key: PrivateKey) => Promise<Signer>;
|
|
25
|
+
/**
|
|
26
|
+
* Verifies a signature in the SSH wire format made with an Ed25519 or ECDSA
|
|
27
|
+
* key
|
|
28
|
+
*
|
|
29
|
+
* @param publicKey The key the signature must have been made with
|
|
30
|
+
* @param signature The signature in the SSH wire format
|
|
31
|
+
* @param data The data that was signed
|
|
32
|
+
* @returns true if the signature is valid, false if it is not or the key type is not supported
|
|
33
|
+
*/
|
|
34
|
+
export declare const verify: (publicKey: PublicKey, signature: Uint8Array, data: Uint8Array<ArrayBuffer>) => Promise<boolean>;
|
|
35
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/ssh/signer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAElE;;;GAGG;AACH,MAAM,WAAW,MAAM;IACtB,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;IAC9B;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CACxD;AAuBD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,QAAe,UAAU,KAAG,OAAO,CAAC,MAAM,CAmClE,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,cAAqB,SAAS,aAAa,UAAU,QAAQ,UAAU,CAAC,WAAW,CAAC,KAAG,OAAO,CAAC,OAAO,CAiCxH,CAAA"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as P from "micro-packed";
|
|
2
|
+
import { toFixedWidth } from "../sshsig/sig_parser.js";
|
|
3
|
+
import { decodePublicKey, SSHBytes, SSHText, SSHUnsignedMpint } from "./encoding.js";
|
|
4
|
+
/** An Ed25519 signature: string algorithm, string signature */
|
|
5
|
+
const Ed25519Signature = P.struct({
|
|
6
|
+
algorithm: SSHText,
|
|
7
|
+
signature: SSHBytes,
|
|
8
|
+
});
|
|
9
|
+
/** An ECDSA signature: string algorithm, string (mpint r, mpint s) */
|
|
10
|
+
const EcdsaSignature = P.struct({
|
|
11
|
+
algorithm: SSHText,
|
|
12
|
+
signature: P.prefix(P.U32BE, P.struct({
|
|
13
|
+
r: SSHUnsignedMpint,
|
|
14
|
+
s: SSHUnsignedMpint,
|
|
15
|
+
})),
|
|
16
|
+
});
|
|
17
|
+
const EcdsaCurves = {
|
|
18
|
+
nistp256: { namedCurve: "P-256", hash: "SHA-256", size: 32 },
|
|
19
|
+
nistp384: { namedCurve: "P-384", hash: "SHA-384", size: 48 },
|
|
20
|
+
nistp521: { namedCurve: "P-521", hash: "SHA-512", size: 66 },
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Creates a {@link Signer} for an Ed25519 or ECDSA (P-256, P-384 or P-521)
|
|
24
|
+
* private key
|
|
25
|
+
*
|
|
26
|
+
* @param key The private key to sign with
|
|
27
|
+
* @returns The signer
|
|
28
|
+
*/
|
|
29
|
+
export const createSigner = async (key) => {
|
|
30
|
+
const publicKey = key.publicKey.blob;
|
|
31
|
+
if (key.type === "ed25519") {
|
|
32
|
+
const cryptoKey = await crypto.subtle.importKey("jwk", key.jwk, { name: "Ed25519" }, false, ["sign"]);
|
|
33
|
+
return {
|
|
34
|
+
publicKey,
|
|
35
|
+
sign: async (data) => Ed25519Signature.encode({
|
|
36
|
+
algorithm: "ssh-ed25519",
|
|
37
|
+
signature: new Uint8Array(await crypto.subtle.sign({ name: "Ed25519" }, cryptoKey, data)),
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const curve = EcdsaCurves[key.curve];
|
|
42
|
+
const cryptoKey = await crypto.subtle.importKey("jwk", key.jwk, { name: "ECDSA", namedCurve: curve.namedCurve }, false, ["sign"]);
|
|
43
|
+
return {
|
|
44
|
+
publicKey,
|
|
45
|
+
sign: async (data) => {
|
|
46
|
+
// WebCrypto returns r || s, each the size of the curve
|
|
47
|
+
const signature = new Uint8Array(await crypto.subtle.sign({ name: "ECDSA", hash: { name: curve.hash } }, cryptoKey, data));
|
|
48
|
+
return EcdsaSignature.encode({
|
|
49
|
+
// the algorithm is named for the curve of the key, never
|
|
50
|
+
// worked out from the signature
|
|
51
|
+
algorithm: `ecdsa-sha2-${key.curve}`,
|
|
52
|
+
signature: {
|
|
53
|
+
r: signature.subarray(0, curve.size),
|
|
54
|
+
s: signature.subarray(curve.size),
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Verifies a signature in the SSH wire format made with an Ed25519 or ECDSA
|
|
62
|
+
* key
|
|
63
|
+
*
|
|
64
|
+
* @param publicKey The key the signature must have been made with
|
|
65
|
+
* @param signature The signature in the SSH wire format
|
|
66
|
+
* @param data The data that was signed
|
|
67
|
+
* @returns true if the signature is valid, false if it is not or the key type is not supported
|
|
68
|
+
*/
|
|
69
|
+
export const verify = async (publicKey, signature, data) => {
|
|
70
|
+
try {
|
|
71
|
+
const { type, fields } = decodePublicKey(publicKey.blob);
|
|
72
|
+
if (type === "ssh-ed25519") {
|
|
73
|
+
const { algorithm, signature: raw } = Ed25519Signature.decode(signature);
|
|
74
|
+
if (algorithm !== type) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const cryptoKey = await crypto.subtle.importKey("raw", new Uint8Array(fields[0]), { name: "Ed25519" }, false, ["verify"]);
|
|
78
|
+
return await crypto.subtle.verify({ name: "Ed25519" }, cryptoKey, new Uint8Array(raw), data);
|
|
79
|
+
}
|
|
80
|
+
const curveName = type.replace(/^ecdsa-sha2-/, "");
|
|
81
|
+
const curve = EcdsaCurves[curveName];
|
|
82
|
+
if (curve !== undefined && type === `ecdsa-sha2-${curveName}`) {
|
|
83
|
+
const { algorithm, signature: { r, s } } = EcdsaSignature.decode(signature);
|
|
84
|
+
if (algorithm !== type || r.length > curve.size || s.length > curve.size) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
// fields are the curve name and the public point
|
|
88
|
+
const cryptoKey = await crypto.subtle.importKey("raw", new Uint8Array(fields[1]), { name: "ECDSA", namedCurve: curve.namedCurve }, false, ["verify"]);
|
|
89
|
+
const raw = P.utils.concatBytes(toFixedWidth(r, curve.size), toFixedWidth(s, curve.size));
|
|
90
|
+
return await crypto.subtle.verify({ name: "ECDSA", hash: { name: curve.hash } }, cryptoKey, new Uint8Array(raw), data);
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// a signature or key that cannot be decoded or imported is not valid
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/ssh/signer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -14,11 +14,6 @@ export type CertificateRequestJWTPayload = {
|
|
|
14
14
|
sub: string;
|
|
15
15
|
[key: string]: string | string[];
|
|
16
16
|
} & JWTPayload;
|
|
17
|
-
export type SSHExtension = {
|
|
18
|
-
critical: boolean;
|
|
19
|
-
name: string;
|
|
20
|
-
data: Buffer<ArrayBuffer>;
|
|
21
|
-
};
|
|
22
17
|
/**
|
|
23
18
|
* The result of executing a statement via {@link CaPreparedStatement.run} or
|
|
24
19
|
* {@link CaDatabase.batch}, modelled on a Cloudflare D1 result.
|
|
@@ -87,24 +82,24 @@ export interface CaSecret {
|
|
|
87
82
|
* {@link CaSecret} for the non-string bindings.
|
|
88
83
|
*/
|
|
89
84
|
export interface SshCaBindings {
|
|
90
|
-
|
|
85
|
+
CERTIFICATE_REQUEST_TIME_SKEW_MAX: string;
|
|
86
|
+
JWT_ALGORITHMS: string | string[];
|
|
87
|
+
JWT_AUD?: string | string[];
|
|
88
|
+
JWT_ISSUER: string;
|
|
89
|
+
JWT_JWKS_URL: string;
|
|
90
|
+
JWT_SSH_CERTIFICATE_PRINCIPALS_CLAIM: string;
|
|
91
|
+
LOG_LEVEL?: string;
|
|
91
92
|
DB_CERTIFICATE_RETENTION: string;
|
|
93
|
+
DB: CaDatabase;
|
|
94
|
+
ISSUER_DN: string;
|
|
92
95
|
PRIVATE_KEY: CaSecret;
|
|
93
96
|
SSH_CERTIFICATE_EXTENSIONS: string;
|
|
94
|
-
SSH_CERTIFICATE_LIFETIME: string;
|
|
95
|
-
SSH_CERTIFICATE_INCLUDE_SELF?: string | boolean;
|
|
96
97
|
SSH_CERTIFICATE_INCLUDE_SELF_EMAIL?: string | boolean;
|
|
98
|
+
SSH_CERTIFICATE_INCLUDE_SELF?: string | boolean;
|
|
99
|
+
SSH_CERTIFICATE_LIFETIME: string;
|
|
97
100
|
SSH_CERTIFICATE_PRINCIPALS?: string | string[];
|
|
98
|
-
SSH_HOST_CERTIFICATE_LIFETIME: string;
|
|
99
101
|
SSH_HOST_CERTIFICATE_ALLOWED_EMAILS?: string | string[];
|
|
100
102
|
SSH_HOST_CERTIFICATE_ALLOWED_ROLES?: string | string[];
|
|
101
|
-
|
|
102
|
-
JWT_JWKS_URL: string;
|
|
103
|
-
JWT_AUD?: string | string[];
|
|
104
|
-
JWT_ISSUER: string;
|
|
105
|
-
JWT_ALGORITHMS: string | string[];
|
|
106
|
-
JWT_SSH_CERTIFICATE_PRINCIPALS_CLAIM: string;
|
|
107
|
-
CERTIFICATE_REQUEST_TIME_SKEW_MAX: string;
|
|
108
|
-
LOG_LEVEL?: string;
|
|
103
|
+
SSH_HOST_CERTIFICATE_LIFETIME: string;
|
|
109
104
|
}
|
|
110
105
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAGjC,MAAM,MAAM,wBAAwB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;CACtB,CAAA;AAGD,MAAM,MAAM,4BAA4B,GAAG;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;CACnC,GAAG,UAAU,CAAA;AAEd
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|