зеркало из https://github.com/mozilla/gecko-dev.git
486 строки
17 KiB
JavaScript
486 строки
17 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
|
|
var WSP = {};
|
|
Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
|
|
var WBXML = {};
|
|
Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML);
|
|
|
|
Cu.import("resource://services-crypto/utils.js");
|
|
Cu.import("resource://services-common/utils.js");
|
|
|
|
// set to true to see debug messages
|
|
var DEBUG = WBXML.DEBUG_ALL | false;
|
|
|
|
/**
|
|
* Public identifier for CP
|
|
*
|
|
* @see http://technical.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.aspx
|
|
*/
|
|
const PUBLIC_IDENTIFIER_CP = "-//WAPFORUM//DTD PROV 1.0//EN";
|
|
|
|
this.PduHelper = {
|
|
|
|
/**
|
|
* @param data
|
|
* A wrapped object containing raw PDU data.
|
|
* @param contentType
|
|
* Content type of incoming CP message, should be "text/vnd.wap.connectivity-xml"
|
|
* or "application/vnd.wap.connectivity-wbxml".
|
|
*
|
|
* @return A message object containing attribute content and contentType.
|
|
* |content| will contain string of decoded CP message if successfully
|
|
* decoded, or raw data if failed.
|
|
* |contentType| will be string representing corresponding type of
|
|
* content.
|
|
*/
|
|
parse: function parse_cp(data, contentType) {
|
|
// We only need content and contentType
|
|
let msg = {
|
|
contentType: contentType
|
|
};
|
|
|
|
/**
|
|
* Message is compressed by WBXML, decode into string.
|
|
*
|
|
* @see WAP-192-WBXML-20010725-A
|
|
*/
|
|
if (contentType === "application/vnd.wap.connectivity-wbxml") {
|
|
let appToken = {
|
|
publicId: PUBLIC_IDENTIFIER_CP,
|
|
tagTokenList: CP_TAG_FIELDS,
|
|
attrTokenList: CP_ATTRIBUTE_FIELDS,
|
|
valueTokenList: CP_VALUE_FIELDS,
|
|
globalTokenOverride: null
|
|
}
|
|
|
|
try {
|
|
let parseResult = WBXML.PduHelper.parse(data, appToken, msg);
|
|
msg.content = parseResult.content;
|
|
msg.contentType = "text/vnd.wap.connectivity-xml";
|
|
} catch (e) {
|
|
// Provide raw data if we failed to parse.
|
|
msg.content = data.array;
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* Message is plain text, transform raw to string.
|
|
*/
|
|
try {
|
|
let stringData = WSP.Octet.decodeMultiple(data, data.array.length);
|
|
msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8");
|
|
} catch (e) {
|
|
// Provide raw data if we failed to parse.
|
|
msg.content = data.array;
|
|
}
|
|
return msg;
|
|
|
|
}
|
|
};
|
|
|
|
/**
|
|
* SEC type values
|
|
*
|
|
* @see WAP-183-ProvCont-20010724-A, clause 5.3
|
|
*/
|
|
const AUTH_SEC_TYPE = (function () {
|
|
let names = {};
|
|
function add(name, number) {
|
|
names[number] = name;
|
|
}
|
|
|
|
add("NETWPIN", 0);
|
|
add("USERPIN", 1);
|
|
add("USERNETWPIN", 2);
|
|
add("USERPINMAC", 3);
|
|
|
|
return names;
|
|
})();
|
|
|
|
this.Authenticator = {
|
|
/**
|
|
* Format IMSI string into GSM format
|
|
*
|
|
* @param imsi
|
|
* IMSI string
|
|
*
|
|
* @return IMSI in GSM format as string object
|
|
*/
|
|
formatImsi: function formatImsi(imsi) {
|
|
let parityByte = ((imsi.length & 1) ? 9 : 1);
|
|
|
|
// Make sure length of IMSI is 15 digits.
|
|
// @see GSM 11.11, clause 10.2.2
|
|
let i = 0;
|
|
for (i = 15 - imsi.length; i > 0; i--) {
|
|
imsi += "F";
|
|
}
|
|
|
|
// char-by-char atoi
|
|
let imsiValue = [];
|
|
imsiValue.push(parityByte);
|
|
for (i = 0; i < imsi.length; i++) {
|
|
imsiValue.push(parseInt(imsi.substr(i, 1), 10));
|
|
}
|
|
|
|
// encoded IMSI
|
|
let imsiEncoded = "";
|
|
for (i = 0; i < imsiValue.length; i += 2) {
|
|
imsiEncoded += String.fromCharCode(imsiValue[i] | (imsiValue[i+1] << 4));
|
|
}
|
|
|
|
return imsiEncoded;
|
|
},
|
|
|
|
/**
|
|
* Perform HMAC check
|
|
*
|
|
* @param wbxml
|
|
* Uint8 typed array of raw WBXML data.
|
|
* @param key
|
|
* key string for HMAC check.
|
|
* @param mac
|
|
* Expected MAC value.
|
|
*
|
|
* @return true for valid, false for invalid.
|
|
*/
|
|
isValid: function isValid(wbxml, key, mac) {
|
|
let hasher = CryptoUtils.makeHMACHasher(Ci.nsICryptoHMAC.SHA1,
|
|
CryptoUtils.makeHMACKey(key));
|
|
hasher.update(wbxml, wbxml.length);
|
|
let result = CommonUtils.bytesAsHex(hasher.finish(false)).toUpperCase();
|
|
return mac == result;
|
|
},
|
|
|
|
/**
|
|
* Perform HMAC authentication.
|
|
*
|
|
* @param wbxml
|
|
* Uint8 typed array of raw WBXML data.
|
|
* @param sec
|
|
* Security method for HMAC check.
|
|
* @param mac
|
|
* Expected MAC value.
|
|
* @param getNetworkPin
|
|
* Callback function for getting network pin.
|
|
*
|
|
* @return true for valid, false for invalid.
|
|
*/
|
|
check: function check_hmac(wbxml, sec, mac, getNetworkPin) {
|
|
// No security set.
|
|
if (sec == null || !mac) {
|
|
return null;
|
|
}
|
|
|
|
let authInfo = {
|
|
pass: false,
|
|
checked: false,
|
|
sec: AUTH_SEC_TYPE[sec],
|
|
mac: mac.toUpperCase(),
|
|
data: wbxml
|
|
};
|
|
|
|
switch (authInfo.sec) {
|
|
case "NETWPIN":
|
|
let key = getNetworkPin();
|
|
authInfo.pass = this.isValid(wbxml, key, authInfo.mac);
|
|
authInfo.checked = true;
|
|
return authInfo;
|
|
|
|
case "USERPIN":
|
|
case "USERPINMAC":
|
|
// We can't check without USER PIN
|
|
return authInfo;
|
|
|
|
case "USERNETWPIN":
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Tag tokens
|
|
*
|
|
* @see OMA-WAP-TS-ProvCont-V1_1-20090421-C, clause 7.1
|
|
*/
|
|
const CP_TAG_FIELDS = (function () {
|
|
let names = {};
|
|
function add(name, codepage, number) {
|
|
let entry = {
|
|
name: name,
|
|
number: number,
|
|
};
|
|
if (!names[codepage]) {
|
|
names[codepage] = {};
|
|
}
|
|
names[codepage][number] = entry;
|
|
}
|
|
|
|
// Code page 0
|
|
add("wap-provisioningdoc", 0, 0x05);
|
|
add("characteristic", 0, 0x06);
|
|
add("parm", 0, 0x07);
|
|
// Code page 1
|
|
add("characteristic", 1, 0x06);
|
|
add("parm", 1, 0x07);
|
|
|
|
return names;
|
|
})();
|
|
|
|
/**
|
|
* Attribute Tokens
|
|
*
|
|
* @see OMA-WAP-TS-ProvCont-V1_1-20090421-C, clause 7.2
|
|
*/
|
|
const CP_ATTRIBUTE_FIELDS = (function () {
|
|
let names = {};
|
|
function add(name, value, codepage, number) {
|
|
let entry = {
|
|
name: name,
|
|
value: value,
|
|
number: number,
|
|
};
|
|
if (!names[codepage]) {
|
|
names[codepage] = {};
|
|
}
|
|
names[codepage][number] = entry;
|
|
}
|
|
|
|
// Code page 0
|
|
add("name", "", 0, 0x05);
|
|
add("value", "", 0, 0x06);
|
|
add("name", "NAME", 0, 0x07);
|
|
add("name", "NAP-ADDRESS", 0, 0x08);
|
|
add("name", "NAP-ADDRTYPE", 0, 0x09);
|
|
add("name", "CALLTYPE", 0, 0x0A);
|
|
add("name", "VALIDUNTIL", 0, 0x0B);
|
|
add("name", "AUTHTYPE", 0, 0x0C);
|
|
add("name", "AUTHNAME", 0, 0x0D);
|
|
add("name", "AUTHSECRET", 0, 0x0E);
|
|
add("name", "LINGER", 0, 0x0F);
|
|
add("name", "BEARER", 0, 0x10);
|
|
add("name", "NAPID", 0, 0x11);
|
|
add("name", "COUNTRY", 0, 0x12);
|
|
add("name", "NETWORK", 0, 0x13);
|
|
add("name", "INTERNET", 0, 0x14);
|
|
add("name", "PROXY-ID", 0, 0x15);
|
|
add("name", "PROXY-PROVIDER-ID", 0, 0x16);
|
|
add("name", "DOMAIN", 0, 0x17);
|
|
add("name", "PROVURL", 0, 0x18);
|
|
add("name", "PXAUTH-TYPE", 0, 0x19);
|
|
add("name", "PXAUTH-ID", 0, 0x1A);
|
|
add("name", "PXAUTH-PW", 0, 0x1B);
|
|
add("name", "STARTPAGE", 0, 0x1C);
|
|
add("name", "BASAUTH-ID", 0, 0x1D);
|
|
add("name", "BASAUTH-PW", 0, 0x1E);
|
|
add("name", "PUSHENABLED", 0, 0x1F);
|
|
add("name", "PXADDR", 0, 0x20);
|
|
add("name", "PXADDRTYPE", 0, 0x21);
|
|
add("name", "TO-NAPID", 0, 0x22);
|
|
add("name", "PORTNBR", 0, 0x23);
|
|
add("name", "SERVICE", 0, 0x24);
|
|
add("name", "LINKSPEED", 0, 0x25);
|
|
add("name", "DNLINKSPEED", 0, 0x26);
|
|
add("name", "LOCAL-ADDR", 0, 0x27);
|
|
add("name", "LOCAL-ADDRTYPE", 0, 0x28);
|
|
add("name", "CONTEXT-ALLOW", 0, 0x29);
|
|
add("name", "TRUST", 0, 0x2A);
|
|
add("name", "MASTER", 0, 0x2B);
|
|
add("name", "SID", 0, 0x2C);
|
|
add("name", "SOC", 0, 0x2D);
|
|
add("name", "WSP-VERSION", 0, 0x2E);
|
|
add("name", "PHYSICAL-PROXY-ID", 0, 0x2F);
|
|
add("name", "CLIENT-ID", 0, 0x30);
|
|
add("name", "DELIVERY-ERR-PDU", 0, 0x31);
|
|
add("name", "DELIVERY-ORDER", 0, 0x32);
|
|
add("name", "TRAFFIC-CLASS", 0, 0x33);
|
|
add("name", "MAX-SDU-SIZE", 0, 0x34);
|
|
add("name", "MAX-BITRATE-UPLINK", 0, 0x35);
|
|
add("name", "MAX-BITRATE-DNLINK", 0, 0x36);
|
|
add("name", "RESIDUAL-BER", 0, 0x37);
|
|
add("name", "SDU-ERROR-RATIO", 0, 0x38);
|
|
add("name", "TRAFFIC-HANDL-PRIO", 0, 0x39);
|
|
add("name", "TRANSFER-DELAY", 0, 0x3A);
|
|
add("name", "GUARANTEED-BITRATE-UPLINK", 0, 0x3B);
|
|
add("name", "GUARANTEED-BITRATE-DNLINK", 0, 0x3C);
|
|
add("name", "PXADDR-FQDN", 0, 0x3D);
|
|
add("name", "PROXY-PW", 0, 0x3E);
|
|
add("name", "PPGAUTH-TYPE", 0, 0x3F);
|
|
add("version", "", 0, 0x45);
|
|
add("version", "1.0", 0, 0x46);
|
|
add("name", "PULLENABLED", 0, 0x47);
|
|
add("name", "DNS-ADDR", 0, 0x48);
|
|
add("name", "MAX-NUM-RETRY", 0, 0x49);
|
|
add("name", "FIRST-RETRY-TIMEOUT", 0, 0x4A);
|
|
add("name", "REREG-THRESHOLD", 0, 0x4B);
|
|
add("name", "T-BIT", 0, 0x4C);
|
|
add("name", "AUTH-ENTITY", 0, 0x4E);
|
|
add("name", "SPI", 0, 0x4F);
|
|
add("type", "", 0, 0x50);
|
|
add("type", "PXLOGICAL", 0, 0x51);
|
|
add("type", "PXPHYSICAL", 0, 0x52);
|
|
add("type", "PORT", 0, 0x53);
|
|
add("type", "VALIDITY", 0, 0x54);
|
|
add("type", "NAPDEF", 0, 0x55);
|
|
add("type", "BOOTSTRAP", 0, 0x56);
|
|
/*
|
|
* Mark out VENDORCONFIG so if it is contained in message, parse
|
|
* will failed and raw data is returned.
|
|
*/
|
|
// add("type", "VENDORCONFIG", 0, 0x57);
|
|
add("type", "CLIENTIDENTITY", 0, 0x58);
|
|
add("type", "PXAUTHINFO", 0, 0x59);
|
|
add("type", "NAPAUTHINFO", 0, 0x5A);
|
|
add("type", "ACCESS", 0, 0x5B);
|
|
|
|
// Code page 1
|
|
add("name", "", 1, 0x05);
|
|
add("value", "", 1, 0x06);
|
|
add("name", "NAME", 1, 0x07);
|
|
add("name", "INTERNET", 1, 0x14);
|
|
add("name", "STARTPAGE", 1, 0x1C);
|
|
add("name", "TO-NAPID", 1, 0x22);
|
|
add("name", "PORTNBR", 1, 0x23);
|
|
add("name", "SERVICE", 1, 0x24);
|
|
add("name", "AACCEPT", 1, 0x2E);
|
|
add("name", "AAUTHDATA", 1, 0x2F);
|
|
add("name", "AAUTHLEVEL", 1, 0x30);
|
|
add("name", "AAUTHNAME", 1, 0x31);
|
|
add("name", "AAUTHSECRET", 1, 0x32);
|
|
add("name", "AAUTHTYPE", 1, 0x33);
|
|
add("name", "ADDR", 1, 0x34);
|
|
add("name", "ADDRTYPE", 1, 0x35);
|
|
add("name", "APPID", 1, 0x36);
|
|
add("name", "APROTOCOL", 1, 0x37);
|
|
add("name", "PROVIDER-ID", 1, 0x38);
|
|
add("name", "TO-PROXY", 1, 0x39);
|
|
add("name", "URI", 1, 0x3A);
|
|
add("name", "RULE", 1, 0x3B);
|
|
add("type", "", 1, 0x50);
|
|
add("type", "PORT", 1, 0x53);
|
|
add("type", "APPLICATION", 1, 0x55);
|
|
add("type", "APPADDR", 1, 0x56);
|
|
add("type", "APPAUTH", 1, 0x57);
|
|
add("type", "CLIENTIDENTITY", 1, 0x58);
|
|
add("type", "RESOURCE", 1, 0x59);
|
|
|
|
return names;
|
|
})();
|
|
|
|
/**
|
|
* Value Tokens
|
|
*
|
|
* @see OMA-WAP-TS-ProvCont-V1_1-20090421-C, clause 7.3
|
|
*/
|
|
const CP_VALUE_FIELDS = (function () {
|
|
let names = {};
|
|
function add(value, codepage, number) {
|
|
let entry = {
|
|
value: value,
|
|
number: number,
|
|
};
|
|
if (!names[codepage]) {
|
|
names[codepage] = {};
|
|
}
|
|
names[codepage][number] = entry;
|
|
}
|
|
|
|
// Code page 0
|
|
add("IPV4", 0, 0x85);
|
|
add("IPV6", 0, 0x86);
|
|
add("E164", 0, 0x87);
|
|
add("ALPHA", 0, 0x88);
|
|
add("APN", 0, 0x89);
|
|
add("SCODE", 0, 0x8A);
|
|
add("TETRA-ITSI", 0, 0x8B);
|
|
add("MAN", 0, 0x8C);
|
|
add("ANALOG-MODEM", 0, 0x90);
|
|
add("V.120", 0, 0x91);
|
|
add("V.110", 0, 0x92);
|
|
add("X.31", 0, 0x93);
|
|
add("BIT-TRANSPARENT", 0, 0x94);
|
|
add("DIRECT-ASYNCHRONOUS-DATA-SERVICE", 0, 0x95);
|
|
add("PAP", 0, 0x9A);
|
|
add("CHAP", 0, 0x9B);
|
|
add("HTTP-BASIC", 0, 0x9C);
|
|
add("HTTP-DIGEST", 0, 0x9D);
|
|
add("WTLS-SS", 0, 0x9E);
|
|
add("MD5", 0, 0x9F); // Added in OMA, 7.3.3
|
|
add("GSM-USSD", 0, 0xA2);
|
|
add("GSM-SMS", 0, 0xA3);
|
|
add("ANSI-136-GUTS", 0, 0xA4);
|
|
add("IS-95-CDMA-SMS", 0, 0xA5);
|
|
add("IS-95-CDMA-CSD", 0, 0xA6);
|
|
add("IS-95-CDMA-PAC", 0, 0xA7);
|
|
add("ANSI-136-CSD", 0, 0xA8);
|
|
add("ANSI-136-GPRS", 0, 0xA9);
|
|
add("GSM-CSD", 0, 0xAA);
|
|
add("GSM-GPRS", 0, 0xAB);
|
|
add("AMPS-CDPD", 0, 0xAC);
|
|
add("PDC-CSD", 0, 0xAD);
|
|
add("PDC-PACKET", 0, 0xAE);
|
|
add("IDEN-SMS", 0, 0xAF);
|
|
add("IDEN-CSD", 0, 0xB0);
|
|
add("IDEN-PACKET", 0, 0xB1);
|
|
add("FLEX/REFLEX", 0, 0xB2);
|
|
add("PHS-SMS", 0, 0xB3);
|
|
add("PHS-CSD", 0, 0xB4);
|
|
add("TETRA-SDS", 0, 0xB5);
|
|
add("TETRA-PACKET", 0, 0xB6);
|
|
add("ANSI-136-GHOST", 0, 0xB7);
|
|
add("MOBITEX-MPAK", 0, 0xB8);
|
|
add("CDMA2000-1X-SIMPLE-IP", 0, 0xB9); // Added in OMA, 7.3.4
|
|
add("CDMA2000-1X-MOBILE-IP", 0, 0xBA); // Added in OMA, 7.3.4
|
|
add("AUTOBOUDING", 0, 0xC5);
|
|
add("CL-WSP", 0, 0xCA);
|
|
add("CO-WSP", 0, 0xCB);
|
|
add("CL-SEC-WSP", 0, 0xCC);
|
|
add("CO-SEC-WSP", 0, 0xCD);
|
|
add("CL-SEC-WTA", 0, 0xCE);
|
|
add("CO-SEC-WTA", 0, 0xCF);
|
|
add("OTA-HTTP-TO", 0, 0xD0); // Added in OMA, 7.3.6
|
|
add("OTA-HTTP-TLS-TO", 0, 0xD1); // Added in OMA, 7.3.6
|
|
add("OTA-HTTP-PO", 0, 0xD2); // Added in OMA, 7.3.6
|
|
add("OTA-HTTP-TLS-PO", 0, 0xD3); // Added in OMA, 7.3.6
|
|
add("AAA", 0, 0xE0); // Added in OMA, 7.3.8
|
|
add("HA", 0, 0xE1); // Added in OMA, 7.3.8
|
|
|
|
// Code page 1
|
|
add("IPV6", 1, 0x86);
|
|
add("E164", 1, 0x87);
|
|
add("ALPHA", 1, 0x88);
|
|
add("APPSRV", 1, 0x8D);
|
|
add("OBEX", 1, 0x8E);
|
|
add(",", 1, 0x90);
|
|
add("HTTP-", 1, 0x91);
|
|
add("BASIC", 1, 0x92);
|
|
add("DIGEST", 1, 0x93);
|
|
|
|
return names;
|
|
})();
|
|
|
|
var debug;
|
|
if (DEBUG) {
|
|
debug = function (s) {
|
|
dump("-$- CpPduHelper: " + s + "\n");
|
|
};
|
|
} else {
|
|
debug = function (s) {};
|
|
}
|
|
|
|
this.EXPORTED_SYMBOLS = [
|
|
// Parser
|
|
"PduHelper",
|
|
// HMAC Authenticator
|
|
"Authenticator",
|
|
];
|