Skip to content

Instantly share code, notes, and snippets.

@Freundschaft
Created November 30, 2016 17:47
Show Gist options
  • Save Freundschaft/479556f0d98438ae4305e41e66f02291 to your computer and use it in GitHub Desktop.
Save Freundschaft/479556f0d98438ae4305e41e66f02291 to your computer and use it in GitHub Desktop.
NfcWifiProtectedSetup created by Freundschaft - https://repl.it/E4HO/63
//parsing according to https://android.googlesource.com/platform/packages/apps/Nfc/+/master/src/com/android/nfc/NfcWifiProtectedSetup.java
//additions according to WIFi Alliance Wi-Fi Protected Setup Specification
//sample payload
var u8 = new Uint8Array([16,14,0,62,16,38,0,1,1,16,69,0,11,87,76,65,78,45,56,50,67,81,90,54,16,3,0,2,0,34,16,15,0,2,0,12,16,39,0,16,52,57,53,54,52,52,53,54,56,48,51,57,48,50,54,51,16,32,0,6,-1,-1,-1,-1,-1,-1]);
function bin2string(array){
var result = "";
for(var i = 0; i < array.length; ++i){
result+= (String.fromCharCode(array[i]));
}
return result;
}
const CREDENTIAL_FIELD_ID = parseInt('0x100E', 16);
const SSID_FIELD_ID = parseInt('0x1045', 16);
const NETWORK_KEY_FIELD_ID = parseInt('0x1027', 16);
const AUTH_TYPE_FIELD_ID = parseInt('0x1003', 16);
const NETWORK_INDEX_ID = parseInt('0x1026', 16);
const ENCRYPTION_TYPE_ID = parseInt('0x100F', 16);
const MAC_ADDRESS_ID = parseInt('0x1020', 16);
const AUTH_TYPE_OPEN = 0;
const AUTH_TYPE_WPA_PSK = parseInt('0x0002', 16);
const AUTH_TYPE_WPA_EAP = parseInt('0x0008', 16);
const AUTH_TYPE_WPA2_EAP = parseInt('0x0010', 16);
const AUTH_TYPE_WPA2_PSK = parseInt('0x0020', 16);
const AUTH_TYPE_EXPECTED_SIZE = 2;
var position = 0;
var dv = new DataView(u8.buffer);
var fieldId = dv.getUint16(position);
position = position + 2;
var fieldSize = dv.getUint16(position) & 65535;
position = position + 2;
parseCredential(dv, fieldSize, position);
function parseCredential(payload, size, position){
var result = {};
var startPosition = position;
while (position < startPosition + size) {
var fieldId = payload.getUint16(position);
position = position + 2;
var fieldSize = payload.getUint16(position) & 65535;
position = position + 2;
// sanity check
if (position + fieldSize > startPosition + size) {
return null;
}
switch (fieldId){
case SSID_FIELD_ID:
result.ssid = bin2string(u8.slice(position, position + fieldSize));
console.log('ssid: ' + result.ssid);
break;
case NETWORK_KEY_FIELD_ID:
result.preSharedKey = bin2string(u8.slice(position, position + fieldSize));
console.log('sharedkey: ' + result.preSharedKey);
break;
case AUTH_TYPE_FIELD_ID:
if (fieldSize != AUTH_TYPE_EXPECTED_SIZE) {
// corrupt data
console.log('corrupt data');
return null;
}
// BITWISE OR CHECK console.log(AUTH_TYPE_WPA_PSK | AUTH_TYPE_WPA2_PSK)
var authType = payload.getUint16(position);
if (authType & AUTH_TYPE_WPA_PSK || authType & AUTH_TYPE_WPA2_PSK) {
result.authType = 'WPA_PSK';
} else if (authType & AUTH_TYPE_WPA_EAP || authType & AUTH_TYPE_WPA2_EAP) {
result.authType = 'WPA_EAP';
} else if (authType & AUTH_TYPE_OPEN) {
result.authType = 'NONE';
}
console.log('authtype: ' + result.authType);
break;
case NETWORK_INDEX_ID:
var networkIndexId = payload.getUint8(position);
console.log('networkIndexId: ' + networkIndexId);
break;
case ENCRYPTION_TYPE_ID:
var encryptionTypeId = payload.getUint16(position);
console.log('encryptionTypeId: ' + encryptionTypeId);
break;
case MAC_ADDRESS_ID:
var macAddressId = u8.slice(position, position + fieldSize);
console.log('macAddressId: ' + macAddressId.reduce(function(a, b){
return a.toString(16) + ':' + b.toString(16);
}));
break;
default:
// unknown
console.log(fieldId + ': fieldsize is ' + fieldSize);
break;
}
position = position + fieldSize;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment