/*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license */ // // asn1hex.js - Hexadecimal represented ASN.1 string library // // version: 1.1 (09-May-2012) // // Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com) // // This software is licensed under the terms of the MIT License. // http://kjur.github.com/jsrsasign/license/ // // The above copyright and license notice shall be // included in all copies or substantial portions of the Software. // // Depends on: // // MEMO: // f('3082025b02...', 2) ... 82025b ... 3bytes // f('020100', 2) ... 01 ... 1byte // f('0203001...', 2) ... 03 ... 1byte // f('02818003...', 2) ... 8180 ... 2bytes // f('3080....0000', 2) ... 80 ... -1 // // Requirements: // - ASN.1 type octet length MUST be 1. // (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) // - /** * get byte length for ASN.1 L(length) bytes * @name getByteLengthOfL_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index * @return byte length for ASN.1 L(length) bytes */ function _asnhex_getByteLengthOfL_AtObj(s, pos) { if (s.substring(pos + 2, pos + 3) != '8') return 1; var i = parseInt(s.substring(pos + 3, pos + 4)); if (i == 0) return -1; // length octet '80' indefinite length if (0 < i && i < 10) return i + 1; // including '8?' octet; return -2; // malformed format } /** * get hexadecimal string for ASN.1 L(length) bytes * @name getHexOfL_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index * @return {String} hexadecimal string for ASN.1 L(length) bytes */ function _asnhex_getHexOfL_AtObj(s, pos) { var len = _asnhex_getByteLengthOfL_AtObj(s, pos); if (len < 1) return ''; return s.substring(pos + 2, pos + 2 + len * 2); } // // getting ASN.1 length value at the position 'idx' of // hexa decimal string 's'. // // f('3082025b02...', 0) ... 82025b ... ??? // f('020100', 0) ... 01 ... 1 // f('0203001...', 0) ... 03 ... 3 // f('02818003...', 0) ... 8180 ... 128 /** * get integer value of ASN.1 length for ASN.1 data * @name getIntOfL_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index * @return ASN.1 L(length) integer value */ function _asnhex_getIntOfL_AtObj(s, pos) { var hLength = _asnhex_getHexOfL_AtObj(s, pos); if (hLength == '') return -1; var bi; if (parseInt(hLength.substring(0, 1)) < 8) { bi = parseBigInt(hLength, 16); } else { bi = parseBigInt(hLength.substring(2), 16); } return bi.intValue(); } /** * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'. * @name getStartPosOfV_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index */ function _asnhex_getStartPosOfV_AtObj(s, pos) { var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); if (l_len < 0) return l_len; return pos + (l_len + 1) * 2; } /** * get hexadecimal string of ASN.1 V(value) * @name getHexOfV_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index * @return {String} hexadecimal string of ASN.1 value. */ function _asnhex_getHexOfV_AtObj(s, pos) { var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); var len = _asnhex_getIntOfL_AtObj(s, pos); return s.substring(pos1, pos1 + len * 2); } /** * get hexadecimal string of ASN.1 TLV at * @name getHexOfTLV_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index * @return {String} hexadecimal string of ASN.1 TLV. * @since 1.1 */ function _asnhex_getHexOfTLV_AtObj(s, pos) { var hT = s.substr(pos, 2); var hL = _asnhex_getHexOfL_AtObj(s, pos); var hV = _asnhex_getHexOfV_AtObj(s, pos); return hT + hL + hV; } /** * get next sibling starting index for ASN.1 object string * @name getPosOfNextSibling_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} pos string index * @return next sibling starting index for ASN.1 object string */ function _asnhex_getPosOfNextSibling_AtObj(s, pos) { var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); var len = _asnhex_getIntOfL_AtObj(s, pos); return pos1 + len * 2; } /** * get array of indexes of child ASN.1 objects * @name getPosArrayOfChildren_AtObj * @memberOf ASN1HEX * @function * @param {String} s hexadecimal string of ASN.1 DER encoded data * @param {Number} start string index of ASN.1 object * @return {Array of Number} array of indexes for childen of ASN.1 objects */ function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { var a = new Array(); var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); a.push(p0); var len = _asnhex_getIntOfL_AtObj(h, pos); var p = p0; var k = 0; while (1) { var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); if (pNext == null || (pNext - p0 >= (len * 2))) break; if (k >= 200) break; a.push(pNext); p = pNext; k++; } return a; } /** * get string index of nth child object of ASN.1 object refered by h, idx * @name getNthChildIndex_AtObj * @memberOf ASN1HEX * @function * @param {String} h hexadecimal string of ASN.1 DER encoded data * @param {Number} idx start string index of ASN.1 object * @param {Number} nth for child * @return {Number} string index of nth child. * @since 1.1 */ function _asnhex_getNthChildIndex_AtObj(h, idx, nth) { var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx); return a[nth]; } // ========== decendant methods ============================== /** * get string index of nth child object of ASN.1 object refered by h, idx * @name getDecendantIndexByNthList * @memberOf ASN1HEX * @function * @param {String} h hexadecimal string of ASN.1 DER encoded data * @param {Number} currentIndex start string index of ASN.1 object * @param {Array of Number} nthList array list of nth * @return {Number} string index refered by nthList * @since 1.1 */ function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) { if (nthList.length == 0) { return currentIndex; } var firstNth = nthList.shift(); var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex); return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList); } /** * get hexadecimal string of ASN.1 TLV refered by current index and nth index list. * @name getDecendantHexTLVByNthList * @memberOf ASN1HEX * @function * @param {String} h hexadecimal string of ASN.1 DER encoded data * @param {Number} currentIndex start string index of ASN.1 object * @param {Array of Number} nthList array list of nth * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList * @since 1.1 */ function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) { var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList); return _asnhex_getHexOfTLV_AtObj(h, idx); } /** * get hexadecimal string of ASN.1 V refered by current index and nth index list. * @name getDecendantHexVByNthList * @memberOf ASN1HEX * @function * @param {String} h hexadecimal string of ASN.1 DER encoded data * @param {Number} currentIndex start string index of ASN.1 object * @param {Array of Number} nthList array list of nth * @return {Number} hexadecimal string of ASN.1 V refered by nthList * @since 1.1 */ function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) { var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList); return _asnhex_getHexOfV_AtObj(h, idx); } // ========== class definition ============================== /** * ASN.1 DER encoded hexadecimal string utility class * @class ASN.1 DER encoded hexadecimal string utility class * @author Kenji Urushima * @version 1.1 (09 May 2012) * @see 'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/ * @since 1.1 */ function ASN1HEX() { return ASN1HEX; } ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj; ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj; ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj; ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj; ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj; ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj; ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj; ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj; ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj; ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList; ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList; ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;