@attest-it/core 0.0.0 → 0.2.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/dist/{chunk-UWYR7JNE.js → chunk-CEE7ONNG.js} +20 -25
- package/dist/chunk-CEE7ONNG.js.map +1 -0
- package/dist/core-alpha.d.ts +47 -36
- package/dist/core-beta.d.ts +47 -36
- package/dist/core-public.d.ts +47 -36
- package/dist/core-unstripped.d.ts +47 -36
- package/dist/{crypto-ITLMIMRJ.js → crypto-VAXWUGKL.js} +3 -3
- package/dist/{crypto-ITLMIMRJ.js.map → crypto-VAXWUGKL.js.map} +1 -1
- package/dist/index.cjs +29 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -36
- package/dist/index.d.ts +50 -37
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-UWYR7JNE.js.map +0 -1
|
@@ -90,7 +90,6 @@ async function cleanupFiles(...paths) {
|
|
|
90
90
|
async function generateKeyPair(options = {}) {
|
|
91
91
|
await ensureOpenSSLAvailable();
|
|
92
92
|
const {
|
|
93
|
-
algorithm = "ed25519",
|
|
94
93
|
privatePath = getDefaultPrivateKeyPath(),
|
|
95
94
|
publicPath = getDefaultPublicKeyPath(),
|
|
96
95
|
force = false
|
|
@@ -108,7 +107,15 @@ async function generateKeyPair(options = {}) {
|
|
|
108
107
|
await ensureDir(path.dirname(privatePath));
|
|
109
108
|
await ensureDir(path.dirname(publicPath));
|
|
110
109
|
try {
|
|
111
|
-
const genArgs =
|
|
110
|
+
const genArgs = [
|
|
111
|
+
"genpkey",
|
|
112
|
+
"-algorithm",
|
|
113
|
+
"RSA",
|
|
114
|
+
"-pkeyopt",
|
|
115
|
+
"rsa_keygen_bits:2048",
|
|
116
|
+
"-out",
|
|
117
|
+
privatePath
|
|
118
|
+
];
|
|
112
119
|
const genResult = await runOpenSSL(genArgs);
|
|
113
120
|
if (genResult.exitCode !== 0) {
|
|
114
121
|
throw new Error(`Failed to generate private key: ${genResult.stderr}`);
|
|
@@ -140,16 +147,8 @@ async function sign(options) {
|
|
|
140
147
|
const sigFile = path.join(tmpDir, "sig.bin");
|
|
141
148
|
try {
|
|
142
149
|
await fs.writeFile(dataFile, processBuffer);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
"-sign",
|
|
146
|
-
"-inkey",
|
|
147
|
-
privateKeyPath,
|
|
148
|
-
"-in",
|
|
149
|
-
dataFile,
|
|
150
|
-
"-out",
|
|
151
|
-
sigFile
|
|
152
|
-
]);
|
|
150
|
+
const signArgs = ["dgst", "-sha256", "-sign", privateKeyPath, "-out", sigFile, dataFile];
|
|
151
|
+
const result = await runOpenSSL(signArgs);
|
|
153
152
|
if (result.exitCode !== 0) {
|
|
154
153
|
throw new Error(`Failed to sign data: ${result.stderr}`);
|
|
155
154
|
}
|
|
@@ -177,21 +176,17 @@ async function verify(options) {
|
|
|
177
176
|
try {
|
|
178
177
|
await fs.writeFile(dataFile, processBuffer);
|
|
179
178
|
await fs.writeFile(sigFile, sigBuffer);
|
|
180
|
-
const
|
|
181
|
-
"
|
|
179
|
+
const verifyArgs = [
|
|
180
|
+
"dgst",
|
|
181
|
+
"-sha256",
|
|
182
182
|
"-verify",
|
|
183
|
-
"-pubin",
|
|
184
|
-
"-inkey",
|
|
185
183
|
publicKeyPath,
|
|
186
|
-
"-
|
|
184
|
+
"-signature",
|
|
187
185
|
sigFile,
|
|
188
|
-
"-in",
|
|
189
186
|
dataFile
|
|
190
|
-
]
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
return result.exitCode === 0;
|
|
187
|
+
];
|
|
188
|
+
const result = await runOpenSSL(verifyArgs);
|
|
189
|
+
return result.exitCode === 0 && result.stdout.toString().includes("Verified OK");
|
|
195
190
|
} finally {
|
|
196
191
|
try {
|
|
197
192
|
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
@@ -208,5 +203,5 @@ async function setKeyPermissions(keyPath) {
|
|
|
208
203
|
}
|
|
209
204
|
|
|
210
205
|
export { checkOpenSSL, generateKeyPair, getDefaultPrivateKeyPath, getDefaultPublicKeyPath, setKeyPermissions, sign, verify };
|
|
211
|
-
//# sourceMappingURL=chunk-
|
|
212
|
-
//# sourceMappingURL=chunk-
|
|
206
|
+
//# sourceMappingURL=chunk-CEE7ONNG.js.map
|
|
207
|
+
//# sourceMappingURL=chunk-CEE7ONNG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/crypto.ts"],"names":[],"mappings":"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","file":"chunk-CEE7ONNG.js","sourcesContent":["/**\n * Cryptographic utilities for key generation, signing, and verification.\n *\n * @remarks\n * This module provides cryptographic operations using OpenSSL for key management\n * and signature verification. It uses RSA-2048 with SHA-256 for signatures,\n * which is universally supported across all OpenSSL and LibreSSL versions.\n *\n * @packageDocumentation\n */\n\nimport { spawn } from 'node:child_process'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\n\n/**\n * Paths to a generated keypair.\n * @public\n */\nexport interface KeyPaths {\n /** Path to the private key file */\n privatePath: string\n /** Path to the public key file */\n publicPath: string\n}\n\n/**\n * Options for key generation.\n * @public\n */\nexport interface KeygenOptions {\n /** Path for private key (default: OS-specific config dir) */\n privatePath?: string\n /** Path for public key (default: repo root) */\n publicPath?: string\n /** Overwrite existing keys (default: false) */\n force?: boolean\n}\n\n/**\n * Options for signing data.\n * @public\n */\nexport interface SignOptions {\n /** Path to the private key file */\n privateKeyPath: string\n /** Data to sign (string or Buffer) */\n data: string | Buffer\n}\n\n/**\n * Options for verifying signatures.\n * @public\n */\nexport interface VerifyOptions {\n /** Path to the public key file */\n publicKeyPath: string\n /** Original data that was signed */\n data: string | Buffer\n /** Base64-encoded signature to verify */\n signature: string\n}\n\n/**\n * Result from spawning an OpenSSL process.\n * @internal\n */\ninterface SpawnResult {\n /** Process exit code */\n exitCode: number\n /** Standard output as Buffer */\n stdout: Buffer\n /** Standard error as string */\n stderr: string\n}\n\n/**\n * Run OpenSSL with the given arguments.\n * @param args - Command-line arguments for OpenSSL\n * @param stdin - Optional data to write to stdin\n * @returns Process result with exit code and outputs\n * @internal\n */\nasync function runOpenSSL(args: string[], stdin?: Buffer): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn('openssl', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n const stdoutChunks: Buffer[] = []\n let stderr = ''\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk)\n })\n\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n\n child.on('error', (err) => {\n reject(new Error(`Failed to spawn OpenSSL: ${err.message}`))\n })\n\n child.on('close', (code) => {\n resolve({\n exitCode: code ?? 1,\n stdout: Buffer.concat(stdoutChunks),\n stderr,\n })\n })\n\n if (stdin) {\n child.stdin.write(stdin)\n }\n child.stdin.end()\n })\n}\n\n/**\n * Check if OpenSSL is available and get version info.\n * @returns OpenSSL version string\n * @throws Error if OpenSSL is not available\n * @public\n */\nexport async function checkOpenSSL(): Promise<string> {\n const result = await runOpenSSL(['version'])\n\n if (result.exitCode !== 0) {\n throw new Error(`OpenSSL check failed: ${result.stderr}`)\n }\n\n return result.stdout.toString().trim()\n}\n\n/**\n * Cached result of OpenSSL availability check.\n * @internal\n */\nlet openSSLChecked = false\n\n/**\n * Ensure OpenSSL is available before performing cryptographic operations.\n * @throws Error with installation instructions if OpenSSL is not available\n * @internal\n */\nasync function ensureOpenSSLAvailable(): Promise<void> {\n if (openSSLChecked) {\n return\n }\n\n try {\n await checkOpenSSL()\n openSSLChecked = true\n } catch {\n throw new Error(\n 'OpenSSL is not installed or not in PATH. ' +\n 'Please install OpenSSL to use attest-it. ' +\n 'On macOS: brew install openssl. ' +\n 'On Ubuntu: apt-get install openssl',\n )\n }\n}\n\n/**\n * Get the default private key path based on OS.\n * - macOS/Linux: ~/.config/attest-it/private.pem\n * - Windows: %APPDATA%\\attest-it\\private.pem\n * @public\n */\nexport function getDefaultPrivateKeyPath(): string {\n const homeDir = os.homedir()\n\n if (process.platform === 'win32') {\n const appData = process.env.APPDATA ?? path.join(homeDir, 'AppData', 'Roaming')\n return path.join(appData, 'attest-it', 'private.pem')\n }\n\n return path.join(homeDir, '.config', 'attest-it', 'private.pem')\n}\n\n/**\n * Get the default public key path (in repo).\n * @public\n */\nexport function getDefaultPublicKeyPath(): string {\n return path.join(process.cwd(), 'attest-it-public.pem')\n}\n\n/**\n * Ensure a directory exists, creating it and parent directories if needed.\n * @param dirPath - Directory path to create\n * @internal\n */\nasync function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true })\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code !== 'EEXIST') {\n throw err\n }\n }\n}\n\n/**\n * Check if a file exists.\n * @param filePath - File path to check\n * @returns true if file exists\n * @internal\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Clean up one or more files, ignoring errors if files don't exist.\n * @param paths - File paths to delete\n * @internal\n */\nasync function cleanupFiles(...paths: string[]): Promise<void> {\n for (const filePath of paths) {\n try {\n await fs.unlink(filePath)\n } catch {\n // Ignore cleanup errors - file may not exist\n }\n }\n}\n\n/**\n * Generate a new RSA-2048 keypair using OpenSSL.\n *\n * RSA-2048 with SHA-256 is used because it's universally supported across\n * all OpenSSL and LibreSSL versions, including older macOS systems.\n *\n * @param options - Generation options\n * @returns Paths to generated keys\n * @throws Error if OpenSSL fails or keys exist without force\n * @public\n */\nexport async function generateKeyPair(options: KeygenOptions = {}): Promise<KeyPaths> {\n // Ensure OpenSSL is available before proceeding\n await ensureOpenSSLAvailable()\n\n const {\n privatePath = getDefaultPrivateKeyPath(),\n publicPath = getDefaultPublicKeyPath(),\n force = false,\n } = options\n\n // Check if keys already exist\n const privateExists = await fileExists(privatePath)\n const publicExists = await fileExists(publicPath)\n\n if ((privateExists || publicExists) && !force) {\n const existing = [privateExists ? privatePath : null, publicExists ? publicPath : null].filter(\n Boolean,\n )\n throw new Error(\n `Key files already exist: ${existing.join(', ')}. Use force: true to overwrite.`,\n )\n }\n\n // Ensure parent directories exist\n await ensureDir(path.dirname(privatePath))\n await ensureDir(path.dirname(publicPath))\n\n try {\n // Generate RSA-2048 private key\n const genArgs = [\n 'genpkey',\n '-algorithm',\n 'RSA',\n '-pkeyopt',\n 'rsa_keygen_bits:2048',\n '-out',\n privatePath,\n ]\n\n const genResult = await runOpenSSL(genArgs)\n if (genResult.exitCode !== 0) {\n throw new Error(`Failed to generate private key: ${genResult.stderr}`)\n }\n\n // Set restrictive permissions on private key\n await setKeyPermissions(privatePath)\n\n // Extract public key\n const pubResult = await runOpenSSL(['pkey', '-in', privatePath, '-pubout', '-out', publicPath])\n\n if (pubResult.exitCode !== 0) {\n throw new Error(`Failed to extract public key: ${pubResult.stderr}`)\n }\n\n return {\n privatePath,\n publicPath,\n }\n } catch (err) {\n // Clean up both key files on any failure\n await cleanupFiles(privatePath, publicPath)\n throw err\n }\n}\n\n/**\n * Sign data using an RSA private key with SHA-256.\n *\n * Uses `openssl dgst -sha256 -sign` which is universally supported across\n * all OpenSSL and LibreSSL versions.\n *\n * @param options - Signing options\n * @returns Base64-encoded signature\n * @throws Error if signing fails\n * @public\n */\nexport async function sign(options: SignOptions): Promise<string> {\n // Ensure OpenSSL is available before proceeding\n await ensureOpenSSLAvailable()\n\n const { privateKeyPath, data } = options\n\n // Check if private key exists\n if (!(await fileExists(privateKeyPath))) {\n throw new Error(`Private key not found: ${privateKeyPath}`)\n }\n\n // Convert data to Buffer\n const dataBuffer = typeof data === 'string' ? Buffer.from(data, 'utf8') : data\n\n // OpenSSL dgst cannot handle empty files, so we need to add a single byte\n // for empty data and document this limitation\n const processBuffer = dataBuffer.length === 0 ? Buffer.from([0x00]) : dataBuffer\n\n // Create temporary directory with OS-level uniqueness guarantees\n // This prevents TOCTOU race conditions that Math.random() would allow\n const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const dataFile = path.join(tmpDir, 'data.bin')\n const sigFile = path.join(tmpDir, 'sig.bin')\n\n try {\n // Write data to temp file\n await fs.writeFile(dataFile, processBuffer)\n\n // Sign using openssl dgst -sha256 (cross-platform compatible)\n const signArgs = ['dgst', '-sha256', '-sign', privateKeyPath, '-out', sigFile, dataFile]\n const result = await runOpenSSL(signArgs)\n\n if (result.exitCode !== 0) {\n throw new Error(`Failed to sign data: ${result.stderr}`)\n }\n\n // Read the signature\n const sigBuffer = await fs.readFile(sigFile)\n return sigBuffer.toString('base64')\n } finally {\n // Clean up temp directory and all files within it\n try {\n await fs.rm(tmpDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors - OS will eventually clean tmpdir\n }\n }\n}\n\n/**\n * Verify a signature using an RSA public key with SHA-256.\n *\n * Uses `openssl dgst -sha256 -verify` which is universally supported across\n * all OpenSSL and LibreSSL versions.\n *\n * @param options - Verification options\n * @returns true if signature is valid\n * @throws Error if verification fails (not just invalid signature)\n * @public\n */\nexport async function verify(options: VerifyOptions): Promise<boolean> {\n // Ensure OpenSSL is available before proceeding\n await ensureOpenSSLAvailable()\n\n const { publicKeyPath, data, signature } = options\n\n // Check if public key exists\n if (!(await fileExists(publicKeyPath))) {\n throw new Error(`Public key not found: ${publicKeyPath}`)\n }\n\n // Convert data to Buffer\n const dataBuffer = typeof data === 'string' ? Buffer.from(data, 'utf8') : data\n\n // OpenSSL dgst cannot handle empty files, so we use the same workaround\n // as in sign() - add a single byte for empty data\n const processBuffer = dataBuffer.length === 0 ? Buffer.from([0x00]) : dataBuffer\n\n // Decode signature from base64\n const sigBuffer = Buffer.from(signature, 'base64')\n\n // Create temporary directory with OS-level uniqueness guarantees\n // This prevents TOCTOU race conditions that Math.random() would allow\n const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const dataFile = path.join(tmpDir, 'data.bin')\n const sigFile = path.join(tmpDir, 'sig.bin')\n\n try {\n // Write data and signature to temp files\n await fs.writeFile(dataFile, processBuffer)\n await fs.writeFile(sigFile, sigBuffer)\n\n // Verify using openssl dgst -sha256 (cross-platform compatible)\n const verifyArgs = [\n 'dgst',\n '-sha256',\n '-verify',\n publicKeyPath,\n '-signature',\n sigFile,\n dataFile,\n ]\n const result = await runOpenSSL(verifyArgs)\n\n // dgst -verify: Exit code 0 means valid, non-0 means invalid\n // Output contains \"Verified OK\" on success\n return result.exitCode === 0 && result.stdout.toString().includes('Verified OK')\n } finally {\n // Clean up temp directory and all files within it\n try {\n await fs.rm(tmpDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors - OS will eventually clean tmpdir\n }\n }\n}\n\n/**\n * Set restrictive permissions on a private key file.\n * @param keyPath - Path to the private key\n * @public\n */\nexport async function setKeyPermissions(keyPath: string): Promise<void> {\n // On Windows, use fs.chmod which has limited effect\n // On Unix, set to 0o600 (read/write for owner only)\n if (process.platform === 'win32') {\n // Windows doesn't support Unix-style permissions in the same way\n // But we still call chmod for consistency\n await fs.chmod(keyPath, 0o600)\n } else {\n await fs.chmod(keyPath, 0o600)\n }\n}\n"]}
|
package/dist/core-alpha.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Supported signature algorithms.
|
|
5
|
-
* @public
|
|
6
|
-
*/
|
|
7
|
-
export declare type Algorithm = 'ed25519' | 'rsa';
|
|
8
|
-
|
|
9
3
|
/**
|
|
10
4
|
* A single attestation entry.
|
|
11
5
|
* @public
|
|
@@ -49,6 +43,8 @@ export declare interface AttestItConfig {
|
|
|
49
43
|
settings: AttestItSettings;
|
|
50
44
|
/** Named test suites with their configurations */
|
|
51
45
|
suites: Record<string, SuiteConfig>;
|
|
46
|
+
/** Named groups of suites */
|
|
47
|
+
groups?: Record<string, string[]>;
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
/**
|
|
@@ -64,8 +60,6 @@ export declare interface AttestItSettings {
|
|
|
64
60
|
attestationsPath: string;
|
|
65
61
|
/** Default command to execute for attestation (can be overridden per suite) */
|
|
66
62
|
defaultCommand?: string;
|
|
67
|
-
/** Cryptographic algorithm to use for signatures */
|
|
68
|
-
algorithm: 'ed25519' | 'rsa';
|
|
69
63
|
}
|
|
70
64
|
|
|
71
65
|
/**
|
|
@@ -142,27 +136,26 @@ export declare class ConfigNotFoundError extends Error {
|
|
|
142
136
|
* Zod schema for the full configuration file.
|
|
143
137
|
*/
|
|
144
138
|
declare const configSchema: z.ZodObject<{
|
|
139
|
+
groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
|
|
145
140
|
settings: z.ZodDefault<z.ZodObject<{
|
|
146
|
-
algorithm: z.ZodDefault<z.ZodEnum<["ed25519", "rsa"]>>;
|
|
147
141
|
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
148
142
|
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
149
143
|
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
150
144
|
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
151
|
-
}, "
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
publicKeyPath?: string | undefined;
|
|
163
|
-
}>>;
|
|
145
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
146
|
+
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
147
|
+
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
148
|
+
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
149
|
+
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
150
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
151
|
+
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
152
|
+
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
153
|
+
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
154
|
+
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
155
|
+
}, z.ZodTypeAny, "passthrough">>>;
|
|
164
156
|
suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
165
157
|
command: z.ZodOptional<z.ZodString>;
|
|
158
|
+
depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
166
159
|
description: z.ZodOptional<z.ZodString>;
|
|
167
160
|
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
168
161
|
ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
@@ -170,6 +163,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
170
163
|
packages: z.ZodArray<z.ZodString, "many">;
|
|
171
164
|
}, "strict", z.ZodTypeAny, {
|
|
172
165
|
command?: string | undefined;
|
|
166
|
+
depends_on?: string[] | undefined;
|
|
173
167
|
description?: string | undefined;
|
|
174
168
|
files?: string[] | undefined;
|
|
175
169
|
ignore?: string[] | undefined;
|
|
@@ -177,6 +171,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
177
171
|
packages: string[];
|
|
178
172
|
}, {
|
|
179
173
|
command?: string | undefined;
|
|
174
|
+
depends_on?: string[] | undefined;
|
|
180
175
|
description?: string | undefined;
|
|
181
176
|
files?: string[] | undefined;
|
|
182
177
|
ignore?: string[] | undefined;
|
|
@@ -184,6 +179,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
184
179
|
packages: string[];
|
|
185
180
|
}>>, Record<string, {
|
|
186
181
|
command?: string | undefined;
|
|
182
|
+
depends_on?: string[] | undefined;
|
|
187
183
|
description?: string | undefined;
|
|
188
184
|
files?: string[] | undefined;
|
|
189
185
|
ignore?: string[] | undefined;
|
|
@@ -191,6 +187,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
191
187
|
packages: string[];
|
|
192
188
|
}>, Record<string, {
|
|
193
189
|
command?: string | undefined;
|
|
190
|
+
depends_on?: string[] | undefined;
|
|
194
191
|
description?: string | undefined;
|
|
195
192
|
files?: string[] | undefined;
|
|
196
193
|
ignore?: string[] | undefined;
|
|
@@ -199,15 +196,16 @@ declare const configSchema: z.ZodObject<{
|
|
|
199
196
|
}>>;
|
|
200
197
|
version: z.ZodLiteral<1>;
|
|
201
198
|
}, "strict", z.ZodTypeAny, {
|
|
199
|
+
groups?: Record<string, string[]> | undefined;
|
|
202
200
|
settings: {
|
|
203
|
-
algorithm: "ed25519" | "rsa";
|
|
204
201
|
attestationsPath: string;
|
|
205
202
|
defaultCommand?: string | undefined;
|
|
206
203
|
maxAgeDays: number;
|
|
207
204
|
publicKeyPath: string;
|
|
208
|
-
};
|
|
205
|
+
} & { [k: string]: unknown };
|
|
209
206
|
suites: Record<string, {
|
|
210
207
|
command?: string | undefined;
|
|
208
|
+
depends_on?: string[] | undefined;
|
|
211
209
|
description?: string | undefined;
|
|
212
210
|
files?: string[] | undefined;
|
|
213
211
|
ignore?: string[] | undefined;
|
|
@@ -216,15 +214,16 @@ declare const configSchema: z.ZodObject<{
|
|
|
216
214
|
}>;
|
|
217
215
|
version: 1;
|
|
218
216
|
}, {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
attestationsPath
|
|
222
|
-
defaultCommand
|
|
223
|
-
maxAgeDays
|
|
224
|
-
publicKeyPath
|
|
225
|
-
}
|
|
217
|
+
groups?: Record<string, string[]> | undefined;
|
|
218
|
+
settings?: undefined | z.objectInputType<{
|
|
219
|
+
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
220
|
+
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
221
|
+
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
222
|
+
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
223
|
+
}, z.ZodTypeAny, "passthrough">;
|
|
226
224
|
suites: Record<string, {
|
|
227
225
|
command?: string | undefined;
|
|
226
|
+
depends_on?: string[] | undefined;
|
|
228
227
|
description?: string | undefined;
|
|
229
228
|
files?: string[] | undefined;
|
|
230
229
|
ignore?: string[] | undefined;
|
|
@@ -326,7 +325,11 @@ export declare interface FingerprintResult {
|
|
|
326
325
|
}
|
|
327
326
|
|
|
328
327
|
/**
|
|
329
|
-
* Generate a new keypair using OpenSSL.
|
|
328
|
+
* Generate a new RSA-2048 keypair using OpenSSL.
|
|
329
|
+
*
|
|
330
|
+
* RSA-2048 with SHA-256 is used because it's universally supported across
|
|
331
|
+
* all OpenSSL and LibreSSL versions, including older macOS systems.
|
|
332
|
+
*
|
|
330
333
|
* @param options - Generation options
|
|
331
334
|
* @returns Paths to generated keys
|
|
332
335
|
* @throws Error if OpenSSL fails or keys exist without force
|
|
@@ -353,8 +356,6 @@ export declare function getDefaultPublicKeyPath(): string;
|
|
|
353
356
|
* @public
|
|
354
357
|
*/
|
|
355
358
|
export declare interface KeygenOptions {
|
|
356
|
-
/** Algorithm to use (default: ed25519) */
|
|
357
|
-
algorithm?: Algorithm;
|
|
358
359
|
/** Path for private key (default: OS-specific config dir) */
|
|
359
360
|
privatePath?: string;
|
|
360
361
|
/** Path for public key (default: repo root) */
|
|
@@ -490,7 +491,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
|
|
|
490
491
|
export declare function setKeyPermissions(keyPath: string): Promise<void>;
|
|
491
492
|
|
|
492
493
|
/**
|
|
493
|
-
* Sign data using
|
|
494
|
+
* Sign data using an RSA private key with SHA-256.
|
|
495
|
+
*
|
|
496
|
+
* Uses `openssl dgst -sha256 -sign` which is universally supported across
|
|
497
|
+
* all OpenSSL and LibreSSL versions.
|
|
498
|
+
*
|
|
494
499
|
* @param options - Signing options
|
|
495
500
|
* @returns Base64-encoded signature
|
|
496
501
|
* @throws Error if signing fails
|
|
@@ -538,6 +543,8 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
|
|
|
538
543
|
command?: string;
|
|
539
544
|
/** Other suite names that, when changed, invalidate this suite's attestation */
|
|
540
545
|
invalidates?: string[];
|
|
546
|
+
/** Array of suite names this suite depends on */
|
|
547
|
+
depends_on?: string[];
|
|
541
548
|
}
|
|
542
549
|
|
|
543
550
|
/**
|
|
@@ -596,7 +603,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
|
|
|
596
603
|
export declare type VerificationStatus = 'EXPIRED' | 'FINGERPRINT_CHANGED' | 'INVALIDATED_BY_PARENT' | 'NEEDS_ATTESTATION' | 'SIGNATURE_INVALID' | 'VALID';
|
|
597
604
|
|
|
598
605
|
/**
|
|
599
|
-
* Verify a signature using
|
|
606
|
+
* Verify a signature using an RSA public key with SHA-256.
|
|
607
|
+
*
|
|
608
|
+
* Uses `openssl dgst -sha256 -verify` which is universally supported across
|
|
609
|
+
* all OpenSSL and LibreSSL versions.
|
|
610
|
+
*
|
|
600
611
|
* @param options - Verification options
|
|
601
612
|
* @returns true if signature is valid
|
|
602
613
|
* @throws Error if verification fails (not just invalid signature)
|
package/dist/core-beta.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Supported signature algorithms.
|
|
5
|
-
* @public
|
|
6
|
-
*/
|
|
7
|
-
export declare type Algorithm = 'ed25519' | 'rsa';
|
|
8
|
-
|
|
9
3
|
/**
|
|
10
4
|
* A single attestation entry.
|
|
11
5
|
* @public
|
|
@@ -49,6 +43,8 @@ export declare interface AttestItConfig {
|
|
|
49
43
|
settings: AttestItSettings;
|
|
50
44
|
/** Named test suites with their configurations */
|
|
51
45
|
suites: Record<string, SuiteConfig>;
|
|
46
|
+
/** Named groups of suites */
|
|
47
|
+
groups?: Record<string, string[]>;
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
/**
|
|
@@ -64,8 +60,6 @@ export declare interface AttestItSettings {
|
|
|
64
60
|
attestationsPath: string;
|
|
65
61
|
/** Default command to execute for attestation (can be overridden per suite) */
|
|
66
62
|
defaultCommand?: string;
|
|
67
|
-
/** Cryptographic algorithm to use for signatures */
|
|
68
|
-
algorithm: 'ed25519' | 'rsa';
|
|
69
63
|
}
|
|
70
64
|
|
|
71
65
|
/**
|
|
@@ -142,27 +136,26 @@ export declare class ConfigNotFoundError extends Error {
|
|
|
142
136
|
* Zod schema for the full configuration file.
|
|
143
137
|
*/
|
|
144
138
|
declare const configSchema: z.ZodObject<{
|
|
139
|
+
groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
|
|
145
140
|
settings: z.ZodDefault<z.ZodObject<{
|
|
146
|
-
algorithm: z.ZodDefault<z.ZodEnum<["ed25519", "rsa"]>>;
|
|
147
141
|
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
148
142
|
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
149
143
|
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
150
144
|
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
151
|
-
}, "
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
publicKeyPath?: string | undefined;
|
|
163
|
-
}>>;
|
|
145
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
146
|
+
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
147
|
+
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
148
|
+
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
149
|
+
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
150
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
151
|
+
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
152
|
+
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
153
|
+
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
154
|
+
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
155
|
+
}, z.ZodTypeAny, "passthrough">>>;
|
|
164
156
|
suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
165
157
|
command: z.ZodOptional<z.ZodString>;
|
|
158
|
+
depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
166
159
|
description: z.ZodOptional<z.ZodString>;
|
|
167
160
|
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
168
161
|
ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
@@ -170,6 +163,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
170
163
|
packages: z.ZodArray<z.ZodString, "many">;
|
|
171
164
|
}, "strict", z.ZodTypeAny, {
|
|
172
165
|
command?: string | undefined;
|
|
166
|
+
depends_on?: string[] | undefined;
|
|
173
167
|
description?: string | undefined;
|
|
174
168
|
files?: string[] | undefined;
|
|
175
169
|
ignore?: string[] | undefined;
|
|
@@ -177,6 +171,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
177
171
|
packages: string[];
|
|
178
172
|
}, {
|
|
179
173
|
command?: string | undefined;
|
|
174
|
+
depends_on?: string[] | undefined;
|
|
180
175
|
description?: string | undefined;
|
|
181
176
|
files?: string[] | undefined;
|
|
182
177
|
ignore?: string[] | undefined;
|
|
@@ -184,6 +179,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
184
179
|
packages: string[];
|
|
185
180
|
}>>, Record<string, {
|
|
186
181
|
command?: string | undefined;
|
|
182
|
+
depends_on?: string[] | undefined;
|
|
187
183
|
description?: string | undefined;
|
|
188
184
|
files?: string[] | undefined;
|
|
189
185
|
ignore?: string[] | undefined;
|
|
@@ -191,6 +187,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
191
187
|
packages: string[];
|
|
192
188
|
}>, Record<string, {
|
|
193
189
|
command?: string | undefined;
|
|
190
|
+
depends_on?: string[] | undefined;
|
|
194
191
|
description?: string | undefined;
|
|
195
192
|
files?: string[] | undefined;
|
|
196
193
|
ignore?: string[] | undefined;
|
|
@@ -199,15 +196,16 @@ declare const configSchema: z.ZodObject<{
|
|
|
199
196
|
}>>;
|
|
200
197
|
version: z.ZodLiteral<1>;
|
|
201
198
|
}, "strict", z.ZodTypeAny, {
|
|
199
|
+
groups?: Record<string, string[]> | undefined;
|
|
202
200
|
settings: {
|
|
203
|
-
algorithm: "ed25519" | "rsa";
|
|
204
201
|
attestationsPath: string;
|
|
205
202
|
defaultCommand?: string | undefined;
|
|
206
203
|
maxAgeDays: number;
|
|
207
204
|
publicKeyPath: string;
|
|
208
|
-
};
|
|
205
|
+
} & { [k: string]: unknown };
|
|
209
206
|
suites: Record<string, {
|
|
210
207
|
command?: string | undefined;
|
|
208
|
+
depends_on?: string[] | undefined;
|
|
211
209
|
description?: string | undefined;
|
|
212
210
|
files?: string[] | undefined;
|
|
213
211
|
ignore?: string[] | undefined;
|
|
@@ -216,15 +214,16 @@ declare const configSchema: z.ZodObject<{
|
|
|
216
214
|
}>;
|
|
217
215
|
version: 1;
|
|
218
216
|
}, {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
attestationsPath
|
|
222
|
-
defaultCommand
|
|
223
|
-
maxAgeDays
|
|
224
|
-
publicKeyPath
|
|
225
|
-
}
|
|
217
|
+
groups?: Record<string, string[]> | undefined;
|
|
218
|
+
settings?: undefined | z.objectInputType<{
|
|
219
|
+
attestationsPath: z.ZodDefault<z.ZodString>;
|
|
220
|
+
defaultCommand: z.ZodOptional<z.ZodString>;
|
|
221
|
+
maxAgeDays: z.ZodDefault<z.ZodNumber>;
|
|
222
|
+
publicKeyPath: z.ZodDefault<z.ZodString>;
|
|
223
|
+
}, z.ZodTypeAny, "passthrough">;
|
|
226
224
|
suites: Record<string, {
|
|
227
225
|
command?: string | undefined;
|
|
226
|
+
depends_on?: string[] | undefined;
|
|
228
227
|
description?: string | undefined;
|
|
229
228
|
files?: string[] | undefined;
|
|
230
229
|
ignore?: string[] | undefined;
|
|
@@ -326,7 +325,11 @@ export declare interface FingerprintResult {
|
|
|
326
325
|
}
|
|
327
326
|
|
|
328
327
|
/**
|
|
329
|
-
* Generate a new keypair using OpenSSL.
|
|
328
|
+
* Generate a new RSA-2048 keypair using OpenSSL.
|
|
329
|
+
*
|
|
330
|
+
* RSA-2048 with SHA-256 is used because it's universally supported across
|
|
331
|
+
* all OpenSSL and LibreSSL versions, including older macOS systems.
|
|
332
|
+
*
|
|
330
333
|
* @param options - Generation options
|
|
331
334
|
* @returns Paths to generated keys
|
|
332
335
|
* @throws Error if OpenSSL fails or keys exist without force
|
|
@@ -353,8 +356,6 @@ export declare function getDefaultPublicKeyPath(): string;
|
|
|
353
356
|
* @public
|
|
354
357
|
*/
|
|
355
358
|
export declare interface KeygenOptions {
|
|
356
|
-
/** Algorithm to use (default: ed25519) */
|
|
357
|
-
algorithm?: Algorithm;
|
|
358
359
|
/** Path for private key (default: OS-specific config dir) */
|
|
359
360
|
privatePath?: string;
|
|
360
361
|
/** Path for public key (default: repo root) */
|
|
@@ -490,7 +491,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
|
|
|
490
491
|
export declare function setKeyPermissions(keyPath: string): Promise<void>;
|
|
491
492
|
|
|
492
493
|
/**
|
|
493
|
-
* Sign data using
|
|
494
|
+
* Sign data using an RSA private key with SHA-256.
|
|
495
|
+
*
|
|
496
|
+
* Uses `openssl dgst -sha256 -sign` which is universally supported across
|
|
497
|
+
* all OpenSSL and LibreSSL versions.
|
|
498
|
+
*
|
|
494
499
|
* @param options - Signing options
|
|
495
500
|
* @returns Base64-encoded signature
|
|
496
501
|
* @throws Error if signing fails
|
|
@@ -538,6 +543,8 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
|
|
|
538
543
|
command?: string;
|
|
539
544
|
/** Other suite names that, when changed, invalidate this suite's attestation */
|
|
540
545
|
invalidates?: string[];
|
|
546
|
+
/** Array of suite names this suite depends on */
|
|
547
|
+
depends_on?: string[];
|
|
541
548
|
}
|
|
542
549
|
|
|
543
550
|
/**
|
|
@@ -596,7 +603,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
|
|
|
596
603
|
export declare type VerificationStatus = 'EXPIRED' | 'FINGERPRINT_CHANGED' | 'INVALIDATED_BY_PARENT' | 'NEEDS_ATTESTATION' | 'SIGNATURE_INVALID' | 'VALID';
|
|
597
604
|
|
|
598
605
|
/**
|
|
599
|
-
* Verify a signature using
|
|
606
|
+
* Verify a signature using an RSA public key with SHA-256.
|
|
607
|
+
*
|
|
608
|
+
* Uses `openssl dgst -sha256 -verify` which is universally supported across
|
|
609
|
+
* all OpenSSL and LibreSSL versions.
|
|
610
|
+
*
|
|
600
611
|
* @param options - Verification options
|
|
601
612
|
* @returns true if signature is valid
|
|
602
613
|
* @throws Error if verification fails (not just invalid signature)
|