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