1 /*! jwsjs-2.0.2 (c) 2010-2015 Kenji Urushima | kjur.github.com/jsrsasign/license 2 */ 3 /* 4 * jwsjs.js - JSON Web Signature JSON Serialization (JWSJS) Class 5 * 6 * version: 2.0.2 (2015 May 29) 7 * 8 * Copyright (c) 2010-2015 Kenji Urushima (kenji.urushima@gmail.com) 9 * 10 * This software is licensed under the terms of the MIT License. 11 * http://kjur.github.com/jsrsasign/license/ 12 * 13 * The above copyright and license notice shall be 14 * included in all copies or substantial portions of the Software. 15 */ 16 17 /** 18 * @fileOverview 19 * @name jwsjs-2.0.js 20 * @author Kenji Urushima kenji.urushima@gmail.com 21 * @version 2.0.2 (2015 May 29) 22 * @since jsjws 1.2, jsrsasign 4.8.0 23 * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a> 24 */ 25 26 if (typeof KJUR == "undefined" || !KJUR) KJUR = {}; 27 if (typeof KJUR.jws == "undefined" || !KJUR.jws) KJUR.jws = {}; 28 29 /** 30 * JSON Web Signature JSON Serialization (JWSJS) class.<br/> 31 * @class JSON Web Signature JSON Serialization (JWSJS) class 32 * @name KJUR.jws.JWSJS 33 * @property {array of String} aHeader array of Encoded JWS Headers 34 * @property {String} sPayload Encoded JWS payload 35 * @property {array of String} aSignature array of Encoded JWS signature value 36 * @author Kenji Urushima 37 * @version 1.0 (18 May 2012) 38 * @requires base64x.js, json-sans-eval.js, jws.js and jsrsasign library 39 * @see <a href="http://kjur.github.com/jsjws/">'jwjws'(JWS JavaScript Library) home page http://kjur.github.com/jsjws/</a> 40 * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a> 41 * @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> 42 */ 43 KJUR.jws.JWSJS = function() { 44 var ns1 = KJUR.jws.JWS; 45 46 this.aHeader = []; 47 this.sPayload = ""; 48 this.aSignature = []; 49 50 // == initialize =================================================================== 51 /** 52 * (re-)initialize this object.<br/> 53 * @name init 54 * @memberOf KJUR.jws.JWSJS 55 * @function 56 */ 57 this.init = function() { 58 this.aHeader = []; 59 this.sPayload = ""; 60 this.aSignature = []; 61 }; 62 63 /** 64 * (re-)initialize and set first signature with JWS.<br/> 65 * @name initWithJWS 66 * @memberOf KJUR.jws.JWSJS 67 * @param {String} sJWS JWS signature to set 68 * @function 69 */ 70 this.initWithJWS = function(sJWS) { 71 this.init(); 72 73 var jws = new KJUR.jws.JWS(); 74 jws.parseJWS(sJWS); 75 76 this.aHeader.push(jws.parsedJWS.headB64U); 77 this.sPayload = jws.parsedJWS.payloadB64U; 78 this.aSignature.push(jws.parsedJWS.sigvalB64U); 79 }; 80 81 // == add signature =================================================================== 82 /** 83 * add a signature to existing JWS-JS by Header and PKCS1 private key.<br/> 84 * @name addSignatureByHeaderKey 85 * @memberOf KJUR.jws.JWSJS 86 * @function 87 * @param {String} sHead JSON string of JWS Header for adding signature. 88 * @param {String} sPemPrvKey string of PKCS1 private key 89 */ 90 this.addSignatureByHeaderKey = function(sHead, sPemPrvKey) { 91 var sPayload = b64utoutf8(this.sPayload); 92 93 var jws = new KJUR.jws.JWS(); 94 var sJWS = jws.generateJWSByP1PrvKey(sHead, sPayload, sPemPrvKey); 95 96 this.aHeader.push(jws.parsedJWS.headB64U); 97 this.aSignature.push(jws.parsedJWS.sigvalB64U); 98 }; 99 100 /** 101 * add a signature to existing JWS-JS by Header, Payload and PKCS1 private key.<br/> 102 * This is to add first signature to JWS-JS object. 103 * @name addSignatureByHeaderPayloadKey 104 * @memberOf KJUR.jws.JWSJS 105 * @function 106 * @param {String} sHead JSON string of JWS Header for adding signature. 107 * @param {String} sPayload string of JWS Payload for adding signature. 108 * @param {String} sPemPrvKey string of PKCS1 private key 109 */ 110 this.addSignatureByHeaderPayloadKey = function(sHead, sPayload, sPemPrvKey) { 111 var jws = new KJUR.jws.JWS(); 112 var sJWS = jws.generateJWSByP1PrvKey(sHead, sPayload, sPemPrvKey); 113 114 this.aHeader.push(jws.parsedJWS.headB64U); 115 this.sPayload = jws.parsedJWS.payloadB64U; 116 this.aSignature.push(jws.parsedJWS.sigvalB64U); 117 }; 118 119 // == verify signature =================================================================== 120 /** 121 * verify JWS-JS object with array of certificate string.<br/> 122 * @name verifyWithCerts 123 * @memberOf KJUR.jws.JWSJS 124 * @function 125 * @param {array of String} aCert array of string for X.509 PEM certificate. 126 * @return 1 if signature is valid. 127 * @throw if JWS-JS signature is invalid. 128 */ 129 this.verifyWithCerts = function(aCert) { 130 if (this.aHeader.length != aCert.length) 131 throw "num headers does not match with num certs"; 132 if (this.aSignature.length != aCert.length) 133 throw "num signatures does not match with num certs"; 134 135 var payload = this.sPayload; 136 var errMsg = ""; 137 for (var i = 0; i < aCert.length; i++) { 138 var cert = aCert[i]; 139 var header = this.aHeader[i]; 140 var sig = this.aSignature[i]; 141 var sJWS = header + "." + payload + "." + sig; 142 143 var jws = new KJUR.jws.JWS(); 144 try { 145 var result = jws.verifyJWSByPemX509Cert(sJWS, cert); 146 if (result != 1) { 147 errMsg += (i + 1) + "th signature unmatch. "; 148 } 149 } catch (ex) { 150 errMsg += (i + 1) + "th signature fail(" + ex + "). "; 151 } 152 } 153 154 if (errMsg == "") { 155 return 1; 156 } else { 157 throw errMsg; 158 } 159 }; 160 161 /** 162 * read JWS-JS string.<br/> 163 * @name raedJWSJS 164 * @memberOf KJUR.jws.JWSJS 165 * @function 166 * @param {String} string of JWS-JS to load. 167 * @throw if sJWSJS is malformed or not JSON string. 168 */ 169 this.readJWSJS = function(sJWSJS) { 170 var oJWSJS = ns1.readSafeJSONString(sJWSJS); 171 if (oJWSJS == null) throw "argument is not JSON string: " + sJWSJS; 172 173 this.aHeader = oJWSJS.headers; 174 this.sPayload = oJWSJS.payload; 175 this.aSignature = oJWSJS.signatures; 176 }; 177 178 // == utility =================================================================== 179 /** 180 * get JSON object for this JWS-JS object.<br/> 181 * @name getJSON 182 * @memberOf KJUR.jws.JWSJS 183 * @function 184 */ 185 this.getJSON = function() { 186 return { "headers": this.aHeader, 187 "payload": this.sPayload, 188 "signatures": this.aSignature }; 189 }; 190 191 /** 192 * check if this JWS-JS object is empty.<br/> 193 * @name isEmpty 194 * @memberOf KJUR.jws.JWSJS 195 * @function 196 * @return 1 if there is no signatures in this object, otherwise 0. 197 */ 198 this.isEmpty = function() { 199 if (this.aHeader.length == 0) return 1; 200 return 0; 201 }; 202 }; 203 204