Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

Commit 354704b

Browse files
committed
Fix bug in self signed JWT creation. The header must contain the cert thumbprint. The jwt-simple lib doesn't provide a way to do that. Switching to customer implementation.
1 parent 17808dc commit 354704b

File tree

4 files changed

+43
-17
lines changed

4 files changed

+43
-17
lines changed

lib/self-signed-jwt.js

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,58 @@
2020
*/
2121
'use strict';
2222

23-
require('date-utils');
2423
var jwtConstants = require('./constants').Jwt;
25-
var jwt = require('jwt-simple');
2624
var Logger = require('./log').Logger;
25+
var util = require('./util');
26+
27+
var crypto = require('crypto');
28+
require('date-utils');
29+
var uuid = require('node-uuid');
2730

28-
function SelfSignedJwt(callContext, authority, clientId, certificate) {
31+
function SelfSignedJwt(callContext, authority, clientId) {
2932
this._log = new Logger('SelfSignedJwt', callContext._logContext);
3033
this._callContext = callContext;
3134

3235
this._tokenEndpoint = authority.tokenEndpoint;
33-
this._certificate = certificate;
3436
this._clientId = clientId;
3537
}
3638

37-
SelfSignedJwt.prototype.create = function() {
38-
var now = new Date();
39-
// var expires = Date.now().add({ minutes: jwtConstants.SELF_SIGNED_JWT_LIFETIME });
39+
SelfSignedJwt.prototype._createHeader = function(thumbprint) {
40+
var header = { typ: 'JWT', alg: 'RS256', x5t : thumbprint };
41+
42+
this._log.verbose('Creating self signed JWT header. Thumbprint: ' + thumbprint);
43+
44+
return header;
45+
};
46+
47+
SelfSignedJwt.prototype._createPayload = function() {
48+
var now = new Date();
4049
var expires = (new Date()).addMinutes(jwtConstants.SELF_SIGNED_JWT_LIFETIME);
4150

42-
var jwtPayload = {};
43-
jwtPayload[jwtConstants.AUDIENCE] = this._authority;
44-
jwtPayload[jwtConstants.ISSUER] = this._clientId;
45-
jwtPayload[jwtConstants.SUBJECT] = this._clientId;
46-
jwtPayload[jwtConstants.NOT_BEFORE] = now.getTime();
47-
jwtPayload[jwtConstants.EXPIRES_ON] = expires.getTime();
51+
this._log.verbose('Creating self signed JWT payload. Expires: ' + expires + ' NotBefore: ' + now);
52+
53+
var jwtPayload = {};
54+
jwtPayload[jwtConstants.AUDIENCE] = this._authority;
55+
jwtPayload[jwtConstants.ISSUER] = this._clientId;
56+
jwtPayload[jwtConstants.SUBJECT] = this._clientId;
57+
jwtPayload[jwtConstants.NOT_BEFORE] = now.getTime();
58+
jwtPayload[jwtConstants.EXPIRES_ON] = expires.getTime();
59+
jwtPayload[jwtConstants.JWT_ID] = uuid.v4();
60+
61+
return jwtPayload;
62+
};
63+
64+
SelfSignedJwt.prototype.create = function(certificate, thumbprint) {
65+
var header = this._createHeader(thumbprint);
66+
var payload = this._createPayload();
67+
68+
var headerString = util.base64EncodeStringUrlSafe(JSON.stringify(header));
69+
var payloadString = util.base64EncodeStringUrlSafe(JSON.stringify(payload));
70+
var stringToSign = headerString + '.' + payloadString;
71+
72+
var signature = util.base64EncodeStringUrlSafe(crypto.createSign('RSA-SHA256').update(stringToSign).sign(certificate, 'base64'));
4873

49-
return jwt.encode(jwtPayload, this._certificate, 'RS256');
74+
return stringToSign + '.' + signature;
5075
};
5176

5277
module.exports.SelfSignedJwt = SelfSignedJwt;

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"licenses": [ { "type": "Apache 2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0" } ],
2424
"dependencies": {
2525
"date-utils": "*",
26-
"jwt-simple": "~0",
2726
"node-uuid": "1.4.1",
2827
"request": ">= 2.9.203",
2928
"underscore": ">= 1.3.1",

test/self-signed-jwt.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ var SelfSignedJwt = testRequire('self-signed-jwt').SelfSignedJwt;
3333

3434
suite('self-signed-jwt', function() {
3535
test('create-jwt', function(done) {
36-
var ssjwt = new SelfSignedJwt(cp.callContext, cp.authority, cp.clienId, util.getSelfSignedCert());
37-
var jwt = ssjwt.create();
36+
var ssjwt = new SelfSignedJwt(cp.callContext, cp.authority, cp.clienId);
37+
var jwt = ssjwt.create(util.getSelfSignedCert(), cp.certHash);
3838
var err;
3939
if (!jwt) {
4040
err = new Error('Returned empty jwt');

test/util/util.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,4 +583,6 @@ util.getSelfSignedCert = function() {
583583
return privatePem;
584584
};
585585

586+
util.commonParameters.certHash = 'C1:5D:EA:86:56:AD:DF:67:BE:80:31:D8:5E:BD:DC:5A:D6:C4:36:E1';
587+
586588
module.exports = util;

0 commit comments

Comments
 (0)