@attest-it/core 0.7.0 → 0.9.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.
@@ -27,6 +27,9 @@ async function runOpenSSL(args, stdin) {
27
27
  stderr
28
28
  });
29
29
  });
30
+ if (stdin) {
31
+ child.stdin.write(stdin);
32
+ }
30
33
  child.stdin.end();
31
34
  });
32
35
  }
@@ -100,7 +103,8 @@ async function generateKeyPair(options = {}) {
100
103
  const {
101
104
  privatePath = getDefaultPrivateKeyPath(),
102
105
  publicPath = getDefaultPublicKeyPath(),
103
- force = false
106
+ force = false,
107
+ passphrase
104
108
  } = options;
105
109
  const privateExists = await fileExists(privatePath);
106
110
  const publicExists = await fileExists(publicPath);
@@ -124,12 +128,25 @@ async function generateKeyPair(options = {}) {
124
128
  "-out",
125
129
  privatePath
126
130
  ];
127
- const genResult = await runOpenSSL(genArgs);
131
+ if (passphrase) {
132
+ genArgs.push("-aes256", "-pass", "stdin");
133
+ }
134
+ const genResult = await runOpenSSL(
135
+ genArgs,
136
+ passphrase ? Buffer.from(passphrase + "\n") : void 0
137
+ );
128
138
  if (genResult.exitCode !== 0) {
129
139
  throw new Error(`Failed to generate private key: ${genResult.stderr}`);
130
140
  }
131
141
  await setKeyPermissions(privatePath);
132
- const pubResult = await runOpenSSL(["pkey", "-in", privatePath, "-pubout", "-out", publicPath]);
142
+ const pubArgs = ["pkey", "-in", privatePath, "-pubout", "-out", publicPath];
143
+ if (passphrase) {
144
+ pubArgs.push("-passin", "stdin");
145
+ }
146
+ const pubResult = await runOpenSSL(
147
+ pubArgs,
148
+ passphrase ? Buffer.from(passphrase + "\n") : void 0
149
+ );
133
150
  if (pubResult.exitCode !== 0) {
134
151
  throw new Error(`Failed to extract public key: ${pubResult.stderr}`);
135
152
  }
@@ -144,7 +161,7 @@ async function generateKeyPair(options = {}) {
144
161
  }
145
162
  async function sign(options) {
146
163
  await ensureOpenSSLAvailable();
147
- const { privateKeyPath, keyProvider, keyRef, data } = options;
164
+ const { privateKeyPath, keyProvider, keyRef, data, passphrase } = options;
148
165
  let effectiveKeyPath;
149
166
  let cleanup;
150
167
  if (keyProvider && keyRef) {
@@ -169,9 +186,22 @@ async function sign(options) {
169
186
  const sigFile = path.join(tmpDir, "sig.bin");
170
187
  try {
171
188
  await fs.writeFile(dataFile, processBuffer);
172
- const signArgs = ["dgst", "-sha256", "-sign", effectiveKeyPath, "-out", sigFile, dataFile];
173
- const result = await runOpenSSL(signArgs);
189
+ const signArgs = ["dgst", "-sha256"];
190
+ if (passphrase) {
191
+ signArgs.push("-passin", "stdin");
192
+ }
193
+ signArgs.push("-sign", effectiveKeyPath, "-out", sigFile, dataFile);
194
+ const result = await runOpenSSL(
195
+ signArgs,
196
+ passphrase ? Buffer.from(passphrase + "\n") : void 0
197
+ );
174
198
  if (result.exitCode !== 0) {
199
+ const stderr = result.stderr.toLowerCase();
200
+ if (stderr.includes("bad decrypt") || stderr.includes("bad password") || stderr.includes("unable to load key") || stderr.includes("wrong password")) {
201
+ throw new Error(
202
+ "Failed to decrypt private key. Please check that the passphrase is correct."
203
+ );
204
+ }
175
205
  throw new Error(`Failed to sign data: ${result.stderr}`);
176
206
  }
177
207
  const sigBuffer = await fs.readFile(sigFile);
@@ -230,5 +260,5 @@ async function setKeyPermissions(keyPath) {
230
260
  }
231
261
 
232
262
  export { checkOpenSSL, generateKeyPair, getDefaultPrivateKeyPath, getDefaultPublicKeyPath, getDefaultYubiKeyEncryptedKeyPath, setKeyPermissions, sign, verify };
233
- //# sourceMappingURL=chunk-T3NLSO5B.js.map
234
- //# sourceMappingURL=chunk-T3NLSO5B.js.map
263
+ //# sourceMappingURL=chunk-FGYLU2HL.js.map
264
+ //# sourceMappingURL=chunk-FGYLU2HL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/crypto.ts"],"names":[],"mappings":";;;;;;AA4FA,eAAe,UAAA,CAAW,MAAgB,KAAA,EAAsC;AAC9E,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,SAAA,EAAW,IAAA,EAAM;AAAA,MACnC,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM;AAAA,KAC/B,CAAA;AAED,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,IAAI,MAAA,GAAS,EAAA;AAEb,IAAA,KAAA,CAAM,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAkB;AACzC,MAAA,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,IACzB,CAAC,CAAA;AAED,IAAA,KAAA,CAAM,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAkB;AACzC,MAAA,MAAA,IAAU,MAAM,QAAA,EAAS;AAAA,IAC3B,CAAC,CAAA;AAED,IAAA,KAAA,CAAM,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AACzB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,OAAO,EAAE,CAAC,CAAA;AAAA,IAC7D,CAAC,CAAA;AAED,IAAA,KAAA,CAAM,EAAA,CAAG,OAAA,EAAS,CAAC,IAAA,KAAS;AAC1B,MAAA,OAAA,CAAQ;AAAA,QACN,UAAU,IAAA,IAAQ,CAAA;AAAA,QAClB,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,YAAY,CAAA;AAAA,QAClC;AAAA,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,CAAM,KAAA,CAAM,MAAM,KAAK,CAAA;AAAA,IACzB;AACA,IAAA,KAAA,CAAM,MAAM,GAAA,EAAI;AAAA,EAClB,CAAC,CAAA;AACH;AAQA,eAAsB,YAAA,GAAgC;AACpD,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,CAAC,SAAS,CAAC,CAAA;AAE3C,EAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,QAAA,EAAS,CAAE,IAAA,EAAK;AACvC;AAMA,IAAI,cAAA,GAAiB,KAAA;AAOrB,eAAe,sBAAA,GAAwC;AACrD,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,YAAA,EAAa;AACnB,IAAA,cAAA,GAAiB,IAAA;AAAA,EACnB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAIF;AAAA,EACF;AACF;AAQO,SAAS,wBAAA,GAAmC;AACjD,EAAA,MAAM,UAAa,EAAA,CAAA,OAAA,EAAQ;AAE3B,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,IAAA,MAAM,UAAU,OAAA,CAAQ,GAAA,CAAI,WAAgB,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,WAAW,SAAS,CAAA;AAC9E,IAAA,OAAY,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,WAAA,EAAa,aAAa,CAAA;AAAA,EACtD;AAEA,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,SAAA,EAAW,WAAA,EAAa,aAAa,CAAA;AACjE;AAMO,SAAS,uBAAA,GAAkC;AAChD,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAI,EAAG,sBAAsB,CAAA;AACxD;AAQO,SAAS,iCAAA,GAA4C;AAC1D,EAAA,MAAM,UAAa,EAAA,CAAA,OAAA,EAAQ;AAE3B,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,IAAA,MAAM,UAAU,OAAA,CAAQ,GAAA,CAAI,WAAgB,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,WAAW,SAAS,CAAA;AAC9E,IAAA,OAAY,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,WAAA,EAAa,qBAAqB,CAAA;AAAA,EAC9D;AAEA,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,SAAA,EAAW,WAAA,EAAa,qBAAqB,CAAA;AACzE;AAOA,eAAe,UAAU,OAAA,EAAgC;AACvD,EAAA,IAAI;AACF,IAAA,MAAS,EAAA,CAAA,KAAA,CAAM,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,EAC7C,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI,eAAe,KAAA,IAAS,MAAA,IAAU,GAAA,IAAO,GAAA,CAAI,SAAS,QAAA,EAAU;AAClE,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AACF;AAQA,eAAe,WAAW,QAAA,EAAoC;AAC5D,EAAA,IAAI;AACF,IAAA,MAAS,UAAO,QAAQ,CAAA;AACxB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAOA,eAAe,gBAAgB,KAAA,EAAgC;AAC7D,EAAA,KAAA,MAAW,YAAY,KAAA,EAAO;AAC5B,IAAA,IAAI;AACF,MAAA,MAAS,UAAO,QAAQ,CAAA;AAAA,IAC1B,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAaA,eAAsB,eAAA,CAAgB,OAAA,GAAyB,EAAC,EAAsB;AAEpF,EAAA,MAAM,sBAAA,EAAuB;AAE7B,EAAA,MAAM;AAAA,IACJ,cAAc,wBAAA,EAAyB;AAAA,IACvC,aAAa,uBAAA,EAAwB;AAAA,IACrC,KAAA,GAAQ,KAAA;AAAA,IACR;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,MAAM,aAAA,GAAgB,MAAM,UAAA,CAAW,WAAW,CAAA;AAClD,EAAA,MAAM,YAAA,GAAe,MAAM,UAAA,CAAW,UAAU,CAAA;AAEhD,EAAA,IAAA,CAAK,aAAA,IAAiB,YAAA,KAAiB,CAAC,KAAA,EAAO;AAC7C,IAAA,MAAM,QAAA,GAAW,CAAC,aAAA,GAAgB,WAAA,GAAc,MAAM,YAAA,GAAe,UAAA,GAAa,IAAI,CAAA,CAAE,MAAA;AAAA,MACtF;AAAA,KACF;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,yBAAA,EAA4B,QAAA,CAAS,IAAA,CAAK,IAAI,CAAC,CAAA,+BAAA;AAAA,KACjD;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,CAAe,IAAA,CAAA,OAAA,CAAQ,WAAW,CAAC,CAAA;AACzC,EAAA,MAAM,SAAA,CAAe,IAAA,CAAA,OAAA,CAAQ,UAAU,CAAC,CAAA;AAExC,EAAA,IAAI;AAEF,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,SAAA;AAAA,MACA,YAAA;AAAA,MACA,KAAA;AAAA,MACA,UAAA;AAAA,MACA,sBAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF;AAGA,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,SAAA,EAAW,OAAA,EAAS,OAAO,CAAA;AAAA,IAC1C;AAKA,IAAA,MAAM,YAAY,MAAM,UAAA;AAAA,MACtB,OAAA;AAAA,MACA,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,UAAA,GAAa,IAAI,CAAA,GAAI,KAAA;AAAA,KAChD;AACA,IAAA,IAAI,SAAA,CAAU,aAAa,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,SAAA,CAAU,MAAM,CAAA,CAAE,CAAA;AAAA,IACvE;AAGA,IAAA,MAAM,kBAAkB,WAAW,CAAA;AAGnC,IAAA,MAAM,UAAU,CAAC,MAAA,EAAQ,OAAO,WAAA,EAAa,SAAA,EAAW,QAAQ,UAAU,CAAA;AAC1E,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,WAAW,OAAO,CAAA;AAAA,IACjC;AACA,IAAA,MAAM,YAAY,MAAM,UAAA;AAAA,MACtB,OAAA;AAAA,MACA,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,UAAA,GAAa,IAAI,CAAA,GAAI,KAAA;AAAA,KAChD;AAEA,IAAA,IAAI,SAAA,CAAU,aAAa,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,SAAA,CAAU,MAAM,CAAA,CAAE,CAAA;AAAA,IACrE;AAEA,IAAA,OAAO;AAAA,MACL,WAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,SAAS,GAAA,EAAK;AAEZ,IAAA,MAAM,YAAA,CAAa,aAAa,UAAU,CAAA;AAC1C,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAaA,eAAsB,KAAK,OAAA,EAAuC;AAEhE,EAAA,MAAM,sBAAA,EAAuB;AAE7B,EAAA,MAAM,EAAE,cAAA,EAAgB,WAAA,EAAa,MAAA,EAAQ,IAAA,EAAM,YAAW,GAAI,OAAA;AAGlE,EAAA,IAAI,gBAAA;AACJ,EAAA,IAAI,OAAA;AAEJ,EAAA,IAAI,eAAe,MAAA,EAAQ;AAEzB,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,aAAA,CAAc,MAAM,CAAA;AACrD,IAAA,gBAAA,GAAmB,MAAA,CAAO,OAAA;AAC1B,IAAA,OAAA,GAAU,MAAA,CAAO,OAAA;AAAA,EACnB,WAAW,cAAA,EAAgB;AAEzB,IAAA,gBAAA,GAAmB,cAAA;AAAA,EACrB,CAAA,MAAO;AACL,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI;AAEF,IAAA,IAAI,CAAE,MAAM,UAAA,CAAW,gBAAgB,CAAA,EAAI;AACzC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,gBAAgB,CAAA,CAAE,CAAA;AAAA,IAC9D;AAGA,IAAA,MAAM,UAAA,GAAa,OAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA,GAAI,IAAA;AAI1E,IAAA,MAAM,aAAA,GAAgB,WAAW,MAAA,KAAW,CAAA,GAAI,OAAO,IAAA,CAAK,CAAC,CAAI,CAAC,CAAA,GAAI,UAAA;AAItE,IAAA,MAAM,SAAS,MAAS,EAAA,CAAA,OAAA,CAAa,UAAQ,EAAA,CAAA,MAAA,EAAO,EAAG,YAAY,CAAC,CAAA;AACpE,IAAA,MAAM,QAAA,GAAgB,IAAA,CAAA,IAAA,CAAK,MAAA,EAAQ,UAAU,CAAA;AAC7C,IAAA,MAAM,OAAA,GAAe,IAAA,CAAA,IAAA,CAAK,MAAA,EAAQ,SAAS,CAAA;AAE3C,IAAA,IAAI;AAEF,MAAA,MAAS,EAAA,CAAA,SAAA,CAAU,UAAU,aAAa,CAAA;AAI1C,MAAA,MAAM,QAAA,GAAW,CAAC,MAAA,EAAQ,SAAS,CAAA;AAGnC,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,QAAA,CAAS,IAAA,CAAK,WAAW,OAAO,CAAA;AAAA,MAClC;AAEA,MAAA,QAAA,CAAS,IAAA,CAAK,OAAA,EAAS,gBAAA,EAAkB,MAAA,EAAQ,SAAS,QAAQ,CAAA;AAGlE,MAAA,MAAM,SAAS,MAAM,UAAA;AAAA,QACnB,QAAA;AAAA,QACA,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,UAAA,GAAa,IAAI,CAAA,GAAI,KAAA;AAAA,OAChD;AAEA,MAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AAEzB,QAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,WAAA,EAAY;AACzC,QAAA,IACE,MAAA,CAAO,QAAA,CAAS,aAAa,CAAA,IAC7B,OAAO,QAAA,CAAS,cAAc,CAAA,IAC9B,MAAA,CAAO,SAAS,oBAAoB,CAAA,IACpC,MAAA,CAAO,QAAA,CAAS,gBAAgB,CAAA,EAChC;AACA,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA,QACF;AACA,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AAAA,MACzD;AAGA,MAAA,MAAM,SAAA,GAAY,MAAS,EAAA,CAAA,QAAA,CAAS,OAAO,CAAA;AAC3C,MAAA,OAAO,SAAA,CAAU,SAAS,QAAQ,CAAA;AAAA,IACpC,CAAA,SAAE;AAEA,MAAA,IAAI;AACF,QAAA,MAAS,MAAG,MAAA,EAAQ,EAAE,WAAW,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AAAA,MACtD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA,SAAE;AAEA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,OAAA,EAAQ;AAAA,IAChB;AAAA,EACF;AACF;AAaA,eAAsB,OAAO,OAAA,EAA0C;AAErE,EAAA,MAAM,sBAAA,EAAuB;AAE7B,EAAA,MAAM,EAAE,aAAA,EAAe,IAAA,EAAM,SAAA,EAAU,GAAI,OAAA;AAG3C,EAAA,IAAI,CAAE,MAAM,UAAA,CAAW,aAAa,CAAA,EAAI;AACtC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,aAAa,CAAA,CAAE,CAAA;AAAA,EAC1D;AAGA,EAAA,MAAM,UAAA,GAAa,OAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA,GAAI,IAAA;AAI1E,EAAA,MAAM,aAAA,GAAgB,WAAW,MAAA,KAAW,CAAA,GAAI,OAAO,IAAA,CAAK,CAAC,CAAI,CAAC,CAAA,GAAI,UAAA;AAGtE,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,QAAQ,CAAA;AAIjD,EAAA,MAAM,SAAS,MAAS,EAAA,CAAA,OAAA,CAAa,UAAQ,EAAA,CAAA,MAAA,EAAO,EAAG,YAAY,CAAC,CAAA;AACpE,EAAA,MAAM,QAAA,GAAgB,IAAA,CAAA,IAAA,CAAK,MAAA,EAAQ,UAAU,CAAA;AAC7C,EAAA,MAAM,OAAA,GAAe,IAAA,CAAA,IAAA,CAAK,MAAA,EAAQ,SAAS,CAAA;AAE3C,EAAA,IAAI;AAEF,IAAA,MAAS,EAAA,CAAA,SAAA,CAAU,UAAU,aAAa,CAAA;AAC1C,IAAA,MAAS,EAAA,CAAA,SAAA,CAAU,SAAS,SAAS,CAAA;AAGrC,IAAA,MAAM,UAAA,GAAa;AAAA,MACjB,MAAA;AAAA,MACA,SAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,UAAU,CAAA;AAI1C,IAAA,OAAO,MAAA,CAAO,aAAa,CAAA,IAAK,MAAA,CAAO,OAAO,QAAA,EAAS,CAAE,SAAS,aAAa,CAAA;AAAA,EACjF,CAAA,SAAE;AAEA,IAAA,IAAI;AACF,MAAA,MAAS,MAAG,MAAA,EAAQ,EAAE,WAAW,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AAAA,IACtD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAOA,eAAsB,kBAAkB,OAAA,EAAgC;AAGtE,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAGhC,IAAA,MAAS,EAAA,CAAA,KAAA,CAAM,SAAS,GAAK,CAAA;AAAA,EAC/B,CAAA,MAAO;AACL,IAAA,MAAS,EAAA,CAAA,KAAA,CAAM,SAAS,GAAK,CAAA;AAAA,EAC/B;AACF","file":"chunk-FGYLU2HL.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 /** Passphrase to encrypt the private key with AES-256 (optional) */\n passphrase?: string\n}\n\n/**\n * Options for signing data.\n * @public\n */\nexport interface SignOptions {\n /** Path to the private key file (legacy) */\n privateKeyPath?: string\n /** Key provider to use for retrieving the private key */\n keyProvider?: import('./key-provider/types.js').KeyProvider\n /** Key reference for the provider */\n keyRef?: string\n /** Data to sign (string or Buffer) */\n data: string | Buffer\n /** Passphrase for encrypted private keys (optional) */\n passphrase?: string\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 * Get the default YubiKey encrypted key path based on OS.\n * - macOS/Linux: ~/.config/attest-it/yubikey-private.enc\n * - Windows: %APPDATA%\\attest-it\\yubikey-private.enc\n * @public\n */\nexport function getDefaultYubiKeyEncryptedKeyPath(): 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', 'yubikey-private.enc')\n }\n\n return path.join(homeDir, '.config', 'attest-it', 'yubikey-private.enc')\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 passphrase,\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 // Add encryption if passphrase is provided\n if (passphrase) {\n genArgs.push('-aes256', '-pass', 'stdin')\n }\n\n // Note: OpenSSL reads passphrase from stdin. While OpenSSL accepts passphrases\n // with or without trailing newlines, we consistently use newline terminators\n // across all operations for predictable behavior.\n const genResult = await runOpenSSL(\n genArgs,\n passphrase ? Buffer.from(passphrase + '\\n') : undefined,\n )\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 (need passphrase if key is encrypted)\n const pubArgs = ['pkey', '-in', privatePath, '-pubout', '-out', publicPath]\n if (passphrase) {\n pubArgs.push('-passin', 'stdin')\n }\n const pubResult = await runOpenSSL(\n pubArgs,\n passphrase ? Buffer.from(passphrase + '\\n') : undefined,\n )\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, keyProvider, keyRef, data, passphrase } = options\n\n // Determine which key path to use\n let effectiveKeyPath: string\n let cleanup: (() => Promise<void>) | undefined\n\n if (keyProvider && keyRef) {\n // Use key provider to retrieve the key\n const result = await keyProvider.getPrivateKey(keyRef)\n effectiveKeyPath = result.keyPath\n cleanup = result.cleanup\n } else if (privateKeyPath) {\n // Legacy path: use privateKeyPath directly\n effectiveKeyPath = privateKeyPath\n } else {\n throw new Error(\n 'Either privateKeyPath or both keyProvider and keyRef must be provided for signing',\n )\n }\n\n try {\n // Check if private key exists\n if (!(await fileExists(effectiveKeyPath))) {\n throw new Error(`Private key not found: ${effectiveKeyPath}`)\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 // Note: -passin must come before -sign for encrypted keys\n const signArgs = ['dgst', '-sha256']\n\n // Add passphrase support for encrypted keys\n if (passphrase) {\n signArgs.push('-passin', 'stdin')\n }\n\n signArgs.push('-sign', effectiveKeyPath, '-out', sigFile, dataFile)\n\n // Note: We consistently use newline terminators for passphrases passed via stdin\n const result = await runOpenSSL(\n signArgs,\n passphrase ? Buffer.from(passphrase + '\\n') : undefined,\n )\n\n if (result.exitCode !== 0) {\n // Detect passphrase-related errors and provide a clearer message\n const stderr = result.stderr.toLowerCase()\n if (\n stderr.includes('bad decrypt') ||\n stderr.includes('bad password') ||\n stderr.includes('unable to load key') ||\n stderr.includes('wrong password')\n ) {\n throw new Error(\n 'Failed to decrypt private key. Please check that the passphrase is correct.',\n )\n }\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 } finally {\n // Always call cleanup function if provided\n if (cleanup) {\n await cleanup()\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"]}
@@ -62,6 +62,8 @@ export declare interface AttestItSettings {
62
62
  publicKeyPath: string;
63
63
  /** Path to the attestations file */
64
64
  attestationsPath: string;
65
+ /** Path to the seals file */
66
+ sealsPath: string;
65
67
  /** Default command to execute for attestation (can be overridden per suite) */
66
68
  defaultCommand?: string;
67
69
  /** Key provider configuration for signing attestations */
@@ -226,6 +228,7 @@ declare const configSchema: z.ZodObject<{
226
228
  }>>;
227
229
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
228
230
  publicKeyPath: z.ZodDefault<z.ZodString>;
231
+ sealsPath: z.ZodDefault<z.ZodString>;
229
232
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
230
233
  attestationsPath: z.ZodDefault<z.ZodString>;
231
234
  defaultCommand: z.ZodOptional<z.ZodString>;
@@ -266,6 +269,7 @@ declare const configSchema: z.ZodObject<{
266
269
  }>>;
267
270
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
268
271
  publicKeyPath: z.ZodDefault<z.ZodString>;
272
+ sealsPath: z.ZodDefault<z.ZodString>;
269
273
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
270
274
  attestationsPath: z.ZodDefault<z.ZodString>;
271
275
  defaultCommand: z.ZodOptional<z.ZodString>;
@@ -306,6 +310,7 @@ declare const configSchema: z.ZodObject<{
306
310
  }>>;
307
311
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
308
312
  publicKeyPath: z.ZodDefault<z.ZodString>;
313
+ sealsPath: z.ZodDefault<z.ZodString>;
309
314
  }, z.ZodTypeAny, "passthrough">>>;
310
315
  suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
311
316
  command: z.ZodOptional<z.ZodString>;
@@ -390,16 +395,19 @@ declare const configSchema: z.ZodObject<{
390
395
  github: z.ZodOptional<z.ZodString>;
391
396
  name: z.ZodString;
392
397
  publicKey: z.ZodString;
398
+ publicKeyAlgorithm: z.ZodOptional<z.ZodEnum<["ed25519"]>>;
393
399
  }, "strict", z.ZodTypeAny, {
394
400
  email?: string | undefined;
395
401
  github?: string | undefined;
396
402
  name: string;
397
403
  publicKey: string;
404
+ publicKeyAlgorithm?: "ed25519" | undefined;
398
405
  }, {
399
406
  email?: string | undefined;
400
407
  github?: string | undefined;
401
408
  name: string;
402
409
  publicKey: string;
410
+ publicKeyAlgorithm?: "ed25519" | undefined;
403
411
  }>>>;
404
412
  version: z.ZodLiteral<1>;
405
413
  }, "strict", z.ZodTypeAny, {
@@ -428,6 +436,7 @@ declare const configSchema: z.ZodObject<{
428
436
  } | undefined;
429
437
  maxAgeDays: number;
430
438
  publicKeyPath: string;
439
+ sealsPath: string;
431
440
  } & { [k: string]: unknown };
432
441
  suites: Record<string, {
433
442
  command?: string | undefined;
@@ -446,6 +455,7 @@ declare const configSchema: z.ZodObject<{
446
455
  github?: string | undefined;
447
456
  name: string;
448
457
  publicKey: string;
458
+ publicKeyAlgorithm?: "ed25519" | undefined;
449
459
  }> | undefined;
450
460
  version: 1;
451
461
  }, {
@@ -500,6 +510,7 @@ declare const configSchema: z.ZodObject<{
500
510
  }>>;
501
511
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
502
512
  publicKeyPath: z.ZodDefault<z.ZodString>;
513
+ sealsPath: z.ZodDefault<z.ZodString>;
503
514
  }, z.ZodTypeAny, "passthrough">;
504
515
  suites: Record<string, {
505
516
  command?: string | undefined;
@@ -518,6 +529,7 @@ declare const configSchema: z.ZodObject<{
518
529
  github?: string | undefined;
519
530
  name: string;
520
531
  publicKey: string;
532
+ publicKeyAlgorithm?: "ed25519" | undefined;
521
533
  }> | undefined;
522
534
  version: 1;
523
535
  }>;
@@ -878,9 +890,8 @@ export declare function getPreferencesPath(): string;
878
890
  /**
879
891
  * Get the project public keys directory.
880
892
  *
881
- * This returns .attest-it/public-keys relative to the given project root.
882
- * The project public keys directory is used for CI/GitHub Actions to
883
- * verify attestation seals.
893
+ * @deprecated Public keys are now stored inline in the team section of config.yaml.
894
+ * This function is kept for backward compatibility but should not be used in new code.
884
895
  *
885
896
  * @param projectRoot - The project root directory (defaults to cwd)
886
897
  * @returns Path to the project public keys directory
@@ -901,6 +912,9 @@ export declare function getPublicKeyFromPrivate(privateKeyPem: string): string;
901
912
  /**
902
913
  * Check if a project has attest-it configuration.
903
914
  *
915
+ * @deprecated This function is kept for backward compatibility but is no longer used
916
+ * by the core library. Public keys are now stored inline in config.yaml.
917
+ *
904
918
  * @param projectRoot - The project root directory (defaults to cwd)
905
919
  * @returns True if the project has .attest-it/config.yaml or similar
906
920
  * @public
@@ -946,6 +960,8 @@ export declare interface KeyGenerationResult {
946
960
  publicKeyPath: string;
947
961
  /** Human-readable storage location description */
948
962
  storageDescription: string;
963
+ /** Whether the private key is encrypted with a passphrase */
964
+ encrypted?: boolean;
949
965
  }
950
966
 
951
967
  /**
@@ -959,6 +975,8 @@ export declare interface KeygenOptions {
959
975
  publicPath?: string;
960
976
  /** Overwrite existing keys (default: false) */
961
977
  force?: boolean;
978
+ /** Passphrase to encrypt the private key with AES-256 (optional) */
979
+ passphrase?: string;
962
980
  }
963
981
 
964
982
  /**
@@ -970,6 +988,8 @@ export declare interface KeygenProviderOptions {
970
988
  publicKeyPath: string;
971
989
  /** Overwrite existing keys */
972
990
  force?: boolean;
991
+ /** Passphrase to encrypt the private key (filesystem provider only) */
992
+ passphrase?: string;
973
993
  }
974
994
 
975
995
  /**
@@ -1271,7 +1291,7 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1271
1291
  * The merge strategy prioritizes security-critical fields from the policy
1272
1292
  * configuration while combining operational fields from both sources:
1273
1293
  *
1274
- * - **Policy settings** (maxAgeDays, publicKeyPath, attestationsPath) are used as-is
1294
+ * - **Policy settings** (maxAgeDays, publicKeyPath, attestationsPath, sealsPath) are used as-is
1275
1295
  * - **Operational settings** (defaultCommand, keyProvider) are added from operational config
1276
1296
  * - **Team and gates** come exclusively from policy config
1277
1297
  * - **Suites and groups** come exclusively from operational config
@@ -1708,30 +1728,36 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1708
1728
  attestationsPath: z.ZodDefault<z.ZodString>;
1709
1729
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
1710
1730
  publicKeyPath: z.ZodDefault<z.ZodString>;
1731
+ sealsPath: z.ZodDefault<z.ZodString>;
1711
1732
  }, "strict", z.ZodTypeAny, {
1712
1733
  attestationsPath: string;
1713
1734
  maxAgeDays: number;
1714
1735
  publicKeyPath: string;
1736
+ sealsPath: string;
1715
1737
  }, {
1716
1738
  attestationsPath?: string | undefined;
1717
1739
  maxAgeDays?: number | undefined;
1718
1740
  publicKeyPath?: string | undefined;
1741
+ sealsPath?: string | undefined;
1719
1742
  }>>;
1720
1743
  team: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
1721
1744
  email: z.ZodOptional<z.ZodString>;
1722
1745
  github: z.ZodOptional<z.ZodString>;
1723
1746
  name: z.ZodString;
1724
1747
  publicKey: z.ZodString;
1748
+ publicKeyAlgorithm: z.ZodOptional<z.ZodLiteral<"ed25519">>;
1725
1749
  }, "strict", z.ZodTypeAny, {
1726
1750
  email?: string | undefined;
1727
1751
  github?: string | undefined;
1728
1752
  name: string;
1729
1753
  publicKey: string;
1754
+ publicKeyAlgorithm?: "ed25519" | undefined;
1730
1755
  }, {
1731
1756
  email?: string | undefined;
1732
1757
  github?: string | undefined;
1733
1758
  name: string;
1734
1759
  publicKey: string;
1760
+ publicKeyAlgorithm?: "ed25519" | undefined;
1735
1761
  }>>>;
1736
1762
  version: z.ZodLiteral<1>;
1737
1763
  }, "strict", z.ZodTypeAny, {
@@ -1749,12 +1775,14 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1749
1775
  attestationsPath: string;
1750
1776
  maxAgeDays: number;
1751
1777
  publicKeyPath: string;
1778
+ sealsPath: string;
1752
1779
  };
1753
1780
  team?: Record<string, {
1754
1781
  email?: string | undefined;
1755
1782
  github?: string | undefined;
1756
1783
  name: string;
1757
1784
  publicKey: string;
1785
+ publicKeyAlgorithm?: "ed25519" | undefined;
1758
1786
  }> | undefined;
1759
1787
  version: 1;
1760
1788
  }, {
@@ -1772,12 +1800,14 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1772
1800
  attestationsPath?: string | undefined;
1773
1801
  maxAgeDays?: number | undefined;
1774
1802
  publicKeyPath?: string | undefined;
1803
+ sealsPath?: string | undefined;
1775
1804
  } | undefined;
1776
1805
  team?: Record<string, {
1777
1806
  email?: string | undefined;
1778
1807
  github?: string | undefined;
1779
1808
  name: string;
1780
1809
  publicKey: string;
1810
+ publicKeyAlgorithm?: "ed25519" | undefined;
1781
1811
  }> | undefined;
1782
1812
  version: 1;
1783
1813
  }>;
@@ -1855,21 +1885,23 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1855
1885
  * Read seals from the seals.json file (async).
1856
1886
  *
1857
1887
  * @param dir - Directory containing .attest-it/seals.json
1888
+ * @param sealsPathOverride - Optional explicit path to seals file (from config.settings.sealsPath)
1858
1889
  * @returns The seals file contents, or an empty seals file if the file doesn't exist
1859
1890
  * @throws Error if file exists but cannot be read or parsed
1860
1891
  * @public
1861
1892
  */
1862
- export declare function readSeals(dir: string): Promise<SealsFile>;
1893
+ export declare function readSeals(dir: string, sealsPathOverride?: string): Promise<SealsFile>;
1863
1894
 
1864
1895
  /**
1865
1896
  * Read seals from the seals.json file (sync).
1866
1897
  *
1867
1898
  * @param dir - Directory containing .attest-it/seals.json
1899
+ * @param sealsPathOverride - Optional explicit path to seals file (from config.settings.sealsPath)
1868
1900
  * @returns The seals file contents, or an empty seals file if the file doesn't exist
1869
1901
  * @throws Error if file exists but cannot be read or parsed
1870
1902
  * @public
1871
1903
  */
1872
- export declare function readSealsSync(dir: string): SealsFile;
1904
+ export declare function readSealsSync(dir: string, sealsPathOverride?: string): SealsFile;
1873
1905
 
1874
1906
  /**
1875
1907
  * Options for reading and verifying signed attestations.
@@ -1936,16 +1968,17 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1936
1968
  export declare function savePreferences(preferences: UserPreferences): Promise<void>;
1937
1969
 
1938
1970
  /**
1939
- * Save a public key to the user's home directory and optionally to the project directory.
1971
+ * Save a public key to the user's home directory.
1940
1972
  *
1941
1973
  * This saves the public key as a base64-encoded string (matching the format in config.yaml)
1942
- * to:
1943
- * 1. ~/.attest-it/public-keys/<slug>.pem (always)
1944
- * 2. ./.attest-it/public-keys/<slug>.pem (if project has attest-it config)
1974
+ * to ~/.attest-it/public-keys/<slug>.pem for backup purposes.
1975
+ *
1976
+ * Public keys are now stored inline in the team section of config.yaml and no longer
1977
+ * written to the project directory.
1945
1978
  *
1946
1979
  * @param slug - The identity slug (used for the filename)
1947
1980
  * @param publicKey - The base64-encoded public key
1948
- * @param projectRoot - The project root directory (defaults to cwd)
1981
+ * @param projectRoot - The project root directory (deprecated, kept for backward compatibility)
1949
1982
  * @returns Paths where the key was saved
1950
1983
  * @public
1951
1984
  */
@@ -1963,16 +1996,17 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
1963
1996
  }
1964
1997
 
1965
1998
  /**
1966
- * Save a public key to the user's home directory and optionally to the project directory (sync).
1999
+ * Save a public key to the user's home directory (sync).
1967
2000
  *
1968
2001
  * This saves the public key as a base64-encoded string (matching the format in config.yaml)
1969
- * to:
1970
- * 1. ~/.attest-it/public-keys/<slug>.pem (always)
1971
- * 2. ./.attest-it/public-keys/<slug>.pem (if project has attest-it config)
2002
+ * to ~/.attest-it/public-keys/<slug>.pem for backup purposes.
2003
+ *
2004
+ * Public keys are now stored inline in the team section of config.yaml and no longer
2005
+ * written to the project directory.
1972
2006
  *
1973
2007
  * @param slug - The identity slug (used for the filename)
1974
2008
  * @param publicKey - The base64-encoded public key
1975
- * @param projectRoot - The project root directory (defaults to cwd)
2009
+ * @param projectRoot - The project root directory (deprecated, kept for backward compatibility)
1976
2010
  * @returns Paths where the key was saved
1977
2011
  * @public
1978
2012
  */
@@ -2107,6 +2141,8 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
2107
2141
  keyRef?: string;
2108
2142
  /** Data to sign (string or Buffer) */
2109
2143
  data: Buffer | string;
2144
+ /** Passphrase for encrypted private keys (optional) */
2145
+ passphrase?: string;
2110
2146
  }
2111
2147
 
2112
2148
  /**
@@ -2171,6 +2207,8 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
2171
2207
  github?: string | undefined;
2172
2208
  /** Base64-encoded Ed25519 public key */
2173
2209
  publicKey: string;
2210
+ /** Public key algorithm (optional, for future-proofing format changes) */
2211
+ publicKeyAlgorithm?: 'ed25519' | undefined;
2174
2212
  }
2175
2213
 
2176
2214
  /**
@@ -2419,20 +2457,22 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
2419
2457
  *
2420
2458
  * @param dir - Directory containing .attest-it/seals.json
2421
2459
  * @param sealsFile - The seals file to write
2460
+ * @param sealsPathOverride - Optional explicit path to seals file (from config.settings.sealsPath)
2422
2461
  * @throws Error if file cannot be written
2423
2462
  * @public
2424
2463
  */
2425
- export declare function writeSeals(dir: string, sealsFile: SealsFile): Promise<void>;
2464
+ export declare function writeSeals(dir: string, sealsFile: SealsFile, sealsPathOverride?: string): Promise<void>;
2426
2465
 
2427
2466
  /**
2428
2467
  * Write seals to the seals.json file (sync).
2429
2468
  *
2430
2469
  * @param dir - Directory containing .attest-it/seals.json
2431
2470
  * @param sealsFile - The seals file to write
2471
+ * @param sealsPathOverride - Optional explicit path to seals file (from config.settings.sealsPath)
2432
2472
  * @throws Error if file cannot be written
2433
2473
  * @public
2434
2474
  */
2435
- export declare function writeSealsSync(dir: string, sealsFile: SealsFile): void;
2475
+ export declare function writeSealsSync(dir: string, sealsFile: SealsFile, sealsPathOverride?: string): void;
2436
2476
 
2437
2477
  /**
2438
2478
  * Write attestations with a cryptographic signature.