diff options
Diffstat (limited to 'crypto/asn1hex.js')
| -rw-r--r-- | crypto/asn1hex.js | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/crypto/asn1hex.js b/crypto/asn1hex.js new file mode 100644 index 0000000..15987bc --- /dev/null +++ b/crypto/asn1hex.js @@ -0,0 +1,106 @@ +// +// asn1hex.js - Hexadecimal represented ASN.1 string library +// +// +// version: 1.0 (2010-Jun-03) +// +// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) +// +// This software is licensed under the terms of the MIT License. +// http://www.opensource.org/licenses/mit-license.php +// +// 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 ...) +// - +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 +} + +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 +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'. +// +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; +} + +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); +} + +function _asnhex_getPosOfNextSibling_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return pos1 + len * 2; +} + +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; +} |
