1 /*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license 2 */ 3 // 4 // asn1hex.js - Hexadecimal represented ASN.1 string library 5 // 6 // version: 1.1 (09-May-2012) 7 // 8 // Copyright (c) 2010-2012 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 // Depends on: 17 // 18 19 // MEMO: 20 // f('3082025b02...', 2) ... 82025b ... 3bytes 21 // f('020100', 2) ... 01 ... 1byte 22 // f('0203001...', 2) ... 03 ... 1byte 23 // f('02818003...', 2) ... 8180 ... 2bytes 24 // f('3080....0000', 2) ... 80 ... -1 25 // 26 // Requirements: 27 // - ASN.1 type octet length MUST be 1. 28 // (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) 29 // - 30 /** 31 * get byte length for ASN.1 L(length) bytes 32 * @name getByteLengthOfL_AtObj 33 * @memberOf ASN1HEX 34 * @function 35 * @param {String} s hexadecimal string of ASN.1 DER encoded data 36 * @param {Number} pos string index 37 * @return byte length for ASN.1 L(length) bytes 38 */ 39 function _asnhex_getByteLengthOfL_AtObj(s, pos) { 40 if (s.substring(pos + 2, pos + 3) != '8') return 1; 41 var i = parseInt(s.substring(pos + 3, pos + 4)); 42 if (i == 0) return -1; // length octet '80' indefinite length 43 if (0 < i && i < 10) return i + 1; // including '8?' octet; 44 return -2; // malformed format 45 } 46 47 48 /** 49 * get hexadecimal string for ASN.1 L(length) bytes 50 * @name getHexOfL_AtObj 51 * @memberOf ASN1HEX 52 * @function 53 * @param {String} s hexadecimal string of ASN.1 DER encoded data 54 * @param {Number} pos string index 55 * @return {String} hexadecimal string for ASN.1 L(length) bytes 56 */ 57 function _asnhex_getHexOfL_AtObj(s, pos) { 58 var len = _asnhex_getByteLengthOfL_AtObj(s, pos); 59 if (len < 1) return ''; 60 return s.substring(pos + 2, pos + 2 + len * 2); 61 } 62 63 // 64 // getting ASN.1 length value at the position 'idx' of 65 // hexa decimal string 's'. 66 // 67 // f('3082025b02...', 0) ... 82025b ... ??? 68 // f('020100', 0) ... 01 ... 1 69 // f('0203001...', 0) ... 03 ... 3 70 // f('02818003...', 0) ... 8180 ... 128 71 /** 72 * get integer value of ASN.1 length for ASN.1 data 73 * @name getIntOfL_AtObj 74 * @memberOf ASN1HEX 75 * @function 76 * @param {String} s hexadecimal string of ASN.1 DER encoded data 77 * @param {Number} pos string index 78 * @return ASN.1 L(length) integer value 79 */ 80 function _asnhex_getIntOfL_AtObj(s, pos) { 81 var hLength = _asnhex_getHexOfL_AtObj(s, pos); 82 if (hLength == '') return -1; 83 var bi; 84 if (parseInt(hLength.substring(0, 1)) < 8) { 85 bi = parseBigInt(hLength, 16); 86 } else { 87 bi = parseBigInt(hLength.substring(2), 16); 88 } 89 return bi.intValue(); 90 } 91 92 /** 93 * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'. 94 * @name getStartPosOfV_AtObj 95 * @memberOf ASN1HEX 96 * @function 97 * @param {String} s hexadecimal string of ASN.1 DER encoded data 98 * @param {Number} pos string index 99 */ 100 function _asnhex_getStartPosOfV_AtObj(s, pos) { 101 var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); 102 if (l_len < 0) return l_len; 103 return pos + (l_len + 1) * 2; 104 } 105 106 /** 107 * get hexadecimal string of ASN.1 V(value) 108 * @name getHexOfV_AtObj 109 * @memberOf ASN1HEX 110 * @function 111 * @param {String} s hexadecimal string of ASN.1 DER encoded data 112 * @param {Number} pos string index 113 * @return {String} hexadecimal string of ASN.1 value. 114 */ 115 function _asnhex_getHexOfV_AtObj(s, pos) { 116 var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); 117 var len = _asnhex_getIntOfL_AtObj(s, pos); 118 return s.substring(pos1, pos1 + len * 2); 119 } 120 121 /** 122 * get hexadecimal string of ASN.1 TLV at 123 * @name getHexOfTLV_AtObj 124 * @memberOf ASN1HEX 125 * @function 126 * @param {String} s hexadecimal string of ASN.1 DER encoded data 127 * @param {Number} pos string index 128 * @return {String} hexadecimal string of ASN.1 TLV. 129 * @since 1.1 130 */ 131 function _asnhex_getHexOfTLV_AtObj(s, pos) { 132 var hT = s.substr(pos, 2); 133 var hL = _asnhex_getHexOfL_AtObj(s, pos); 134 var hV = _asnhex_getHexOfV_AtObj(s, pos); 135 return hT + hL + hV; 136 } 137 138 /** 139 * get next sibling starting index for ASN.1 object string 140 * @name getPosOfNextSibling_AtObj 141 * @memberOf ASN1HEX 142 * @function 143 * @param {String} s hexadecimal string of ASN.1 DER encoded data 144 * @param {Number} pos string index 145 * @return next sibling starting index for ASN.1 object string 146 */ 147 function _asnhex_getPosOfNextSibling_AtObj(s, pos) { 148 var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); 149 var len = _asnhex_getIntOfL_AtObj(s, pos); 150 return pos1 + len * 2; 151 } 152 153 /** 154 * get array of indexes of child ASN.1 objects 155 * @name getPosArrayOfChildren_AtObj 156 * @memberOf ASN1HEX 157 * @function 158 * @param {String} s hexadecimal string of ASN.1 DER encoded data 159 * @param {Number} start string index of ASN.1 object 160 * @return {Array of Number} array of indexes for childen of ASN.1 objects 161 */ 162 function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { 163 var a = new Array(); 164 var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); 165 a.push(p0); 166 167 var len = _asnhex_getIntOfL_AtObj(h, pos); 168 var p = p0; 169 var k = 0; 170 while (1) { 171 var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); 172 if (pNext == null || (pNext - p0 >= (len * 2))) break; 173 if (k >= 200) break; 174 175 a.push(pNext); 176 p = pNext; 177 178 k++; 179 } 180 181 return a; 182 } 183 184 /** 185 * get string index of nth child object of ASN.1 object refered by h, idx 186 * @name getNthChildIndex_AtObj 187 * @memberOf ASN1HEX 188 * @function 189 * @param {String} h hexadecimal string of ASN.1 DER encoded data 190 * @param {Number} idx start string index of ASN.1 object 191 * @param {Number} nth for child 192 * @return {Number} string index of nth child. 193 * @since 1.1 194 */ 195 function _asnhex_getNthChildIndex_AtObj(h, idx, nth) { 196 var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx); 197 return a[nth]; 198 } 199 200 // ========== decendant methods ============================== 201 202 /** 203 * get string index of nth child object of ASN.1 object refered by h, idx 204 * @name getDecendantIndexByNthList 205 * @memberOf ASN1HEX 206 * @function 207 * @param {String} h hexadecimal string of ASN.1 DER encoded data 208 * @param {Number} currentIndex start string index of ASN.1 object 209 * @param {Array of Number} nthList array list of nth 210 * @return {Number} string index refered by nthList 211 * @since 1.1 212 */ 213 function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) { 214 if (nthList.length == 0) { 215 return currentIndex; 216 } 217 var firstNth = nthList.shift(); 218 var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex); 219 return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList); 220 } 221 222 /** 223 * get hexadecimal string of ASN.1 TLV refered by current index and nth index list. 224 * @name getDecendantHexTLVByNthList 225 * @memberOf ASN1HEX 226 * @function 227 * @param {String} h hexadecimal string of ASN.1 DER encoded data 228 * @param {Number} currentIndex start string index of ASN.1 object 229 * @param {Array of Number} nthList array list of nth 230 * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList 231 * @since 1.1 232 */ 233 function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) { 234 var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList); 235 return _asnhex_getHexOfTLV_AtObj(h, idx); 236 } 237 238 /** 239 * get hexadecimal string of ASN.1 V refered by current index and nth index list. 240 * @name getDecendantHexVByNthList 241 * @memberOf ASN1HEX 242 * @function 243 * @param {String} h hexadecimal string of ASN.1 DER encoded data 244 * @param {Number} currentIndex start string index of ASN.1 object 245 * @param {Array of Number} nthList array list of nth 246 * @return {Number} hexadecimal string of ASN.1 V refered by nthList 247 * @since 1.1 248 */ 249 function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) { 250 var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList); 251 return _asnhex_getHexOfV_AtObj(h, idx); 252 } 253 254 // ========== class definition ============================== 255 256 /** 257 * ASN.1 DER encoded hexadecimal string utility class 258 * @class ASN.1 DER encoded hexadecimal string utility class 259 * @author Kenji Urushima 260 * @version 1.1 (09 May 2012) 261 * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a> 262 * @since 1.1 263 */ 264 function ASN1HEX() { 265 return ASN1HEX; 266 } 267 268 ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj; 269 ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj; 270 ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj; 271 ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj; 272 ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj; 273 ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj; 274 ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj; 275 ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj; 276 ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj; 277 ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList; 278 ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList; 279 ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList; 280