blob: da3b4b758aaa7341ed4b5571a890dfd788660b7e [file] [log] [blame]
Alexander Afanasyev181a8b92013-02-28 13:28:53 -08001/*! 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 */
39function _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 */
57function _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 */
80function _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 */
100function _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 */
115function _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 */
131function _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 */
147function _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 */
162function _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 */
195function _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 */
213function _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 */
233function _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 */
249function _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 */
264function ASN1HEX() {
265 return ASN1HEX;
266}
267
268ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj;
269ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj;
270ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj;
271ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj;
272ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj;
273ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj;
274ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj;
275ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj;
276ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj;
277ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
278ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
279ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;