/*
* This file is part of Sensorium.
*
* Sensorium is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sensorium is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Sensorium. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
package at.univie.sensorium.privacy;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import android.util.Base64;
import android.util.Log;
import at.univie.sensorium.SensorRegistry;
import at.univie.sensorium.preferences.Preferences;
import at.univie.sensorium.sensors.SensorValue;
public class Privacy {
public static enum PrivacyLevel {
NO(0, "Full Sensor Access"), LOW(1, "Low Privacy"), MED(2, "Medium Privacy"), HIGH(3, "High Privacy"), FULL(4, "Sensor not visible");
private int value;
private String name;
private PrivacyLevel(int value, String name) {
this.value = value;
this.name = name;
}
public int value() {
return value;
}
@Override
public String toString() {
return name;
}
public static PrivacyLevel fromInt(int x) {
switch (x) {
case 0:
return NO;
case 1:
return LOW;
case 2:
return MED;
case 3:
return HIGH;
case 4:
return FULL;
}
return null;
}
}
protected static SensorValue anonymizeValue(SensorValue val, PrivacyLevel l) {
switch (l) {
case NO:
return val;
case LOW:
case MED:
return hash(val);
case HIGH:
return hash(salt(val));
case FULL:
default:
val.setValue("n/a");
return val;
}
}
protected static SensorValue anonymizestrict(SensorValue val, PrivacyLevel l) {
val.setValue("n/a");
return val;
}
protected static SensorValue anonymizesignalstrength(SensorValue val, PrivacyLevel l) {
switch (l) {
case NO:
return val;
case LOW:
SensorValue ret = new SensorValue(val);
if (val.getValue() instanceof Integer && (Integer) val.getValue() >= -70) {
ret.setValue("high");
} else {
ret.setValue("low");
}
return ret;
case MED:
return hash(val);
case HIGH:
return hash(salt(val));
case FULL:
default:
val.setValue("n/a");
return val;
}
}
public static SensorValue anonymize(SensorValue val, PrivacyLevel l) {
SensorValue retval = new SensorValue(val);
switch (retval.getType()) {
case LATITUDE:
case LONGITUDE:
return LocationPrivacy.anonymizeValue(retval, l);
case ADDRESS:
return LocationPrivacy.anonymizeAddress(retval, l);
case CID:
case LAC:
case MCC:
case MNC:
case NETWORKTYPE:
return anonymizeValue(retval, l);
case SIGNALSTRENGTH:
return anonymizesignalstrength(retval, l);
case SIM_SERIAL:
case SUBSCRIBER_ID:
return anonymizestrict(retval, l);
default:
// Log.d(SensorRegistry.TAG, "No known privacy methods for type " +
// val.getType().getName());
return retval;
}
}
protected static SensorValue hash(SensorValue val) {
SensorValue ret = new SensorValue(val);
ret.setUnit(SensorValue.UNIT.HASH);
String sha1 = "";
String message = (val.getValue().toString()) + val.getUnit() + val.getType();
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
md.reset();
md.update(message.getBytes("UTF-8"), 0, message.length());
byte[] sha1hash = md.digest();
sha1 = Base64.encodeToString(sha1hash, Base64.NO_WRAP | Base64.NO_PADDING);
} catch (NoSuchAlgorithmException e) {
Log.d(SensorRegistry.TAG, e.toString());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.d(SensorRegistry.TAG, sw.toString());
} catch (UnsupportedEncodingException e) {
Log.d(SensorRegistry.TAG, e.toString());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.d(SensorRegistry.TAG, sw.toString());
}
ret.setValue(sha1);
return ret;
}
protected static SensorValue salt(SensorValue val) {
// load stored seed or generate a new one
String salt = SensorRegistry.getInstance().getPreferences().getString(Preferences.PRIVACY_HASH, "");
if (salt.equals("")) {
SecureRandom random = new SecureRandom();
salt = (new BigInteger(130, random)).toString(32);
SensorRegistry.getInstance().getPreferences().putString(Preferences.PRIVACY_HASH, salt);
}
Log.d("Sensorium", "Salt is " + salt);
SensorValue ret = new SensorValue(val);
ret.setValue(salt + val.getValue().toString());
return ret;
}
}