Skip to content

Commit 9082e18

Browse files
committed
do not accept PKCS#8, certificates.
accept jwk
1 parent f75a727 commit 9082e18

File tree

4 files changed

+28
-92
lines changed

4 files changed

+28
-92
lines changed

src/utils.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const boom = require('boom')
22
const joi = require('joi')
3+
const jwkToPem = require('jwk-to-pem')
34

45
/**
56
* @type Object
@@ -18,7 +19,7 @@ const scheme = joi.object({
1819
.description('The related secret of the Keycloak client/application')
1920
.example('1234-bar-4321-foo'),
2021
publicKey: joi.alternatives().try(
21-
joi.string().regex(/^-----BEGIN((( RSA)? PUBLIC KEY)| CERTIFICATE)-----[\s\S]*-----END((( RSA)? PUBLIC KEY)| CERTIFICATE)-----\s?$/ig, 'PEM'),
22+
joi.string().regex(/^-----BEGIN RSA PUBLIC KEY-----[\s\S]*-----END RSA PUBLIC KEY-----\s?$/ig, 'PEM'),
2223
joi.object().type(Buffer),
2324
joi.object({
2425
kty: joi.string().required()
@@ -45,18 +46,37 @@ const scheme = joi.object({
4546
.unknown(false)
4647
.required()
4748

49+
/**
50+
* @function
51+
* @private
52+
*
53+
* Check whether the passed in value is a JSON Web Key.
54+
*
55+
* @param {*} key The value to be tested
56+
* @returns {boolean} Whether the value is a JWK
57+
*/
58+
function isJwk (key) {
59+
return !!(key && key.kty)
60+
}
61+
4862
/**
4963
* @function
5064
* @public
5165
*
5266
* Validate the plugin related options.
67+
* If `publicKey` is JWK transform to PEM.
5368
*
5469
* @param {Object} opts The plugin related options
5570
* @returns {Object} The validated options
5671
*
57-
* @throws {Error} Options are invalid
72+
* @throws {TypeError} If JWK is malformed or invalid
73+
* @throws {Error} If options are invalid
5874
*/
5975
function verify (opts) {
76+
if (isJwk(opts.publicKey)) {
77+
opts.publicKey = jwkToPem(opts.publicKey)
78+
}
79+
6080
return joi.attempt(opts, scheme)
6181
}
6282

@@ -109,6 +129,7 @@ function fakeToolkit (h) {
109129
}
110130

111131
module.exports = {
132+
isJwk,
112133
raiseUnauthorized,
113134
errorMessages,
114135
fakeToolkit,

test/fixtures/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const entitlementPath = `/authz/entitlement/${clientId}`
4848
const realmUrl = `${baseUrl}${realmPath}`
4949
const publicKeyBuffer = fs.readFileSync('./test/fixtures/public-rsa.pem')
5050
const publicKeyRsa = publicKeyBuffer.toString()
51-
const publicKey = fs.readFileSync('./test/fixtures/public.pem')
52-
const publicKeyCert = fs.readFileSync('./test/fixtures/public.cert')
51+
const publicKey = fs.readFileSync('./test/fixtures/public.pem').toString()
52+
const publicKeyCert = fs.readFileSync('./test/fixtures/public.cert').toString()
5353
const publicKeyJwk = {
5454
kty: 'RSA',
5555
n: 'ALq_ejKEGv25YOXiRapjf_1eKEIymgSZeihL1khgFYEZtj7JxSswiSvWia1IxE0uO9_8enwB18heUCrp-mrzcaVrNlc8JTuLfAYthKUltsNJXndjs0fzBQmFF9QYNNDly5nYdJL3pgAR10ji-GbOJzfea6--ybHRup7cpVprZ2ZaH8ksC4xa1wdiRabp5eJ-3he8vLw-GcsnL4vsZfjrjAOqqJi0JnyAxdKiYdEDLf8YeggeKKCuWhculRzkVOYEujKEoCe_GT4apimskXelNK4Qzqu21olcpJLUz3QdV_2JTG0B6J8qmdM9rIe3u6Ja6FHRNRbA4tEncVdmc733_CCD0hk--IELmlOG7qFVKTI0nVw3ycPZuIv5obGcF9fzFFPDqtQLAR3YE5DVWlcBXOmewKiUhlv5sTCkKrKTq_vwQDPKZ8OQQkf0Z2QSXzIwGIkoeq1WLhFlAQS4GViETQDMkcEvDrVsQA3zgbVcJ_H5sPLHIa6PVw9e1XKk3Y5UtTJK-92aA9RmoFmb7kjms9j9D4Z32qUVBdSpG44528sy6X0_DIKL78QUCQyHEWC-aHrV7v_1eazQK9J2uMzAZDzotwK6RafmeGCrpWJkhBv_9teqy5s45VihJB9Tit_Y3XQ6zE4nZcQymPkx4XskAT2eqRX2yhDOdvNYJWI5HkKR',

test/index.verify.spec.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

test/utils.validate.spec.js

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ test('throw error if options are invalid – publicKey', (t) => {
104104
{},
105105
{
106106
foobar: 42
107-
}
107+
},
108+
fixtures.common.publicKey,
109+
fixtures.common.publicKeyCert
108110
]
109111

110112
t.plan(invalids.length)
@@ -258,18 +260,6 @@ test('throw no error if options are valid – offline', (t) => {
258260
})
259261
})
260262

261-
test('throw no error if options are valid – publicKey', (t) => {
262-
t.plan(valids.length)
263-
264-
valids.forEach((valid) => {
265-
t.notThrows(
266-
() => utils.verify(helpers.getOptions(Object.assign({
267-
publicKey: fixtures.common.publicKey
268-
}, valid))),
269-
Error, helpers.log('valid.publicKey', valid))
270-
})
271-
})
272-
273263
test('throw no error if options are valid – publicKey/Rsa', (t) => {
274264
t.plan(valids.length)
275265

@@ -282,18 +272,6 @@ test('throw no error if options are valid – publicKey/Rsa', (t) => {
282272
})
283273
})
284274

285-
test('throw no error if options are valid – publicKey/Cert', (t) => {
286-
t.plan(valids.length)
287-
288-
valids.forEach((valid) => {
289-
t.notThrows(
290-
() => utils.verify(helpers.getOptions(Object.assign({
291-
publicKey: fixtures.common.publicKeyCert
292-
}, valid))),
293-
Error, helpers.log('valid.publicKey/Cert', valid))
294-
})
295-
})
296-
297275
test('throw no error if options are valid – publicKey/Buffer', (t) => {
298276
t.plan(valids.length)
299277

0 commit comments

Comments
 (0)