/** * Copyright (C) 2011 Whisper Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package org.thoughtcrime.securesms.util; import java.lang.reflect.Field; import java.util.Arrays; import javax.crypto.spec.SecretKeySpec; import org.thoughtcrime.securesms.crypto.MasterSecret; import android.util.Log; /** * This is not straightforward in Java, but this class makes * a best-effort attempt to clean up memory in immutable objects. * * @author Moxie Marlinspike */ public class MemoryCleaner { public static void clean(MasterSecret masterSecret) { try { SecretKeySpec cipherKey = masterSecret.getEncryptionKey(); SecretKeySpec macKey = masterSecret.getMacKey(); Field keyField = SecretKeySpec.class.getDeclaredField("key"); keyField.setAccessible(true); byte[] cipherKeyField = (byte[]) keyField.get(cipherKey); byte[] macKeyField = (byte[]) keyField.get(macKey); Arrays.fill(cipherKeyField, (byte)0x00); Arrays.fill(macKeyField, (byte)0x00); } catch (NoSuchFieldException nsfe) { Log.w("MemoryCleaner", nsfe); } catch (IllegalArgumentException e) { Log.w("MemoryCleaner", e); } catch (IllegalAccessException e) { Log.w("MemoryCleaner", e); } } public static void clean(String string) { try { Field charArrayField = String.class.getDeclaredField("value"); charArrayField.setAccessible(true); char[] internalBuffer = (char[])charArrayField.get(string); Arrays.fill(internalBuffer, 'A'); } catch (NoSuchFieldException nsfe) { Log.w("MemoryCleaner", nsfe); } catch (IllegalArgumentException e) { Log.w("MemoryCleaner", e); } catch (IllegalAccessException e) { Log.w("MemoryCleaner", e); } } }