Bug 914685 - 0001. Support GSM network pin authentication. r=vicamo

This commit is contained in:
Chuck Lee 2013-10-14 14:47:50 +08:00
Родитель c5a7bf0e88
Коммит 97b8dbde89
2 изменённых файлов: 145 добавлений и 1 удалений

Просмотреть файл

@ -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
});
},