| /*! 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 <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a> |
| * @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; |