UNPKG

green-jwt

Version:

Node implementation of JSON Web Token (JWT) with support for signatures (JWS), encryption (JWE) and web keys (JWK).

388 lines (325 loc) 10.4 kB
// Generated by CoffeeScript 1.6.3 (function() { var HMACSigner, HMACVerifier, JwaAlgorithm, NONE_SIGNER, NoneSigner, NoneVerifier, RSSigner, RSVerifier, crypto, ju, jwa_provider, jwa_table, jwa_verifier, newHMACSigner, newHMACVerifier, newNoneSigner, newNoneVerifier, newRSSigner, newRSVerifier, _ref, _ref1, _ref2, _ref3, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; crypto = require("crypto"); ju = require("./utils"); jwa_table = { NONE: { TYPE: "SIGNATURE", HASH_AL: {} }, HMAC: { TYPE: "SIGNATURE", HASH_AL: { HS256: "SHA256", HS384: "SHA384", HS512: "SHA512" } }, RSA: { TYPE: "SIGNATURE", HASH_AL: { RS256: "RSA-SHA256", RS384: "RSA-SHA384", RS512: "RSA-SHA512" } } }; JwaAlgorithm = (function() { function JwaAlgorithm() {} JwaAlgorithm.prototype.type = function() { var _ref; return jwa_table != null ? (_ref = jwa_table[this.alg]) != null ? _ref.TYPE : void 0 : void 0; }; JwaAlgorithm.prototype.hash = function(alg) { var _ref; return jwa_table != null ? (_ref = jwa_table[this.alg]) != null ? _ref.HASH_AL[alg] : void 0 : void 0; }; return JwaAlgorithm; })(); NoneSigner = (function(_super) { __extends(NoneSigner, _super); function NoneSigner() { _ref = NoneSigner.__super__.constructor.apply(this, arguments); return _ref; } NoneSigner.prototype.alg = "NONE"; NoneSigner.prototype.update = function(data) { return this; }; NoneSigner.prototype.digest = function() { return ""; }; NoneSigner.prototype.sign = function() { return this.digest(); }; return NoneSigner; })(JwaAlgorithm); NONE_SIGNER = new NoneSigner; newNoneSigner = function() { return NONE_SIGNER; }; NoneVerifier = (function(_super) { __extends(NoneVerifier, _super); function NoneVerifier() { _ref1 = NoneVerifier.__super__.constructor.apply(this, arguments); return _ref1; } NoneVerifier.prototype.alg = "NONE"; NoneVerifier.prototype.verify = function(jwt_req) { var jwt_claim, jwt_enc_sig, jwt_header, _ref2; jwt_header = jwt_req != null ? jwt_req.header : void 0; jwt_claim = jwt_req != null ? jwt_req.claim : void 0; jwt_enc_sig = jwt_req != null ? (_ref2 = jwt_req.segments) != null ? _ref2[2] : void 0 : void 0; if (jwt_header.alg !== "none") { return false; } if (jwt_enc_sig) { return false; } return true; }; return NoneVerifier; })(JwaAlgorithm); newNoneVerifier = function() { return new NoneVerifier; }; HMACSigner = (function(_super) { __extends(HMACSigner, _super); HMACSigner.prototype.alg = "HMAC"; function HMACSigner(alg, key) { var error; if (alg == null) { alg = "HS256"; } this.key = key; if (!alg) { throw Error("A defined algorithm is required."); } this.osslAlg = this.hash(alg.toUpperCase()); if (!this.osslAlg) { throw Error("Algorithm " + this.alg + " is not supported by HMAC."); } try { this.hmac = crypto.createHmac(this.osslAlg, this.key); } catch (_error) { error = _error; throw new Error("HMAC does not support algorithm " + this.alg + " => " + this.osslAlg + "! " + error); } } HMACSigner.prototype.update = function(data) { if (!this.hmac) { throw new Error("There is no reference to the hmac object!"); } this.hmac.update(data); return this; }; HMACSigner.prototype.digest = function(encoding) { if (encoding == null) { encoding = "base64"; } if (!this.hmac) { throw new Error("There is no reference to the hmac object!"); } return ju.base64urlEscape(this.hmac.digest(encoding)); }; HMACSigner.prototype.sign = function(encoding) { return this.digest(encoding); }; return HMACSigner; })(JwaAlgorithm); newHMACSigner = function(alg, key) { return new HMACSigner(alg, key); }; HMACVerifier = (function(_super) { __extends(HMACVerifier, _super); function HMACVerifier() { _ref2 = HMACVerifier.__super__.constructor.apply(this, arguments); return _ref2; } HMACVerifier.prototype.alg = "HMAC"; HMACVerifier.prototype.verify = function(jwt_req, key) { var algImpl, signer, _actual_sign, _alg, _claim, _enc_sig, _ref3, _ref4, _ref5, _ref6, _ref7, _typ; if (!jwt_req) { throw new Error("jwt request not specified"); } if (!key) { throw new Error("key not specified"); } _typ = jwt_req != null ? (_ref3 = jwt_req.header) != null ? _ref3.typ : void 0 : void 0; _alg = jwt_req != null ? (_ref4 = jwt_req.header) != null ? _ref4.alg : void 0 : void 0; _claim = jwt_req != null ? jwt_req.claim : void 0; _enc_sig = jwt_req != null ? (_ref5 = jwt_req.segments) != null ? _ref5[2] : void 0 : void 0; if (_typ !== "JWT") { return false; } if (!this.hash(_alg)) { throw new Error("Hash " + _alg + " is not supported!"); } if (!_enc_sig) { return false; } algImpl = jwa_provider(_alg); if (!algImpl) { return false; } signer = algImpl(key); signer.update("" + ((_ref6 = jwt_req.segments) != null ? _ref6[0] : void 0) + "." + ((_ref7 = jwt_req.segments) != null ? _ref7[1] : void 0)); _actual_sign = signer.sign(); return _actual_sign === _enc_sig; }; return HMACVerifier; })(JwaAlgorithm); newHMACVerifier = function() { return new HMACVerifier; }; RSSigner = (function(_super) { __extends(RSSigner, _super); RSSigner.prototype.alg = "RSA"; RSSigner.prototype._assertSigner = function() { if (!this.signer) { throw Error("Signer is not defined!"); } }; function RSSigner(alg, key_PEM) { var error; if (alg == null) { alg = "RSA-SHA256"; } this.key_PEM = key_PEM; if (!alg) { throw Error("A defined algorithm is required."); } this.osslAlg = this.hash(alg.toUpperCase()); if (!this.osslAlg) { new Error("Algorithm " + alg + " is not supported by the specification."); } try { this.signer = crypto.createSign(this.osslAlg); } catch (_error) { error = _error; throw new Error("Unable to create a signer with algorithm " + this.osslAlg + "!"); } } RSSigner.prototype.update = function(data) { this._assertSigner(); this.signer.update(data); return this; }; RSSigner.prototype.sign = function(format) { var _enc_sign, _signed; if (format == null) { format = "base64"; } this._assertSigner(); _signed = this.signer.sign(this.key_PEM, format); _enc_sign = ju.base64urlEscape(_signed); return _enc_sign; }; return RSSigner; })(JwaAlgorithm); newRSSigner = function(alg, key_PEM) { return new RSSigner(alg, key_PEM); }; RSVerifier = (function(_super) { var _createVerifier; __extends(RSVerifier, _super); function RSVerifier() { _ref3 = RSVerifier.__super__.constructor.apply(this, arguments); return _ref3; } RSVerifier.prototype.alg = "RSA"; _createVerifier = function(alg) { var error; try { return crypto.createVerify(alg); } catch (_error) { error = _error; throw new Error("Unable to create a verifier with algorithm " + alg + "! " + error); } }; RSVerifier.prototype.verify = function(jwt_req, public_key) { var openSSL, _alg, _claim, _enc_sig, _ref4, _ref5, _ref6, _sig, _typ, _verifier; if (!jwt_req) { throw new Error("jwt request not specified"); } if (!public_key) { throw new Error("public_key not specified"); } _typ = jwt_req != null ? (_ref4 = jwt_req.header) != null ? _ref4.typ : void 0 : void 0; _alg = jwt_req != null ? (_ref5 = jwt_req.header) != null ? _ref5.alg : void 0 : void 0; _claim = jwt_req != null ? jwt_req.claim : void 0; _enc_sig = jwt_req != null ? (_ref6 = jwt_req.segments) != null ? _ref6[2] : void 0 : void 0; if (_typ !== "JWT") { return false; } if (!_enc_sig) { return false; } openSSL = this.hash(_alg); if (!openSSL) { throw new Error("Hash " + _alg + " is not supported for this JWA " + this.type); } _verifier = _createVerifier(openSSL); if (!_verifier) { return false; } _verifier.update("" + jwt_req.segments[0] + "." + jwt_req.segments[1]); _sig = ju.base64urlUnescape(_enc_sig); return _verifier.verify(public_key, _sig, "base64"); }; return RSVerifier; })(JwaAlgorithm); newRSVerifier = function() { return new RSVerifier; }; module.exports.provider = jwa_provider = function(code) { var _this = this; switch (code) { case "none": return function() { return newNoneSigner(); }; case "HS256": case "HS384": case "HS512": return function(key) { return newHMACSigner(code, key); }; case "RS256": case "RS384": case "RS512": return function(key) { return newRSSigner(code, key); }; case "ES256": case "ES384": case "ES512": return void 0; default: return void 0; } }; module.exports.verifier = jwa_verifier = function(code) { switch (code) { case "none": return newNoneVerifier(); case "HS256": case "HS384": case "HS512": return newHMACVerifier(); case "RS256": case "RS384": case "RS512": return newRSVerifier(); case "ES256": case "ES384": case "ES512": return void 0; default: return void 0; } }; }).call(this);