api-console-assets
Version:
This repo only exists to publish api console components to npm
305 lines (285 loc) • 10.7 kB
JavaScript
/* jwsjs-2.2.1 (c) 2010-2018 Kenji Urushima | kjur.github.com/jsrsasign/license
*/
/*
* jwsjs.js - JSON Web Signature JSON Serialization (JWSJS) Class
*
* Copyright (c) 2010-2018 Kenji Urushima (kenji.urushima@gmail.com)
*
* This software is licensed under the terms of the MIT License.
* https://kjur.github.io/jsrsasign/license/
*
* The above copyright and license notice shall be
* included in all copies or substantial portions of the Software.
*/
/**
* @fileOverview
* @name jwsjs-2.0.js
* @author Kenji Urushima kenji.urushima@gmail.com
* @version jsrsasign 8.0.0 jwsjs 2.2.1 (2018-Mar-24)
* @since jsjws 1.2, jsrsasign 4.8.0
* @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
*/
if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
if (typeof KJUR.jws == "undefined" || !KJUR.jws) KJUR.jws = {};
/**
* JSON Web Signature JSON Serialization (JWSJS) class.<br/>
* @class JSON Web Signature JSON Serialization (JWSJS) class
* @name KJUR.jws.JWSJS
* @property {array of String} aHeader array of Encoded JWS Headers
* @property {String} sPayload Encoded JWS payload
* @property {array of String} aSignature array of Encoded JWS signature value
* @author Kenji Urushima
* @version 2.1.0 (2016 Sep 6)
* @see <a href="https://kjur.github.io/jsjws/">old jwjws home page https://kjur.github.io/jsjws/</a>
* @see <a href="https://kjur.github.io/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page https://kjur.github.io/jsrsasign/</a>
* @see <a href="http://tools.ietf.org/html/draft-jones-json-web-signature-json-serialization-01">IETF I-D JSON Web Signature JSON Serialization (JWS-JS) specification</a>
*
* @description
* This class generates and verfies "JSON Web Signature JSON Serialization (JWSJS)" of
* <a href="http://tools.ietf.org/html/draft-jones-json-web-signature-json-serialization-01">
* IETF Internet Draft</a>. Here is major methods of this class:
* <ul>
* <li>{@link KJUR.jws.JWSJS#readJWSJS} - initialize with string or JSON object of JWSJS.</li>
* <li>{@link KJUR.jws.JWSJS#initWithJWS} - initialize with JWS as first signature.</li>
* <li>{@link KJUR.jws.JWSJS#addSignature} - append signature to JWSJS object.</li>
* <li>{@link KJUR.jws.JWSJS#verifyAll} - verify all signatures in JWSJS object.</li>
* <li>{@link KJUR.jws.JWSJS#getJSON} - get result of JWSJS object as JSON object.</li>
* </ul>
*
* @example
* // initialize
* jwsjs1 = new KJUR.jws.JWSJS();
* jwsjs1.readJWSJS("{headers: [...], payload: "eyJ...", signatures: [...]}");
*
* // add PS256 signature with RSA private key object
* prvKeyObj = KEYUTIL.getKey("-----BEGIN PRIVATE KEY...");
* jwsjs1.addSignature("PS256", {alg: "PS256"}, prvKeyObj);
* // add HS256 signature with HMAC password "secret"
* jwsjs1.addSignature(null, {alg: "HS256"}, {utf8: "secret"});
*
* // get result finally
* jwsjsObj1 = jwsjs1.getJSON();
*
* // verify all signatures
* isValid = jwsjs1.verifyAll([["-----BEGIN CERT...", ["RS256"]],
* [{utf8: "secret"}, ["HS256"]]]);
*
*/
KJUR.jws.JWSJS = function() {
var _KJUR = KJUR,
_KJUR_jws = _KJUR.jws,
_KJUR_jws_JWS = _KJUR_jws.JWS,
_readSafeJSONString = _KJUR_jws_JWS.readSafeJSONString;
this.aHeader = [];
this.sPayload = "";
this.aSignature = [];
// == initialize ==========================================================
/**
* (re-)initialize this object.<br/>
* @name init
* @memberOf KJUR.jws.JWSJS#
* @function
*/
this.init = function() {
this.aHeader = [];
this.sPayload = undefined;
this.aSignature = [];
};
/**
* (re-)initialize and set first signature with JWS.<br/>
* @name initWithJWS
* @memberOf KJUR.jws.JWSJS#
* @param {String} sJWS JWS signature to set
* @function
* @example
* jwsjs1 = new KJUR.jws.JWSJWS();
* jwsjs1.initWithJWS("eyJ...");
*/
this.initWithJWS = function(sJWS) {
this.init();
var a = sJWS.split(".");
if (a.length != 3)
throw "malformed input JWS";
this.aHeader.push(a[0]);
this.sPayload = a[1];
this.aSignature.push(a[2]);
};
// == add signature =======================================================
/**
* add a signature to existing JWS-JS by algorithm, header and key.<br/>
* @name addSignature
* @memberOf KJUR.jws.JWSJS#
* @function
* @param {String} alg JWS algorithm. If null, alg in header will be used.
* @param {Object} spHead string or object of JWS Header to add.
* @param {Object} key JWS key to sign. key object, PEM private key or HMAC key
* @param {String} pass optional password for encrypted PEM private key
* @throw if signature append failed.
* @example
* // initialize
* jwsjs1 = new KJUR.jws.JWSJS();
* jwsjs1.readJWSJS("{headers: [...], payload: "eyJ...", signatures: [...]}");
*
* // add PS256 signature with RSA private key object
* prvKeyObj = KEYUTIL.getKey("-----BEGIN PRIVATE KEY...");
* jwsjs1.addSignature("PS256", {alg: "PS256"}, prvKeyObj);
*
* // add HS256 signature with HMAC password "secret"
* jwsjs1.addSignature(null, {alg: "HS256"}, {utf8: "secret"});
*
* // get result finally
* jwsjsObj1 = jwsjs1.getJSON();
*/
this.addSignature = function(alg, spHead, key, pass) {
if (this.sPayload === undefined || this.sPayload === null)
throw "there's no JSON-JS signature to add.";
var sigLen = this.aHeader.length;
if (this.aHeader.length != this.aSignature.length)
throw "aHeader.length != aSignature.length";
try {
var sJWS = KJUR.jws.JWS.sign(alg, spHead, this.sPayload, key, pass);
var a = sJWS.split(".");
var sHeader2 = a[0];
var sSignature2 = a[2];
this.aHeader.push(a[0]);
this.aSignature.push(a[2]);
} catch(ex) {
if (this.aHeader.length > sigLen) this.aHeader.pop();
if (this.aSignature.length > sigLen) this.aSignature.pop();
throw "addSignature failed: " + ex;
}
};
// == verify signature ====================================================
/**
* verify all signature of JWS-JS object by array of key and acceptAlgs.<br/>
* @name verifyAll
* @memberOf KJUR.jws.JWSJS#
* @function
* @param {array of key and acceptAlgs} aKeyAlg a array of key and acceptAlgs
* @return true if all signatures are valid otherwise false
* @since jwsjs 2.1.0 jsrsasign 5.1.0
* @example
* jwsjs1 = new KJUR.jws.JWSJS();
* jwsjs1.readJWSJS("{headers: [...], payload: "eyJ...", signatures: [...]}");
* isValid = jwsjs1.verifyAll([["-----BEGIN CERT...", ["RS256"]],
* [{utf8: "secret"}, ["HS256"]]]);
*/
this.verifyAll = function(aKeyAlg) {
if (this.aHeader.length !== aKeyAlg.length ||
this.aSignature.length !== aKeyAlg.length)
return false;
for (var i = 0; i < aKeyAlg.length; i++) {
var keyAlg = aKeyAlg[i];
if (keyAlg.length !== 2) return false;
var result = this.verifyNth(i, keyAlg[0], keyAlg[1]);
if (result === false) return false;
}
return true;
};
/**
* verify Nth signature of JWS-JS object by key and acceptAlgs.<br/>
* @name verifyNth
* @memberOf KJUR.jws.JWSJS#
* @function
* @param {Integer} idx nth index of JWS-JS signature to verify
* @param {Object} key key to verify
* @param {array of String} acceptAlgs array of acceptable signature algorithms
* @return true if signature is valid otherwise false
* @since jwsjs 2.1.0 jsrsasign 5.1.0
* @example
* jwsjs1 = new KJUR.jws.JWSJS();
* jwsjs1.readJWSJS("{headers: [...], payload: "eyJ...", signatures: [...]}");
* isValid1 = jwsjs1.verifyNth(0, "-----BEGIN CERT...", ["RS256"]);
* isValid2 = jwsjs1.verifyNth(1, {utf8: "secret"}, ["HS256"]);
*/
this.verifyNth = function(idx, key, acceptAlgs) {
if (this.aHeader.length <= idx || this.aSignature.length <= idx)
return false;
var sHeader = this.aHeader[idx];
var sSignature = this.aSignature[idx];
var sJWS = sHeader + "." + this.sPayload + "." + sSignature;
var result = false;
try {
result = _KJUR_jws_JWS.verify(sJWS, key, acceptAlgs);
} catch (ex) {
return false;
}
return result;
};
/**
* read JWS-JS string or object<br/>
* @name readJWSJS
* @memberOf KJUR.jws.JWSJS#
* @function
* @param {Object} spJWSJS string or JSON object of JWS-JS to load.
* @throw if sJWSJS is malformed or not JSON string.
* @description
* NOTE: Loading from JSON object is suppored from
* jsjws 2.1.0 jsrsasign 5.1.0 (2016-Sep-06).
* @example
* // load JWSJS from string
* jwsjs1 = new KJUR.jws.JWSJS();
* jwsjs1.readJWSJS("{headers: [...], payload: "eyJ...", signatures: [...]}");
*
* // load JWSJS from JSON object
* jwsjs1 = new KJUR.jws.JWSJS();
* jwsjs1.readJWSJS({headers: [...], payload: "eyJ...", signatures: [...]});
*/
this.readJWSJS = function(spJWSJS) {
if (typeof spJWSJS === "string") {
var oJWSJS = _readSafeJSONString(spJWSJS);
if (oJWSJS == null) throw "argument is not safe JSON object string";
this.aHeader = oJWSJS.headers;
this.sPayload = oJWSJS.payload;
this.aSignature = oJWSJS.signatures;
} else {
try {
if (spJWSJS.headers.length > 0) {
this.aHeader = spJWSJS.headers;
} else {
throw "malformed header";
}
if (typeof spJWSJS.payload === "string") {
this.sPayload = spJWSJS.payload;
} else {
throw "malformed signatures";
}
if (spJWSJS.signatures.length > 0) {
this.aSignatures = spJWSJS.signatures;
} else {
throw "malformed signatures";
}
} catch (ex) {
throw "malformed JWS-JS JSON object: " + ex;
}
}
};
// == utility =============================================================
/**
* get JSON object for this JWS-JS object.<br/>
* @name getJSON
* @memberOf KJUR.jws.JWSJS#
* @function
* @example
* jwsj1 = new KJUR.jws.JWSJS();
* // do some jwsj1 operation then get result by getJSON()
* jwsjsObj1 = jwsjs1.getJSON();
* // jwsjsObj1 → { headers: [...], payload: "ey...", signatures: [...] }
*/
this.getJSON = function() {
return { "headers": this.aHeader,
"payload": this.sPayload,
"signatures": this.aSignature };
};
/**
* check if this JWS-JS object is empty.<br/>
* @name isEmpty
* @memberOf KJUR.jws.JWSJS#
* @function
* @return 1 if there is no signatures in this object, otherwise 0.
*/
this.isEmpty = function() {
if (this.aHeader.length == 0) return 1;
return 0;
};
};