/******************************************************************************* * Copyright (C) 2015 Connor Lanigan (email: dev@connorlanigan.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package de.norvos.account; import java.io.IOException; import java.util.List; import org.whispersystems.libaxolotl.IdentityKey; import org.whispersystems.libaxolotl.IdentityKeyPair; import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.util.guava.Optional; import org.whispersystems.textsecure.api.TextSecureAccountManager; import de.norvos.axolotl.TrustStore; import de.norvos.axolotl.stores.IdentityKeyStore; import de.norvos.axolotl.stores.PreKeyStore; import de.norvos.axolotl.stores.SignedPreKeyStore; import de.norvos.utils.Constants; import de.norvos.utils.RandomUtils; /** * Provides methods to register a client with the server. * * @author Connor Lanigan */ public class Registrator { private static boolean initialized = false; final static private int initialSignedKeyID = 5; private static List<PreKeyRecord> oneTimePreKeys; final static private int passwordLength = 40; final static boolean REDPHONE_UNSUPPORTED = false; private static boolean requested = false; final static public String WHISPERSYSTEMS_REGISTRATION_ID = "312334754206"; /** * Initialize the Registrator. This will generate new keys, and a new * installation ID.<br> * <strong>Warning: All existing user data is possibly destroyed after * calling this method.</strong> */ public static void initialize() { IdentityKeyStore.getInstance().initialize(); oneTimePreKeys = PreKeyStore.getInstance().initialize(); final IdentityKeyPair identityKeyPair = IdentityKeyStore.getInstance().getIdentityKeyPair(); SignedPreKeyStore.getInstance().initialize(identityKeyPair, initialSignedKeyID); SettingsService.setPassword(RandomUtils.randomAlphanumerical(passwordLength)); SettingsService.setSignalingKey(RandomUtils.randomAlphanumerical(52)); SettingsService.setInstallID(RandomUtils.generateInstallId()); initialized = true; } /** * Requests a verification SMS code for this client from the server. The * Registrator needs to be {@link Registrator#initialize() initialized} * first. * * @throws IOException * if an error occurs during registering * @throws IllegalStateException * if this Registrator has not been initialized */ public static void requestCode() throws IOException { if (!initialized) { throw new IllegalStateException("Registrator must be initialized by calling initialize() first."); } final String url = SettingsService.getURL(); final String username = SettingsService.getUsername(); final TrustStore trustStore = TrustStore.getInstance(); final String password = SettingsService.getPassword(); final TextSecureAccountManager accountManager = new TextSecureAccountManager(url, trustStore, username, password, Constants.USER_AGENT); try { accountManager.requestSmsVerificationCode(); } catch (final Exception e) { throw new IOException(e); } requested = true; } /** * Verifies the received SMS code. * * @param verificationCode * @throws IOException */ public static void verify(final String verificationCode) throws IOException { if (!initialized) { throw new IllegalStateException("Registrator must be initialized by calling initialize() first."); } if (!requested) { throw new IllegalStateException("Registrator must request a code before verifying."); } final String url = SettingsService.getURL(); final String username = SettingsService.getUsername(); final TrustStore trustStore = TrustStore.getInstance(); final String password = SettingsService.getPassword(); final String signalingKey = SettingsService.getSignalingKey(); final Integer installID = SettingsService.getInstallID(); final TextSecureAccountManager accountManager = new TextSecureAccountManager(url, trustStore, username, password, Constants.USER_AGENT); accountManager.verifyAccountWithCode(verificationCode, signalingKey, installID, REDPHONE_UNSUPPORTED); accountManager.setGcmId(Optional.of("Norvos does not support GCM.")); final IdentityKey identityKey = IdentityKeyStore.getInstance().getIdentityKeyPair().getPublicKey(); final PreKeyRecord lastResortKey = PreKeyStore.getInstance().getLastResortKey(); final SignedPreKeyRecord signedPreKey = SignedPreKeyStore.getInstance().loadSignedPreKeys().get(0); accountManager.setPreKeys(identityKey, lastResortKey, signedPreKey, oneTimePreKeys); SettingsService.setSetupFinished(true); } }