зеркало из https://github.com/mozilla/gecko-dev.git
Bug 914685 - 0001. Support GSM network pin authentication. r=vicamo
This commit is contained in:
Родитель
c5a7bf0e88
Коммит
97b8dbde89
|
@ -11,6 +11,9 @@ Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
|
|||
let 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
|
||||
let DEBUG = WBXML.DEBUG_ALL | false;
|
||||
|
||||
|
@ -83,6 +86,128 @@ this.PduHelper = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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(),
|
||||
dataLength: wbxml.length,
|
||||
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
|
||||
*
|
||||
|
@ -347,4 +472,6 @@ if (DEBUG) {
|
|||
this.EXPORTED_SYMBOLS = [
|
||||
// Parser
|
||||
"PduHelper",
|
||||
// HMAC Authenticator
|
||||
"Authenticator",
|
||||
];
|
||||
|
|
|
@ -37,6 +37,9 @@ XPCOMUtils.defineLazyGetter(this, "CP", function () {
|
|||
XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
|
||||
"@mozilla.org/system-message-internal;1",
|
||||
"nsISystemMessagesInternal");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gRIL",
|
||||
"@mozilla.org/ril;1",
|
||||
"nsIRadioInterfaceLayer");
|
||||
|
||||
/**
|
||||
* Helpers for WAP PDU processing.
|
||||
|
@ -91,6 +94,7 @@ this.WapPushManager = {
|
|||
*/
|
||||
let contentType = options.headers["content-type"].media;
|
||||
let msg;
|
||||
let authInfo = null;
|
||||
|
||||
if (contentType === "text/vnd.wap.si" ||
|
||||
contentType === "application/vnd.wap.sic") {
|
||||
|
@ -100,6 +104,18 @@ this.WapPushManager = {
|
|||
msg = SL.PduHelper.parse(data, contentType);
|
||||
} else if (contentType === "text/vnd.wap.connectivity-xml" ||
|
||||
contentType === "application/vnd.wap.connectivity-wbxml") {
|
||||
// Apply HMAC authentication on WBXML encoded CP message.
|
||||
if (contentType === "application/vnd.wap.connectivity-wbxml") {
|
||||
let params = options.headers["content-type"].params;
|
||||
let sec = params && params.sec;
|
||||
let mac = params && params.mac;
|
||||
authInfo = CP.Authenticator.check(data.array.subarray(data.offset),
|
||||
sec, mac, function getNetworkPin() {
|
||||
let imsi = gRIL.getRadioInterface(0).rilContext.imsi;
|
||||
return CP.Authenticator.formatImsi(imsi);
|
||||
});
|
||||
}
|
||||
|
||||
msg = CP.PduHelper.parse(data, contentType);
|
||||
} else {
|
||||
// Unsupported type, provide raw data.
|
||||
|
@ -118,7 +134,8 @@ this.WapPushManager = {
|
|||
gSystemMessenger.broadcastMessage("wappush-received", {
|
||||
sender: sender,
|
||||
contentType: msg.contentType,
|
||||
content: msg.content
|
||||
content: msg.content,
|
||||
authInfo: authInfo
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче