@gbuerk/gcrypt 0.1.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/LICENSE +21 -0
- package/README.md +167 -0
- package/dist/commands.d.ts +49 -0
- package/dist/commands.js +333 -0
- package/dist/commands.js.map +1 -0
- package/dist/crypto.d.ts +18 -0
- package/dist/crypto.js +134 -0
- package/dist/crypto.js.map +1 -0
- package/dist/document.d.ts +45 -0
- package/dist/document.js +437 -0
- package/dist/document.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +285 -0
- package/dist/index.js.map +1 -0
- package/dist/key-storage.d.ts +6 -0
- package/dist/key-storage.js +41 -0
- package/dist/key-storage.js.map +1 -0
- package/dist/member-setup-code.d.ts +6 -0
- package/dist/member-setup-code.js +39 -0
- package/dist/member-setup-code.js.map +1 -0
- package/dist/node-types.d.ts +1 -0
- package/dist/node-types.js +3 -0
- package/dist/node-types.js.map +1 -0
- package/package.json +59 -0
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createPrivateKey, createPublicKey, generateKeyPairSync, sign, verify } from 'node:crypto';
|
|
2
|
+
import { Decrypter, Encrypter, generateX25519Identity, identityToRecipient } from 'age-encryption';
|
|
3
|
+
const encryptedValuePattern = /^ENC\[age:([A-Za-z0-9_-]+)\]$/;
|
|
4
|
+
const publicKeyPrefix = 'ed25519:';
|
|
5
|
+
const privateKeyPrefix = 'ed25519-secret:';
|
|
6
|
+
export async function generateAgeIdentity() {
|
|
7
|
+
const identity = await generateX25519Identity();
|
|
8
|
+
return { identity, recipient: await identityToRecipient(identity) };
|
|
9
|
+
}
|
|
10
|
+
export async function ageRecipientForIdentity(identity) {
|
|
11
|
+
validateIdentity(identity);
|
|
12
|
+
return identityToRecipient(identity);
|
|
13
|
+
}
|
|
14
|
+
export async function encryptValue(value, recipients) {
|
|
15
|
+
if (recipients.length === 0) {
|
|
16
|
+
throw new Error('At least one access key is required');
|
|
17
|
+
}
|
|
18
|
+
const encrypter = new Encrypter();
|
|
19
|
+
for (const recipient of recipients) {
|
|
20
|
+
validateRecipient(recipient);
|
|
21
|
+
encrypter.addRecipient(recipient);
|
|
22
|
+
}
|
|
23
|
+
const ciphertext = await encrypter.encrypt(value);
|
|
24
|
+
return `ENC[age:${Buffer.from(ciphertext).toString('base64url')}]`;
|
|
25
|
+
}
|
|
26
|
+
export async function decryptValue(encryptedValue, identity) {
|
|
27
|
+
const match = encryptedValuePattern.exec(encryptedValue);
|
|
28
|
+
if (!match) {
|
|
29
|
+
throw new Error('Invalid encrypted value');
|
|
30
|
+
}
|
|
31
|
+
validateIdentity(identity);
|
|
32
|
+
const decrypter = new Decrypter();
|
|
33
|
+
decrypter.addIdentity(identity);
|
|
34
|
+
return decrypter.decrypt(Buffer.from(match[1], 'base64url'), 'text');
|
|
35
|
+
}
|
|
36
|
+
export function generateSigningIdentity() {
|
|
37
|
+
const { privateKey, publicKey } = generateKeyPairSync('ed25519');
|
|
38
|
+
return {
|
|
39
|
+
privateKey: `${privateKeyPrefix}${privateKey.export({ format: 'der', type: 'pkcs8' }).toString('base64url')}`,
|
|
40
|
+
publicKey: `${publicKeyPrefix}${publicKey.export({ format: 'der', type: 'spki' }).toString('base64url')}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function signDocument(document, privateKey) {
|
|
44
|
+
return sign(null, Buffer.from(document), parsePrivateKey(privateKey)).toString('base64url');
|
|
45
|
+
}
|
|
46
|
+
export function verifyDocument(document, signature, publicKey) {
|
|
47
|
+
if (!/^[A-Za-z0-9_-]+$/.test(signature)) {
|
|
48
|
+
throw new Error('Invalid Ed25519 signature');
|
|
49
|
+
}
|
|
50
|
+
let signatureBytes;
|
|
51
|
+
try {
|
|
52
|
+
signatureBytes = Buffer.from(signature, 'base64url');
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error('Invalid Ed25519 signature');
|
|
56
|
+
}
|
|
57
|
+
if (signatureBytes.length !== 64) {
|
|
58
|
+
throw new Error('Invalid Ed25519 signature');
|
|
59
|
+
}
|
|
60
|
+
return verify(null, Buffer.from(document), parsePublicKey(publicKey), signatureBytes);
|
|
61
|
+
}
|
|
62
|
+
export function signingPublicKeyForIdentity(privateKey) {
|
|
63
|
+
const publicKey = createPublicKey(parsePrivateKey(privateKey));
|
|
64
|
+
return `${publicKeyPrefix}${publicKey.export({ format: 'der', type: 'spki' }).toString('base64url')}`;
|
|
65
|
+
}
|
|
66
|
+
export function validateAgeRecipient(recipient) {
|
|
67
|
+
validateRecipient(recipient);
|
|
68
|
+
}
|
|
69
|
+
export function validateSigningPublicKey(publicKey) {
|
|
70
|
+
parsePublicKey(publicKey);
|
|
71
|
+
}
|
|
72
|
+
function validateRecipient(recipient) {
|
|
73
|
+
if (!recipient.startsWith('age1') || recipient.startsWith('age1pq') || recipient.startsWith('age1tag')) {
|
|
74
|
+
throw new Error('Invalid access key');
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const encrypter = new Encrypter();
|
|
78
|
+
encrypter.addRecipient(recipient);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
throw new Error('Invalid access key');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function validateIdentity(identity) {
|
|
85
|
+
if (!identity.startsWith('AGE-SECRET-KEY-1')) {
|
|
86
|
+
throw new Error('Invalid age identity');
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const decrypter = new Decrypter();
|
|
90
|
+
decrypter.addIdentity(identity);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
throw new Error('Invalid age identity');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function parsePrivateKey(privateKey) {
|
|
97
|
+
if (!privateKey.startsWith(privateKeyPrefix)) {
|
|
98
|
+
throw new Error('Invalid Ed25519 private key');
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const key = createPrivateKey({
|
|
102
|
+
key: Buffer.from(privateKey.slice(privateKeyPrefix.length), 'base64url'),
|
|
103
|
+
format: 'der',
|
|
104
|
+
type: 'pkcs8',
|
|
105
|
+
});
|
|
106
|
+
if (key.asymmetricKeyType !== 'ed25519') {
|
|
107
|
+
throw new Error('not an Ed25519 key');
|
|
108
|
+
}
|
|
109
|
+
return key;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
throw new Error('Invalid Ed25519 private key');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function parsePublicKey(publicKey) {
|
|
116
|
+
if (!publicKey.startsWith(publicKeyPrefix)) {
|
|
117
|
+
throw new Error('Invalid Ed25519 public key');
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const key = createPublicKey({
|
|
121
|
+
key: Buffer.from(publicKey.slice(publicKeyPrefix.length), 'base64url'),
|
|
122
|
+
format: 'der',
|
|
123
|
+
type: 'spki',
|
|
124
|
+
});
|
|
125
|
+
if (key.asymmetricKeyType !== 'ed25519') {
|
|
126
|
+
throw new Error('not an Ed25519 key');
|
|
127
|
+
}
|
|
128
|
+
return key;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
throw new Error('Invalid Ed25519 public key');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type DocumentFormat = 'dotenv' | 'json';
|
|
2
|
+
export type JsonScalarType = 'string' | 'number' | 'boolean' | 'null';
|
|
3
|
+
export interface DocumentMetadata {
|
|
4
|
+
version: 2;
|
|
5
|
+
members: DocumentMember[];
|
|
6
|
+
recipients: string[];
|
|
7
|
+
maintainers: string[];
|
|
8
|
+
signatures: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface DocumentMember {
|
|
11
|
+
id: string;
|
|
12
|
+
recipient: string;
|
|
13
|
+
signingKey: string;
|
|
14
|
+
isMaintainer: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface EncryptedValue {
|
|
17
|
+
key: string;
|
|
18
|
+
marker: string;
|
|
19
|
+
jsonType?: JsonScalarType;
|
|
20
|
+
}
|
|
21
|
+
export interface EncryptedDocument {
|
|
22
|
+
format: DocumentFormat;
|
|
23
|
+
metadata: DocumentMetadata;
|
|
24
|
+
values: EncryptedValue[];
|
|
25
|
+
}
|
|
26
|
+
interface SourceValue extends EncryptedValue {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ParsedDocument extends EncryptedDocument {
|
|
31
|
+
source: string;
|
|
32
|
+
sourceValues: SourceValue[];
|
|
33
|
+
}
|
|
34
|
+
export declare class DocumentValidationError extends Error {
|
|
35
|
+
constructor(message: string);
|
|
36
|
+
}
|
|
37
|
+
export declare function parseEncryptedDocument(source: string, format: DocumentFormat): ParsedDocument;
|
|
38
|
+
export declare function parseDotenvDocument(source: string): ParsedDocument;
|
|
39
|
+
export declare function parseJsonDocument(source: string): ParsedDocument;
|
|
40
|
+
export declare function renderEncryptedDocument(document: ParsedDocument, markers: readonly string[]): string;
|
|
41
|
+
export declare function canonicalSigningData(document: EncryptedDocument): string;
|
|
42
|
+
export declare function validateRecipientConsistency(document: EncryptedDocument): void;
|
|
43
|
+
export declare function extractAgeRecipients(marker: string): string[];
|
|
44
|
+
export declare function isEncryptedMarker(value: string): boolean;
|
|
45
|
+
export {};
|
package/dist/document.js
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
export class DocumentValidationError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'DocumentValidationError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
const markerPattern = /^ENC\[age:([A-Za-z0-9_-]+)\]$/;
|
|
8
|
+
const metadataKeys = new Set(['warning', 'version', 'members', 'recipients', 'maintainers', 'signatures']);
|
|
9
|
+
export function parseEncryptedDocument(source, format) {
|
|
10
|
+
return format === 'dotenv' ? parseDotenvDocument(source) : parseJsonDocument(source);
|
|
11
|
+
}
|
|
12
|
+
export function parseDotenvDocument(source) {
|
|
13
|
+
const metadata = { signatures: [] };
|
|
14
|
+
const values = [];
|
|
15
|
+
const lines = source.matchAll(/.*(?:\r\n|\n|\r|$)/g);
|
|
16
|
+
for (const match of lines) {
|
|
17
|
+
const line = match[0];
|
|
18
|
+
if (line === '')
|
|
19
|
+
continue;
|
|
20
|
+
const content = line.replace(/\r\n$|[\r\n]$/u, '');
|
|
21
|
+
const metadataMatch = /^\s*#\s*gcrypt(?:-(member|recipients|maintainers|signature))?\s*:\s*(.*?)\s*$/u.exec(content);
|
|
22
|
+
if (metadataMatch) {
|
|
23
|
+
const [, name, value] = metadataMatch;
|
|
24
|
+
if (name === undefined) {
|
|
25
|
+
if (metadata.version !== undefined)
|
|
26
|
+
throw new DocumentValidationError('Duplicate gcrypt version metadata');
|
|
27
|
+
if (value !== '2')
|
|
28
|
+
throw new DocumentValidationError('Unsupported gcrypt version');
|
|
29
|
+
metadata.version = 2;
|
|
30
|
+
}
|
|
31
|
+
else if (name === 'signature') {
|
|
32
|
+
metadata.signatures.push(value);
|
|
33
|
+
}
|
|
34
|
+
else if (name === 'member') {
|
|
35
|
+
metadata.members ??= [];
|
|
36
|
+
metadata.members.push(parseDotenvMember(value));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const key = name === 'recipients' ? 'recipients' : 'maintainers';
|
|
40
|
+
if (metadata[key] !== undefined)
|
|
41
|
+
throw new DocumentValidationError(`Duplicate gcrypt ${key} metadata`);
|
|
42
|
+
metadata[key] = splitMetadataList(value, key);
|
|
43
|
+
}
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const assignment = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*/u.exec(content);
|
|
47
|
+
if (!assignment)
|
|
48
|
+
continue;
|
|
49
|
+
const valueStart = match.index + assignment[0].length;
|
|
50
|
+
const rawValue = content.slice(assignment[0].length);
|
|
51
|
+
const marker = parseDotenvMarker(rawValue);
|
|
52
|
+
if (marker) {
|
|
53
|
+
values.push({ key: assignment[1], marker: marker.value, start: valueStart + marker.start, end: valueStart + marker.end });
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new DocumentValidationError(`Dotenv value ${assignment[1]} is not an encrypted marker`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const parsed = createParsedDocument('dotenv', source, metadata, values);
|
|
60
|
+
ensureUniqueKeys(parsed.values);
|
|
61
|
+
return parsed;
|
|
62
|
+
}
|
|
63
|
+
export function parseJsonDocument(source) {
|
|
64
|
+
let document;
|
|
65
|
+
try {
|
|
66
|
+
document = JSON.parse(source);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
throw new DocumentValidationError('Invalid JSON document');
|
|
70
|
+
}
|
|
71
|
+
if (!isRecord(document) || Array.isArray(document))
|
|
72
|
+
throw new DocumentValidationError('JSON document must be a top-level object');
|
|
73
|
+
if (!Object.hasOwn(document, '$gcrypt'))
|
|
74
|
+
throw new DocumentValidationError('JSON document is missing $gcrypt metadata');
|
|
75
|
+
const metadata = parseJsonMetadata(document.$gcrypt);
|
|
76
|
+
const values = [];
|
|
77
|
+
const scanner = new JsonObjectScanner(source);
|
|
78
|
+
for (const property of scanner.properties()) {
|
|
79
|
+
if (property.key === '$gcrypt')
|
|
80
|
+
continue;
|
|
81
|
+
if (property.type === 'object' || property.type === 'array') {
|
|
82
|
+
throw new DocumentValidationError(`JSON value ${property.key} must be a scalar`);
|
|
83
|
+
}
|
|
84
|
+
if (property.type !== 'string' || !isEncryptedMarker(property.value)) {
|
|
85
|
+
throw new DocumentValidationError(`JSON value ${property.key} is not an encrypted marker`);
|
|
86
|
+
}
|
|
87
|
+
values.push({ key: property.key, marker: property.value, jsonType: property.type, start: property.start, end: property.end });
|
|
88
|
+
}
|
|
89
|
+
return { format: 'json', source, metadata, values, sourceValues: values };
|
|
90
|
+
}
|
|
91
|
+
export function renderEncryptedDocument(document, markers) {
|
|
92
|
+
if (markers.length !== document.sourceValues.length)
|
|
93
|
+
throw new DocumentValidationError('Replacement marker count does not match document values');
|
|
94
|
+
let rendered = document.source;
|
|
95
|
+
for (let index = document.sourceValues.length - 1; index >= 0; index -= 1) {
|
|
96
|
+
const value = document.sourceValues[index];
|
|
97
|
+
const marker = markers[index];
|
|
98
|
+
if (!isEncryptedMarker(marker))
|
|
99
|
+
throw new DocumentValidationError('Replacement value is not an encrypted marker');
|
|
100
|
+
const replacement = document.format === 'json' ? JSON.stringify(marker) : marker;
|
|
101
|
+
rendered = `${rendered.slice(0, value.start)}${replacement}${rendered.slice(value.end)}`;
|
|
102
|
+
}
|
|
103
|
+
return rendered;
|
|
104
|
+
}
|
|
105
|
+
export function canonicalSigningData(document) {
|
|
106
|
+
return JSON.stringify({
|
|
107
|
+
format: document.format,
|
|
108
|
+
version: document.metadata.version,
|
|
109
|
+
members: document.metadata.members,
|
|
110
|
+
recipients: document.metadata.recipients,
|
|
111
|
+
maintainers: document.metadata.maintainers,
|
|
112
|
+
values: document.values.map(({ key, marker, jsonType }) => ({ key, marker, ...(jsonType ? { jsonType } : {}) })),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export function validateRecipientConsistency(document) {
|
|
116
|
+
const expected = recipientSet(document.metadata.recipients);
|
|
117
|
+
for (const value of document.values) {
|
|
118
|
+
const actual = recipientSet(extractAgeRecipients(value.marker));
|
|
119
|
+
if (actual.size !== expected.size || [...expected].some((recipient) => !actual.has(recipient))) {
|
|
120
|
+
throw new DocumentValidationError(`Recipients in ${value.key} do not match document metadata`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export function extractAgeRecipients(marker) {
|
|
125
|
+
const payload = markerPayload(marker);
|
|
126
|
+
let decoded;
|
|
127
|
+
try {
|
|
128
|
+
decoded = Buffer.from(payload, 'base64url').toString('utf8');
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
throw new DocumentValidationError('Encrypted marker has invalid base64url payload');
|
|
132
|
+
}
|
|
133
|
+
const lines = decoded.split(/\r?\n/u);
|
|
134
|
+
if (lines[0] !== 'age-encryption.org/v1')
|
|
135
|
+
throw new DocumentValidationError('Encrypted marker is not an age file');
|
|
136
|
+
const recipients = [];
|
|
137
|
+
for (const line of lines.slice(1)) {
|
|
138
|
+
if (line.startsWith('---'))
|
|
139
|
+
break;
|
|
140
|
+
const stanza = /^-> X25519 (\S+)$/u.exec(line);
|
|
141
|
+
if (stanza)
|
|
142
|
+
recipients.push(ageRecipientFromStanza(stanza[1]));
|
|
143
|
+
}
|
|
144
|
+
if (recipients.length === 0)
|
|
145
|
+
throw new DocumentValidationError('Encrypted marker has no X25519 recipients');
|
|
146
|
+
if (recipientSet(recipients).size !== recipients.length)
|
|
147
|
+
throw new DocumentValidationError('Encrypted marker has duplicate recipients');
|
|
148
|
+
return recipients;
|
|
149
|
+
}
|
|
150
|
+
export function isEncryptedMarker(value) {
|
|
151
|
+
return markerPattern.test(value);
|
|
152
|
+
}
|
|
153
|
+
function createParsedDocument(format, source, partial, values) {
|
|
154
|
+
const metadata = validateMetadata(partial);
|
|
155
|
+
return { format, source, metadata, values, sourceValues: values };
|
|
156
|
+
}
|
|
157
|
+
function parseDotenvMarker(rawValue) {
|
|
158
|
+
const match = /^(?:"(ENC\[age:[A-Za-z0-9_-]+\])"|'(ENC\[age:[A-Za-z0-9_-]+\])'|(ENC\[age:[A-Za-z0-9_-]+\]))\s*(?:#.*)?$/u.exec(rawValue);
|
|
159
|
+
if (!match)
|
|
160
|
+
return undefined;
|
|
161
|
+
const value = match[1] ?? match[2] ?? match[3];
|
|
162
|
+
const start = rawValue.indexOf(value);
|
|
163
|
+
return { value, start, end: start + value.length };
|
|
164
|
+
}
|
|
165
|
+
function parseJsonMetadata(value) {
|
|
166
|
+
if (!isRecord(value) || Array.isArray(value))
|
|
167
|
+
throw new DocumentValidationError('$gcrypt metadata must be an object');
|
|
168
|
+
for (const key of Object.keys(value)) {
|
|
169
|
+
if (!metadataKeys.has(key))
|
|
170
|
+
throw new DocumentValidationError(`Unknown $gcrypt metadata field ${key}`);
|
|
171
|
+
}
|
|
172
|
+
if (value.warning !== undefined && value.warning !== 'Do not manually edit this file. Use gcrypt instead.') {
|
|
173
|
+
throw new DocumentValidationError('Invalid $gcrypt warning');
|
|
174
|
+
}
|
|
175
|
+
return validateMetadata({
|
|
176
|
+
version: value.version === 2 ? 2 : undefined,
|
|
177
|
+
members: Array.isArray(value.members) ? value.members.map(parseJsonMember) : undefined,
|
|
178
|
+
recipients: Array.isArray(value.recipients) ? value.recipients : undefined,
|
|
179
|
+
maintainers: Array.isArray(value.maintainers) ? value.maintainers : undefined,
|
|
180
|
+
signatures: Array.isArray(value.signatures) ? value.signatures : undefined,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function validateMetadata(partial) {
|
|
184
|
+
if (partial.version !== 2)
|
|
185
|
+
throw new DocumentValidationError('Missing or unsupported gcrypt version');
|
|
186
|
+
const members = validateMembers(partial.members);
|
|
187
|
+
const recipients = validateStringList(partial.recipients, 'recipients');
|
|
188
|
+
const maintainers = validateStringList(partial.maintainers, 'maintainers');
|
|
189
|
+
const signatures = validateStringList(partial.signatures, 'signatures', true);
|
|
190
|
+
const memberRecipients = members.map(({ recipient }) => recipient);
|
|
191
|
+
const memberMaintainers = members.flatMap(({ signingKey, isMaintainer }) => isMaintainer ? [signingKey] : []);
|
|
192
|
+
if (!sameList(recipients, memberRecipients))
|
|
193
|
+
throw new DocumentValidationError('gcrypt recipients metadata does not match members');
|
|
194
|
+
if (!sameList(maintainers, memberMaintainers))
|
|
195
|
+
throw new DocumentValidationError('gcrypt maintainers metadata does not match members');
|
|
196
|
+
return { version: 2, members, recipients, maintainers, signatures };
|
|
197
|
+
}
|
|
198
|
+
function validateMembers(members) {
|
|
199
|
+
if (!members || members.length === 0)
|
|
200
|
+
throw new DocumentValidationError('Missing gcrypt members metadata');
|
|
201
|
+
const ids = new Set();
|
|
202
|
+
const recipients = new Set();
|
|
203
|
+
const signingKeys = new Set();
|
|
204
|
+
return members.map((member) => {
|
|
205
|
+
if (!isRecord(member) || Object.keys(member).length !== 4 || Object.keys(member).some((key) => !['id', 'recipient', 'signingKey', 'isMaintainer'].includes(key))) {
|
|
206
|
+
throw new DocumentValidationError('Invalid gcrypt member metadata');
|
|
207
|
+
}
|
|
208
|
+
if (typeof member.id !== 'string' || member.id === '' || /\s/u.test(member.id) || ids.has(member.id)) {
|
|
209
|
+
throw new DocumentValidationError('Invalid or duplicate gcrypt member id');
|
|
210
|
+
}
|
|
211
|
+
if (typeof member.recipient !== 'string' || member.recipient.trim() === '' || /\s/u.test(member.recipient) || recipients.has(member.recipient)) {
|
|
212
|
+
throw new DocumentValidationError('Invalid or duplicate gcrypt member recipient');
|
|
213
|
+
}
|
|
214
|
+
if (typeof member.signingKey !== 'string' || member.signingKey.trim() === '' || /\s/u.test(member.signingKey) || signingKeys.has(member.signingKey)) {
|
|
215
|
+
throw new DocumentValidationError('Invalid or duplicate gcrypt member signing key');
|
|
216
|
+
}
|
|
217
|
+
if (typeof member.isMaintainer !== 'boolean')
|
|
218
|
+
throw new DocumentValidationError('Invalid gcrypt member maintainer role');
|
|
219
|
+
ids.add(member.id);
|
|
220
|
+
recipients.add(member.recipient);
|
|
221
|
+
signingKeys.add(member.signingKey);
|
|
222
|
+
try {
|
|
223
|
+
validateAgeRecipient(member.recipient);
|
|
224
|
+
validateSigningPublicKey(member.signingKey);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
throw new DocumentValidationError('Invalid gcrypt member key metadata');
|
|
228
|
+
}
|
|
229
|
+
return { id: member.id, recipient: member.recipient, signingKey: member.signingKey, isMaintainer: member.isMaintainer };
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function validateStringList(values, name, allowEmpty = false) {
|
|
233
|
+
if (!values || (!allowEmpty && values.length === 0))
|
|
234
|
+
throw new DocumentValidationError(`Missing gcrypt ${name} metadata`);
|
|
235
|
+
if (values.some((value) => typeof value !== 'string' || value.trim() === '' || /[\s,]/u.test(value))) {
|
|
236
|
+
throw new DocumentValidationError(`Invalid gcrypt ${name} metadata`);
|
|
237
|
+
}
|
|
238
|
+
if (new Set(values).size !== values.length)
|
|
239
|
+
throw new DocumentValidationError(`Duplicate gcrypt ${name} metadata`);
|
|
240
|
+
return [...values];
|
|
241
|
+
}
|
|
242
|
+
function splitMetadataList(value, name) {
|
|
243
|
+
if (value === '')
|
|
244
|
+
throw new DocumentValidationError(`Missing gcrypt ${name} metadata`);
|
|
245
|
+
return value.split(',');
|
|
246
|
+
}
|
|
247
|
+
function parseDotenvMember(value) {
|
|
248
|
+
const fields = value.split(',');
|
|
249
|
+
if (fields.length !== 4)
|
|
250
|
+
throw new DocumentValidationError('Invalid gcrypt member metadata');
|
|
251
|
+
const [id, recipient, signingKey, isMaintainer] = fields;
|
|
252
|
+
if (isMaintainer !== 'true' && isMaintainer !== 'false')
|
|
253
|
+
throw new DocumentValidationError('Invalid gcrypt member metadata');
|
|
254
|
+
return { id, recipient, signingKey, isMaintainer: isMaintainer === 'true' };
|
|
255
|
+
}
|
|
256
|
+
function parseJsonMember(value) {
|
|
257
|
+
if (!isRecord(value) || Array.isArray(value))
|
|
258
|
+
throw new DocumentValidationError('Invalid gcrypt member metadata');
|
|
259
|
+
return {
|
|
260
|
+
id: value.id,
|
|
261
|
+
recipient: value.recipient,
|
|
262
|
+
signingKey: value.signingKey,
|
|
263
|
+
isMaintainer: value.isMaintainer,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function sameList(left, right) {
|
|
267
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
268
|
+
}
|
|
269
|
+
function markerPayload(marker) {
|
|
270
|
+
const match = markerPattern.exec(marker);
|
|
271
|
+
if (!match)
|
|
272
|
+
throw new DocumentValidationError('Invalid encrypted marker');
|
|
273
|
+
return match[1];
|
|
274
|
+
}
|
|
275
|
+
function recipientSet(recipients) {
|
|
276
|
+
if (new Set(recipients).size !== recipients.length)
|
|
277
|
+
throw new DocumentValidationError('Duplicate recipients');
|
|
278
|
+
return new Set(recipients);
|
|
279
|
+
}
|
|
280
|
+
// age files encode X25519 recipient bytes in the stanza; metadata uses bech32 age1 keys.
|
|
281
|
+
function ageRecipientFromStanza(stanza) {
|
|
282
|
+
if (stanza.startsWith('age1'))
|
|
283
|
+
return stanza; // Supports readable fixture files as well.
|
|
284
|
+
let bytes;
|
|
285
|
+
try {
|
|
286
|
+
bytes = Buffer.from(stanza, 'base64');
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
throw new DocumentValidationError('Encrypted marker has an invalid X25519 recipient');
|
|
290
|
+
}
|
|
291
|
+
if (bytes.length !== 32)
|
|
292
|
+
throw new DocumentValidationError('Encrypted marker has an invalid X25519 recipient');
|
|
293
|
+
const data = convertBits([...bytes], 8, 5);
|
|
294
|
+
const checksumInput = [...bech32Prefix('age'), ...data];
|
|
295
|
+
return `age1${data.map((word) => 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'[word]).join('')}${bech32Checksum(checksumInput).map((word) => 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'[word]).join('')}`;
|
|
296
|
+
}
|
|
297
|
+
function convertBits(values, from, to) {
|
|
298
|
+
let accumulator = 0;
|
|
299
|
+
let bits = 0;
|
|
300
|
+
const output = [];
|
|
301
|
+
for (const value of values) {
|
|
302
|
+
accumulator = (accumulator << from) | value;
|
|
303
|
+
bits += from;
|
|
304
|
+
while (bits >= to) {
|
|
305
|
+
bits -= to;
|
|
306
|
+
output.push((accumulator >> bits) & 31);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (bits > 0)
|
|
310
|
+
output.push((accumulator << (to - bits)) & 31);
|
|
311
|
+
return output;
|
|
312
|
+
}
|
|
313
|
+
function bech32Prefix(prefix) { return [...prefix].map((character) => character.charCodeAt(0) >> 5).concat(0, [...prefix].map((character) => character.charCodeAt(0) & 31)); }
|
|
314
|
+
function bech32Checksum(words) {
|
|
315
|
+
let value = 1;
|
|
316
|
+
for (const word of [...words, 0, 0, 0, 0, 0, 0])
|
|
317
|
+
value = bech32Polymod(value) ^ word;
|
|
318
|
+
value ^= 1;
|
|
319
|
+
return [5, 4, 3, 2, 1, 0].map((shift) => (value >> (shift * 5)) & 31);
|
|
320
|
+
}
|
|
321
|
+
function bech32Polymod(value) {
|
|
322
|
+
const top = value >>> 25;
|
|
323
|
+
let result = (value & 0x1ffffff) << 5;
|
|
324
|
+
for (const [index, generator] of [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3].entries())
|
|
325
|
+
if ((top >> index) & 1)
|
|
326
|
+
result ^= generator;
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
function ensureUniqueKeys(values) {
|
|
330
|
+
if (new Set(values.map(({ key }) => key)).size !== values.length)
|
|
331
|
+
throw new DocumentValidationError('Duplicate document keys are not supported');
|
|
332
|
+
}
|
|
333
|
+
function isRecord(value) {
|
|
334
|
+
return typeof value === 'object' && value !== null;
|
|
335
|
+
}
|
|
336
|
+
class JsonObjectScanner {
|
|
337
|
+
source;
|
|
338
|
+
position = 0;
|
|
339
|
+
constructor(source) {
|
|
340
|
+
this.source = source;
|
|
341
|
+
}
|
|
342
|
+
*properties() {
|
|
343
|
+
this.skipWhitespace();
|
|
344
|
+
this.expect('{');
|
|
345
|
+
this.skipWhitespace();
|
|
346
|
+
if (this.peek() === '}')
|
|
347
|
+
return;
|
|
348
|
+
while (true) {
|
|
349
|
+
const key = this.readString();
|
|
350
|
+
this.skipWhitespace();
|
|
351
|
+
this.expect(':');
|
|
352
|
+
this.skipWhitespace();
|
|
353
|
+
const start = this.position;
|
|
354
|
+
const { value, type } = this.readValue();
|
|
355
|
+
const end = this.position;
|
|
356
|
+
yield { key, value, type, start, end };
|
|
357
|
+
this.skipWhitespace();
|
|
358
|
+
if (this.peek() === '}')
|
|
359
|
+
return;
|
|
360
|
+
this.expect(',');
|
|
361
|
+
this.skipWhitespace();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
readValue() {
|
|
365
|
+
if (this.peek() === '"')
|
|
366
|
+
return { value: this.readString(), type: 'string' };
|
|
367
|
+
if (this.source.startsWith('true', this.position)) {
|
|
368
|
+
this.position += 4;
|
|
369
|
+
return { value: 'true', type: 'boolean' };
|
|
370
|
+
}
|
|
371
|
+
if (this.source.startsWith('false', this.position)) {
|
|
372
|
+
this.position += 5;
|
|
373
|
+
return { value: 'false', type: 'boolean' };
|
|
374
|
+
}
|
|
375
|
+
if (this.source.startsWith('null', this.position)) {
|
|
376
|
+
this.position += 4;
|
|
377
|
+
return { value: 'null', type: 'null' };
|
|
378
|
+
}
|
|
379
|
+
if (this.peek() === '{' || this.peek() === '[') {
|
|
380
|
+
const type = this.peek() === '{' ? 'object' : 'array';
|
|
381
|
+
return { value: this.readCompound(), type };
|
|
382
|
+
}
|
|
383
|
+
const match = /-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/u.exec(this.source.slice(this.position));
|
|
384
|
+
if (!match)
|
|
385
|
+
throw new DocumentValidationError('Invalid JSON value');
|
|
386
|
+
this.position += match[0].length;
|
|
387
|
+
return { value: match[0], type: 'number' };
|
|
388
|
+
}
|
|
389
|
+
readCompound() {
|
|
390
|
+
const start = this.position;
|
|
391
|
+
const open = this.source[this.position];
|
|
392
|
+
const close = open === '{' ? '}' : ']';
|
|
393
|
+
let depth = 0;
|
|
394
|
+
do {
|
|
395
|
+
const character = this.source[this.position];
|
|
396
|
+
if (character === '"')
|
|
397
|
+
this.readString();
|
|
398
|
+
else {
|
|
399
|
+
this.position += 1;
|
|
400
|
+
if (character === open)
|
|
401
|
+
depth += 1;
|
|
402
|
+
if (character === close)
|
|
403
|
+
depth -= 1;
|
|
404
|
+
}
|
|
405
|
+
} while (depth > 0 && this.position < this.source.length);
|
|
406
|
+
return this.source.slice(start, this.position);
|
|
407
|
+
}
|
|
408
|
+
readString() {
|
|
409
|
+
const start = this.position;
|
|
410
|
+
this.expect('"');
|
|
411
|
+
while (this.position < this.source.length) {
|
|
412
|
+
const character = this.source[this.position];
|
|
413
|
+
this.position += 1;
|
|
414
|
+
if (character === '\\')
|
|
415
|
+
this.position += 1;
|
|
416
|
+
else if (character === '"') {
|
|
417
|
+
try {
|
|
418
|
+
return JSON.parse(this.source.slice(start, this.position));
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
throw new DocumentValidationError('Invalid JSON string');
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
throw new DocumentValidationError('Unterminated JSON string');
|
|
426
|
+
}
|
|
427
|
+
skipWhitespace() { while (/\s/u.test(this.peek()))
|
|
428
|
+
this.position += 1; }
|
|
429
|
+
peek() { return this.source[this.position] ?? ''; }
|
|
430
|
+
expect(character) {
|
|
431
|
+
if (this.peek() !== character)
|
|
432
|
+
throw new DocumentValidationError('Invalid JSON document');
|
|
433
|
+
this.position += 1;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
import { validateAgeRecipient, validateSigningPublicKey } from './crypto.js';
|
|
437
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
|