Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
9 let WSP = {};
10 Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
11 let WBXML = {};
12 Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML);
14 Cu.import("resource://services-crypto/utils.js");
15 Cu.import("resource://services-common/utils.js");
17 // set to true to see debug messages
18 let DEBUG = WBXML.DEBUG_ALL | false;
20 /**
21 * Public identifier for CP
22 *
23 * @see http://technical.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.aspx
24 */
25 const PUBLIC_IDENTIFIER_CP = "-//WAPFORUM//DTD PROV 1.0//EN";
27 this.PduHelper = {
29 /**
30 * @param data
31 * A wrapped object containing raw PDU data.
32 * @param contentType
33 * Content type of incoming CP message, should be "text/vnd.wap.connectivity-xml"
34 * or "application/vnd.wap.connectivity-wbxml".
35 *
36 * @return A message object containing attribute content and contentType.
37 * |content| will contain string of decoded CP message if successfully
38 * decoded, or raw data if failed.
39 * |contentType| will be string representing corresponding type of
40 * content.
41 */
42 parse: function parse_cp(data, contentType) {
43 // We only need content and contentType
44 let msg = {
45 contentType: contentType
46 };
48 /**
49 * Message is compressed by WBXML, decode into string.
50 *
51 * @see WAP-192-WBXML-20010725-A
52 */
53 if (contentType === "application/vnd.wap.connectivity-wbxml") {
54 let appToken = {
55 publicId: PUBLIC_IDENTIFIER_CP,
56 tagTokenList: CP_TAG_FIELDS,
57 attrTokenList: CP_ATTRIBUTE_FIELDS,
58 valueTokenList: CP_VALUE_FIELDS,
59 globalTokenOverride: null
60 }
62 try {
63 let parseResult = WBXML.PduHelper.parse(data, appToken, msg);
64 msg.content = parseResult.content;
65 msg.contentType = "text/vnd.wap.connectivity-xml";
66 } catch (e) {
67 // Provide raw data if we failed to parse.
68 msg.content = data.array;
69 }
71 return msg;
72 }
74 /**
75 * Message is plain text, transform raw to string.
76 */
77 try {
78 let stringData = WSP.Octet.decodeMultiple(data, data.array.length);
79 msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8");
80 } catch (e) {
81 // Provide raw data if we failed to parse.
82 msg.content = data.array;
83 }
84 return msg;
86 }
87 };
89 /**
90 * SEC type values
91 *
92 * @see WAP-183-ProvCont-20010724-A, clause 5.3
93 */
94 const AUTH_SEC_TYPE = (function () {
95 let names = {};
96 function add(name, number) {
97 names[number] = name;
98 }
100 add("NETWPIN", 0);
101 add("USERPIN", 1);
102 add("USERNETWPIN", 2);
103 add("USERPINMAC", 3);
105 return names;
106 })();
108 this.Authenticator = {
109 /**
110 * Format IMSI string into GSM format
111 *
112 * @param imsi
113 * IMSI string
114 *
115 * @return IMSI in GSM format as string object
116 */
117 formatImsi: function formatImsi(imsi) {
118 let parityByte = ((imsi.length & 1) ? 9 : 1);
120 // Make sure length of IMSI is 15 digits.
121 // @see GSM 11.11, clause 10.2.2
122 let i = 0;
123 for (i = 15 - imsi.length; i > 0; i--) {
124 imsi += "F";
125 }
127 // char-by-char atoi
128 let imsiValue = [];
129 imsiValue.push(parityByte);
130 for (i = 0; i < imsi.length; i++) {
131 imsiValue.push(parseInt(imsi.substr(i, 1), 10));
132 }
134 // encoded IMSI
135 let imsiEncoded = "";
136 for (i = 0; i < imsiValue.length; i += 2) {
137 imsiEncoded += String.fromCharCode(imsiValue[i] | (imsiValue[i+1] << 4));
138 }
140 return imsiEncoded;
141 },
143 /**
144 * Perform HMAC check
145 *
146 * @param wbxml
147 * Uint8 typed array of raw WBXML data.
148 * @param key
149 * key string for HMAC check.
150 * @param mac
151 * Expected MAC value.
152 *
153 * @return true for valid, false for invalid.
154 */
155 isValid: function isValid(wbxml, key, mac) {
156 let hasher = CryptoUtils.makeHMACHasher(Ci.nsICryptoHMAC.SHA1,
157 CryptoUtils.makeHMACKey(key));
158 hasher.update(wbxml, wbxml.length);
159 let result = CommonUtils.bytesAsHex(hasher.finish(false)).toUpperCase();
160 return mac == result;
161 },
163 /**
164 * Perform HMAC authentication.
165 *
166 * @param wbxml
167 * Uint8 typed array of raw WBXML data.
168 * @param sec
169 * Security method for HMAC check.
170 * @param mac
171 * Expected MAC value.
172 * @param getNetworkPin
173 * Callback function for getting network pin.
174 *
175 * @return true for valid, false for invalid.
176 */
177 check: function check_hmac(wbxml, sec, mac, getNetworkPin) {
178 // No security set.
179 if (sec == null || !mac) {
180 return null;
181 }
183 let authInfo = {
184 pass: false,
185 checked: false,
186 sec: AUTH_SEC_TYPE[sec],
187 mac: mac.toUpperCase(),
188 data: wbxml
189 };
191 switch (authInfo.sec) {
192 case "NETWPIN":
193 let key = getNetworkPin();
194 authInfo.pass = this.isValid(wbxml, key, authInfo.mac);
195 authInfo.checked = true;
196 return authInfo;
198 case "USERPIN":
199 case "USERPINMAC":
200 // We can't check without USER PIN
201 return authInfo;
203 case "USERNETWPIN":
204 default:
205 return null;
206 }
207 }
208 };
210 /**
211 * Tag tokens
212 *
213 * @see OMA-WAP-TS-ProvCont-V1_1-20090421-C, clause 7.1
214 */
215 const CP_TAG_FIELDS = (function () {
216 let names = {};
217 function add(name, codepage, number) {
218 let entry = {
219 name: name,
220 number: number,
221 };
222 if (!names[codepage]) {
223 names[codepage] = {};
224 }
225 names[codepage][number] = entry;
226 }
228 // Code page 0
229 add("wap-provisioningdoc", 0, 0x05);
230 add("characteristic", 0, 0x06);
231 add("parm", 0, 0x07);
232 // Code page 1
233 add("characteristic", 1, 0x06);
234 add("parm", 1, 0x07);
236 return names;
237 })();
239 /**
240 * Attribute Tokens
241 *
242 * @see OMA-WAP-TS-ProvCont-V1_1-20090421-C, clause 7.2
243 */
244 const CP_ATTRIBUTE_FIELDS = (function () {
245 let names = {};
246 function add(name, value, codepage, number) {
247 let entry = {
248 name: name,
249 value: value,
250 number: number,
251 };
252 if (!names[codepage]) {
253 names[codepage] = {};
254 }
255 names[codepage][number] = entry;
256 }
258 // Code page 0
259 add("name", "", 0, 0x05);
260 add("value", "", 0, 0x06);
261 add("name", "NAME", 0, 0x07);
262 add("name", "NAP-ADDRESS", 0, 0x08);
263 add("name", "NAP-ADDRTYPE", 0, 0x09);
264 add("name", "CALLTYPE", 0, 0x0A);
265 add("name", "VALIDUNTIL", 0, 0x0B);
266 add("name", "AUTHTYPE", 0, 0x0C);
267 add("name", "AUTHNAME", 0, 0x0D);
268 add("name", "AUTHSECRET", 0, 0x0E);
269 add("name", "LINGER", 0, 0x0F);
270 add("name", "BEARER", 0, 0x10);
271 add("name", "NAPID", 0, 0x11);
272 add("name", "COUNTRY", 0, 0x12);
273 add("name", "NETWORK", 0, 0x13);
274 add("name", "INTERNET", 0, 0x14);
275 add("name", "PROXY-ID", 0, 0x15);
276 add("name", "PROXY-PROVIDER-ID", 0, 0x16);
277 add("name", "DOMAIN", 0, 0x17);
278 add("name", "PROVURL", 0, 0x18);
279 add("name", "PXAUTH-TYPE", 0, 0x19);
280 add("name", "PXAUTH-ID", 0, 0x1A);
281 add("name", "PXAUTH-PW", 0, 0x1B);
282 add("name", "STARTPAGE", 0, 0x1C);
283 add("name", "BASAUTH-ID", 0, 0x1D);
284 add("name", "BASAUTH-PW", 0, 0x1E);
285 add("name", "PUSHENABLED", 0, 0x1F);
286 add("name", "PXADDR", 0, 0x20);
287 add("name", "PXADDRTYPE", 0, 0x21);
288 add("name", "TO-NAPID", 0, 0x22);
289 add("name", "PORTNBR", 0, 0x23);
290 add("name", "SERVICE", 0, 0x24);
291 add("name", "LINKSPEED", 0, 0x25);
292 add("name", "DNLINKSPEED", 0, 0x26);
293 add("name", "LOCAL-ADDR", 0, 0x27);
294 add("name", "LOCAL-ADDRTYPE", 0, 0x28);
295 add("name", "CONTEXT-ALLOW", 0, 0x29);
296 add("name", "TRUST", 0, 0x2A);
297 add("name", "MASTER", 0, 0x2B);
298 add("name", "SID", 0, 0x2C);
299 add("name", "SOC", 0, 0x2D);
300 add("name", "WSP-VERSION", 0, 0x2E);
301 add("name", "PHYSICAL-PROXY-ID", 0, 0x2F);
302 add("name", "CLIENT-ID", 0, 0x30);
303 add("name", "DELIVERY-ERR-PDU", 0, 0x31);
304 add("name", "DELIVERY-ORDER", 0, 0x32);
305 add("name", "TRAFFIC-CLASS", 0, 0x33);
306 add("name", "MAX-SDU-SIZE", 0, 0x34);
307 add("name", "MAX-BITRATE-UPLINK", 0, 0x35);
308 add("name", "MAX-BITRATE-DNLINK", 0, 0x36);
309 add("name", "RESIDUAL-BER", 0, 0x37);
310 add("name", "SDU-ERROR-RATIO", 0, 0x38);
311 add("name", "TRAFFIC-HANDL-PRIO", 0, 0x39);
312 add("name", "TRANSFER-DELAY", 0, 0x3A);
313 add("name", "GUARANTEED-BITRATE-UPLINK", 0, 0x3B);
314 add("name", "GUARANTEED-BITRATE-DNLINK", 0, 0x3C);
315 add("name", "PXADDR-FQDN", 0, 0x3D);
316 add("name", "PROXY-PW", 0, 0x3E);
317 add("name", "PPGAUTH-TYPE", 0, 0x3F);
318 add("version", "", 0, 0x45);
319 add("version", "1.0", 0, 0x46);
320 add("name", "PULLENABLED", 0, 0x47);
321 add("name", "DNS-ADDR", 0, 0x48);
322 add("name", "MAX-NUM-RETRY", 0, 0x49);
323 add("name", "FIRST-RETRY-TIMEOUT", 0, 0x4A);
324 add("name", "REREG-THRESHOLD", 0, 0x4B);
325 add("name", "T-BIT", 0, 0x4C);
326 add("name", "AUTH-ENTITY", 0, 0x4E);
327 add("name", "SPI", 0, 0x4F);
328 add("type", "", 0, 0x50);
329 add("type", "PXLOGICAL", 0, 0x51);
330 add("type", "PXPHYSICAL", 0, 0x52);
331 add("type", "PORT", 0, 0x53);
332 add("type", "VALIDITY", 0, 0x54);
333 add("type", "NAPDEF", 0, 0x55);
334 add("type", "BOOTSTRAP", 0, 0x56);
335 /*
336 * Mark out VENDORCONFIG so if it is contained in message, parse
337 * will failed and raw data is returned.
338 */
339 // add("type", "VENDORCONFIG", 0, 0x57);
340 add("type", "CLIENTIDENTITY", 0, 0x58);
341 add("type", "PXAUTHINFO", 0, 0x59);
342 add("type", "NAPAUTHINFO", 0, 0x5A);
343 add("type", "ACCESS", 0, 0x5B);
345 // Code page 1
346 add("name", "", 1, 0x05);
347 add("value", "", 1, 0x06);
348 add("name", "NAME", 1, 0x07);
349 add("name", "INTERNET", 1, 0x14);
350 add("name", "STARTPAGE", 1, 0x1C);
351 add("name", "TO-NAPID", 1, 0x22);
352 add("name", "PORTNBR", 1, 0x23);
353 add("name", "SERVICE", 1, 0x24);
354 add("name", "AACCEPT", 1, 0x2E);
355 add("name", "AAUTHDATA", 1, 0x2F);
356 add("name", "AAUTHLEVEL", 1, 0x30);
357 add("name", "AAUTHNAME", 1, 0x31);
358 add("name", "AAUTHSECRET", 1, 0x32);
359 add("name", "AAUTHTYPE", 1, 0x33);
360 add("name", "ADDR", 1, 0x34);
361 add("name", "ADDRTYPE", 1, 0x35);
362 add("name", "APPID", 1, 0x36);
363 add("name", "APROTOCOL", 1, 0x37);
364 add("name", "PROVIDER-ID", 1, 0x38);
365 add("name", "TO-PROXY", 1, 0x39);
366 add("name", "URI", 1, 0x3A);
367 add("name", "RULE", 1, 0x3B);
368 add("type", "", 1, 0x50);
369 add("type", "PORT", 1, 0x53);
370 add("type", "APPLICATION", 1, 0x55);
371 add("type", "APPADDR", 1, 0x56);
372 add("type", "APPAUTH", 1, 0x57);
373 add("type", "CLIENTIDENTITY", 1, 0x58);
374 add("type", "RESOURCE", 1, 0x59);
376 return names;
377 })();
379 /**
380 * Value Tokens
381 *
382 * @see OMA-WAP-TS-ProvCont-V1_1-20090421-C, clause 7.3
383 */
384 const CP_VALUE_FIELDS = (function () {
385 let names = {};
386 function add(value, codepage, number) {
387 let entry = {
388 value: value,
389 number: number,
390 };
391 if (!names[codepage]) {
392 names[codepage] = {};
393 }
394 names[codepage][number] = entry;
395 }
397 // Code page 0
398 add("IPV4", 0, 0x85);
399 add("IPV6", 0, 0x86);
400 add("E164", 0, 0x87);
401 add("ALPHA", 0, 0x88);
402 add("APN", 0, 0x89);
403 add("SCODE", 0, 0x8A);
404 add("TETRA-ITSI", 0, 0x8B);
405 add("MAN", 0, 0x8C);
406 add("ANALOG-MODEM", 0, 0x90);
407 add("V.120", 0, 0x91);
408 add("V.110", 0, 0x92);
409 add("X.31", 0, 0x93);
410 add("BIT-TRANSPARENT", 0, 0x94);
411 add("DIRECT-ASYNCHRONOUS-DATA-SERVICE", 0, 0x95);
412 add("PAP", 0, 0x9A);
413 add("CHAP", 0, 0x9B);
414 add("HTTP-BASIC", 0, 0x9C);
415 add("HTTP-DIGEST", 0, 0x9D);
416 add("WTLS-SS", 0, 0x9E);
417 add("MD5", 0, 0x9F); // Added in OMA, 7.3.3
418 add("GSM-USSD", 0, 0xA2);
419 add("GSM-SMS", 0, 0xA3);
420 add("ANSI-136-GUTS", 0, 0xA4);
421 add("IS-95-CDMA-SMS", 0, 0xA5);
422 add("IS-95-CDMA-CSD", 0, 0xA6);
423 add("IS-95-CDMA-PAC", 0, 0xA7);
424 add("ANSI-136-CSD", 0, 0xA8);
425 add("ANSI-136-GPRS", 0, 0xA9);
426 add("GSM-CSD", 0, 0xAA);
427 add("GSM-GPRS", 0, 0xAB);
428 add("AMPS-CDPD", 0, 0xAC);
429 add("PDC-CSD", 0, 0xAD);
430 add("PDC-PACKET", 0, 0xAE);
431 add("IDEN-SMS", 0, 0xAF);
432 add("IDEN-CSD", 0, 0xB0);
433 add("IDEN-PACKET", 0, 0xB1);
434 add("FLEX/REFLEX", 0, 0xB2);
435 add("PHS-SMS", 0, 0xB3);
436 add("PHS-CSD", 0, 0xB4);
437 add("TETRA-SDS", 0, 0xB5);
438 add("TETRA-PACKET", 0, 0xB6);
439 add("ANSI-136-GHOST", 0, 0xB7);
440 add("MOBITEX-MPAK", 0, 0xB8);
441 add("CDMA2000-1X-SIMPLE-IP", 0, 0xB9); // Added in OMA, 7.3.4
442 add("CDMA2000-1X-MOBILE-IP", 0, 0xBA); // Added in OMA, 7.3.4
443 add("AUTOBOUDING", 0, 0xC5);
444 add("CL-WSP", 0, 0xCA);
445 add("CO-WSP", 0, 0xCB);
446 add("CL-SEC-WSP", 0, 0xCC);
447 add("CO-SEC-WSP", 0, 0xCD);
448 add("CL-SEC-WTA", 0, 0xCE);
449 add("CO-SEC-WTA", 0, 0xCF);
450 add("OTA-HTTP-TO", 0, 0xD0); // Added in OMA, 7.3.6
451 add("OTA-HTTP-TLS-TO", 0, 0xD1); // Added in OMA, 7.3.6
452 add("OTA-HTTP-PO", 0, 0xD2); // Added in OMA, 7.3.6
453 add("OTA-HTTP-TLS-PO", 0, 0xD3); // Added in OMA, 7.3.6
454 add("AAA", 0, 0xE0); // Added in OMA, 7.3.8
455 add("HA", 0, 0xE1); // Added in OMA, 7.3.8
457 // Code page 1
458 add("IPV6", 1, 0x86);
459 add("E164", 1, 0x87);
460 add("ALPHA", 1, 0x88);
461 add("APPSRV", 1, 0x8D);
462 add("OBEX", 1, 0x8E);
463 add(",", 1, 0x90);
464 add("HTTP-", 1, 0x91);
465 add("BASIC", 1, 0x92);
466 add("DIGEST", 1, 0x93);
468 return names;
469 })();
471 let debug;
472 if (DEBUG) {
473 debug = function (s) {
474 dump("-$- CpPduHelper: " + s + "\n");
475 };
476 } else {
477 debug = function (s) {};
478 }
480 this.EXPORTED_SYMBOLS = [
481 // Parser
482 "PduHelper",
483 // HMAC Authenticator
484 "Authenticator",
485 ];