-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.js
107 lines (92 loc) · 3 KB
/
server.js
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
const restana = require('restana')
const opensslService = require('./openssl-service')
const { v4: uuidv4 } = require('uuid')
const assert = require('assert')
const { AssertionError } = require('assert')
const ALLOWED_BITS = [1024, 2048, 3072, 4096]
let OPENSSL_VERSION
const app = restana({})
app.get(['/api/openssl-version', '/api/health/status'], async (req, res) => {
res.send(OPENSSL_VERSION)
})
app.get('/api/generate/:algorithm', async (req, res) => {
const { algorithm } = req.params
const bits = parseInt(req.query.bits || 3072)
const bytes = parseInt(req.query.bytes || 32)
const filePrefix = `./keys/${uuidv4()}`
const filePubKey = `${filePrefix}-public.pem`
const filePrivKey = `${filePrefix}-private.pem`
try {
assert.ok(ALLOWED_BITS.includes(bits), 'Unsupported bits size! Expecting one of: [1024, 2048, 3072, 4096]')
assert.ok(bytes >= 12 && bytes <= 160, 'Invalid bytes value! Expecting: bytes >= 12 && bytes <= 160')
switch (algorithm) {
case 'RS256':
case 'RS384':
case 'RS512':
case 'PS256':
case 'PS384':
case 'PS512': {
await opensslService.exec(`genrsa -out ${filePrivKey} ${bits}`)
await opensslService.exec(`rsa -in ${filePrivKey} -pubout -out ${filePubKey}`)
const { privateKey, publicKey } = await opensslService.getAndDeleteKeyPair(filePrivKey, filePubKey)
res.send({
privateKey,
publicKey,
algorithm,
bits,
openssl: OPENSSL_VERSION
})
break
}
case 'HS256':
case 'HS384':
case 'HS512': {
const secret = await opensslService.exec(`rand -base64 ${bytes}`)
res.send({
secret: secret.toString().trim(),
algorithm,
bytes,
openssl: OPENSSL_VERSION
})
break
}
case 'ES256':
case 'ES384':
case 'ES512': {
let curve = 'secp521r1'
if (algorithm === 'ES256') {
curve = 'secp256r1'
} else if (algorithm === 'ES384') {
curve = 'secp384r1'
}
await opensslService.exec(`ecparam -genkey -name ${curve} -noout -out ${filePrivKey}`)
await opensslService.exec(`ec -in ${filePrivKey} -pubout -out ${filePubKey}`)
const { privateKey, publicKey } = await opensslService.getAndDeleteKeyPair(filePrivKey, filePubKey)
res.send({
privateKey,
publicKey,
algorithm,
openssl: OPENSSL_VERSION,
curve
})
break
}
default:
res.send('Unsupported algorithm!', 404)
}
} catch (err) {
if (err instanceof AssertionError) {
res.send(err.message, 400)
} else {
res.send(err.message, 500)
}
}
})
opensslService.exec('version').then(version => {
OPENSSL_VERSION = version.toString().trim()
const PORT = process.env.PORT || 3000
app.start(PORT)
console.log('API successfully running on port: ' + PORT)
}).catch(err => {
console.error('OpenSSL integration failed: ' + err.message)
})