/*! 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; |