generated from actions/typescript-action
-
Notifications
You must be signed in to change notification settings - Fork 3
/
gpg.ts
128 lines (109 loc) · 2.85 KB
/
gpg.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import * as exec from '@actions/exec'
import * as fs from 'fs'
import * as openpgp from './openpgp'
import * as os from 'os'
import * as path from 'path'
export const agentConfig = `default-cache-ttl 7200
max-cache-ttl 31536000
allow-preset-passphrase`
const gpgConnectAgent = async (
command: string,
homedir: string
): Promise<string> => {
const cmd = `gpg-connect-agent --homedir ${homedir} "${command}" /bye`
const res = await exec.getExecOutput(cmd, [], {
ignoreReturnCode: true,
silent: true
})
if (res.stderr.length > 0 && res.exitCode !== 0) {
throw new Error(res.stderr)
}
for (const 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 importKey = async (
key: string,
homedir: string
): Promise<string> => {
const keyFolder: string = fs.mkdtempSync(
path.join(os.tmpdir(), 'ghaction-import-gpg-')
)
const keyPath = `${keyFolder}/key.pgp`
fs.writeFileSync(
keyPath,
(await openpgp.isArmored(key))
? key
: Buffer.from(key, 'base64').toString(),
{mode: 0o600}
)
const args = ['--homedir', homedir, '--import', '--batch', '--yes', keyPath]
try {
const res = await exec.getExecOutput('gpg', args, {
ignoreReturnCode: true,
silent: true
})
if (res.stderr.length > 0 && res.exitCode !== 0) {
throw new Error(res.stderr)
}
if (res.stderr !== '') {
return res.stderr.trim()
}
return res.stdout.trim()
} finally {
fs.unlinkSync(keyPath)
}
}
export const getKeygrips = async (
fingerprint: string,
homedir: string
): Promise<string[]> => {
const args = [
'--homedir',
homedir,
'--batch',
'--with-colons',
'--with-keygrip',
'--list-secret-keys',
fingerprint
]
const res = await exec.getExecOutput('gpg', args, {
ignoreReturnCode: true,
silent: true
})
const keygrips: string[] = []
for (const line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
if (line.startsWith('grp')) {
keygrips.push(line.replace(/(grp|:)/g, '').trim())
}
}
return keygrips
}
export const overwriteAgentConfiguration = async (
config: string,
homedir: string
): Promise<void> => {
// nosemgrep
const gpgAgentConfPath: string = path.join(homedir, 'gpg-agent.conf')
fs.writeFile(gpgAgentConfPath, config, function (err) {
if (err) throw err
})
await gpgConnectAgent('RELOADAGENT', homedir)
}
export const presetPassphrase = async (
keygrip: string,
passphrase: string,
homedir: string
): Promise<string> => {
const hexPassphrase: string = Buffer.from(passphrase, 'utf8')
.toString('hex')
.toUpperCase()
await gpgConnectAgent(
`PRESET_PASSPHRASE ${keygrip} -1 ${hexPassphrase}`,
homedir
)
return await gpgConnectAgent(`KEYINFO ${keygrip}`, homedir)
}