Use gpg-connect-agent to seed the internal cache of gpg-agent

Fix keygrip (#10)
This commit is contained in:
CrazyMax 2020-05-06 00:10:34 +02:00
parent 041b376dd4
commit 7f1aa5edc1
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 3248E46B6BB8C7F7
3 changed files with 38 additions and 70 deletions

View file

@ -6,7 +6,7 @@ const userInfo = {
passphrase: 'with stupid passphrase', passphrase: 'with stupid passphrase',
keyID: 'D523BD50DD70B0BA', keyID: 'D523BD50DD70B0BA',
fingerprint: '27571A53B86AF0C799B38BA77D851EB72D73BDA0', fingerprint: '27571A53B86AF0C799B38BA77D851EB72D73BDA0',
keygrip: 'BA83FC8947213477F28ADC019F6564A956456163', keygrip: '3E2D1142AA59E08E16B7E2C64BA6DDC773B1A627',
pgp: `-----BEGIN PGP PRIVATE KEY BLOCK----- pgp: `-----BEGIN PGP PRIVATE KEY BLOCK-----
lQdGBF6tzaABEACjFbX7PFEG6vDPN2MPyxYW7/3o/sonORj4HXUFjFxxJxktJ3x3 lQdGBF6tzaABEACjFbX7PFEG6vDPN2MPyxYW7/3o/sonORj4HXUFjFxxJxktJ3x3

49
dist/index.js generated vendored
View file

@ -1139,20 +1139,25 @@ const exec = __importStar(__webpack_require__(807));
exports.agentConfig = `default-cache-ttl 7200 exports.agentConfig = `default-cache-ttl 7200
max-cache-ttl 31536000 max-cache-ttl 31536000
allow-preset-passphrase`; allow-preset-passphrase`;
const getGpgPresetPassphrasePath = () => __awaiter(void 0, void 0, void 0, function* () {
const { libexecdir: libexecdir } = yield exports.getDirs();
let gpgPresetPassphrasePath = path.join(libexecdir, 'gpg-preset-passphrase');
if (yield fs.existsSync(gpgPresetPassphrasePath)) {
return gpgPresetPassphrasePath;
}
return 'gpg-preset-passphrase';
});
const getGnupgHome = () => __awaiter(void 0, void 0, void 0, function* () { const getGnupgHome = () => __awaiter(void 0, void 0, void 0, function* () {
if (process.env.GNUPGHOME) { if (process.env.GNUPGHOME) {
return process.env.GNUPGHOME; return process.env.GNUPGHOME;
} }
return path.join(process.env.HOME || '', '.gnupg'); return path.join(process.env.HOME || '', '.gnupg');
}); });
const gpgConnectAgent = (command) => __awaiter(void 0, void 0, void 0, function* () {
return yield exec.exec(`gpg-connect-agent "${command}" /bye`, [], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('ERR')) {
throw new Error(line);
}
}
return res.stdout.trim();
});
});
exports.getVersion = () => __awaiter(void 0, void 0, void 0, function* () { exports.getVersion = () => __awaiter(void 0, void 0, void 0, function* () {
return yield exec.exec('gpg', ['--version'], true).then(res => { return yield exec.exec('gpg', ['--version'], true).then(res => {
if (res.stderr != '') { if (res.stderr != '') {
@ -1238,6 +1243,7 @@ exports.getKeygrip = (fingerprint) => __awaiter(void 0, void 0, void 0, function
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) { for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('grp')) { if (line.startsWith('grp')) {
keygrip = line.replace(/(grp|:)/g, '').trim(); keygrip = line.replace(/(grp|:)/g, '').trim();
break;
} }
} }
return keygrip; return keygrip;
@ -1249,31 +1255,12 @@ exports.configureAgent = (config) => __awaiter(void 0, void 0, void 0, function*
if (err) if (err)
throw err; throw err;
}); });
yield exec.exec(`gpg-connect-agent "RELOADAGENT" /bye`, [], true).then(res => { yield gpgConnectAgent('RELOADAGENT');
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
});
}); });
exports.presetPassphrase = (keygrip, passphrase) => __awaiter(void 0, void 0, void 0, function* () { exports.presetPassphrase = (keygrip, passphrase) => __awaiter(void 0, void 0, void 0, function* () {
yield exec const hexPassphrase = Buffer.from(passphrase, 'utf8').toString('hex').toUpperCase();
.exec(`"${yield getGpgPresetPassphrasePath()}" --verbose --preset --passphrase "${passphrase}" ${keygrip}`, [], true) yield gpgConnectAgent(`PRESET_PASSPHRASE ${keygrip} -1 ${hexPassphrase}`);
.then(res => { return yield gpgConnectAgent(`KEYINFO ${keygrip}`);
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
});
return yield exec.exec(`gpg-connect-agent "KEYINFO ${keygrip}" /bye`, [], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('ERR')) {
throw new Error(line);
}
}
return res.stdout.trim();
});
}); });
exports.deleteKey = (fingerprint) => __awaiter(void 0, void 0, void 0, function* () { exports.deleteKey = (fingerprint) => __awaiter(void 0, void 0, void 0, function* () {
yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', fingerprint], true).then(res => { yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', fingerprint], true).then(res => {

View file

@ -19,15 +19,6 @@ export interface Dirs {
homedir: string; homedir: string;
} }
const getGpgPresetPassphrasePath = async (): Promise<string> => {
const {libexecdir: libexecdir} = await getDirs();
let gpgPresetPassphrasePath = path.join(libexecdir, 'gpg-preset-passphrase');
if (await fs.existsSync(gpgPresetPassphrasePath)) {
return gpgPresetPassphrasePath;
}
return 'gpg-preset-passphrase';
};
const getGnupgHome = async (): Promise<string> => { const getGnupgHome = async (): Promise<string> => {
if (process.env.GNUPGHOME) { if (process.env.GNUPGHOME) {
return process.env.GNUPGHOME; return process.env.GNUPGHOME;
@ -35,6 +26,20 @@ const getGnupgHome = async (): Promise<string> => {
return path.join(process.env.HOME || '', '.gnupg'); return path.join(process.env.HOME || '', '.gnupg');
}; };
const gpgConnectAgent = async (command: string): Promise<string> => {
return await exec.exec(`gpg-connect-agent "${command}" /bye`, [], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('ERR')) {
throw new Error(line);
}
}
return res.stdout.trim();
});
};
export const getVersion = async (): Promise<Version> => { export const getVersion = async (): Promise<Version> => {
return await exec.exec('gpg', ['--version'], true).then(res => { return await exec.exec('gpg', ['--version'], true).then(res => {
if (res.stderr != '') { if (res.stderr != '') {
@ -125,6 +130,7 @@ export const getKeygrip = async (fingerprint: string): Promise<string> => {
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) { for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('grp')) { if (line.startsWith('grp')) {
keygrip = line.replace(/(grp|:)/g, '').trim(); keygrip = line.replace(/(grp|:)/g, '').trim();
break;
} }
} }
return keygrip; return keygrip;
@ -136,38 +142,13 @@ export const configureAgent = async (config: string): Promise<void> => {
await fs.writeFile(gpgAgentConf, config, function (err) { await fs.writeFile(gpgAgentConf, config, function (err) {
if (err) throw err; if (err) throw err;
}); });
await gpgConnectAgent('RELOADAGENT');
await exec.exec(`gpg-connect-agent "RELOADAGENT" /bye`, [], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
});
}; };
export const presetPassphrase = async (keygrip: string, passphrase: string): Promise<string> => { export const presetPassphrase = async (keygrip: string, passphrase: string): Promise<string> => {
await exec const hexPassphrase: string = Buffer.from(passphrase, 'utf8').toString('hex').toUpperCase();
.exec( await gpgConnectAgent(`PRESET_PASSPHRASE ${keygrip} -1 ${hexPassphrase}`);
`"${await getGpgPresetPassphrasePath()}" --verbose --preset --passphrase "${passphrase}" ${keygrip}`, return await gpgConnectAgent(`KEYINFO ${keygrip}`);
[],
true
)
.then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
});
return await exec.exec(`gpg-connect-agent "KEYINFO ${keygrip}" /bye`, [], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('ERR')) {
throw new Error(line);
}
}
return res.stdout.trim();
});
}; };
export const deleteKey = async (fingerprint: string): Promise<void> => { export const deleteKey = async (fingerprint: string): Promise<void> => {