protected void finishLogin(final byte[] privateKeyData, final byte[] publicKeyData) { Log.v(TAG, "finishing login"); // update public key try { mKey.update(publicKeyData); } catch (IOException e) { Log.v(TAG, "error decoding public key", e); // TODO what now?? } if (mProgress == null) startProgress(); mProgress.setCancelable(false); setProgressMessage(getString(R.string.msg_initializing)); final Account account = new Account(mPhoneNumber, Authenticator.ACCOUNT_TYPE); // generate the bridge certificate byte[] bridgeCertData; try { // TODO subjectAltName? bridgeCertData = X509Bridge.createCertificate(privateKeyData, publicKeyData, mPassphrase, null) .getEncoded(); } catch (Exception e) { // abort throw new RuntimeException("unable to build X.509 bridge certificate", e); } // workaround for bug in AccountManager (http://stackoverflow.com/a/11698139/1045199) // procedure will continue in removeAccount callback mAccountManager.removeAccount( account, new AccountRemovalCallback( this, account, mPassphrase, privateKeyData, publicKeyData, bridgeCertData, mName), mHandler); }
@Override public void processPacket(Stanza packet) { PublicKeyPublish p = (PublicKeyPublish) packet; if (p.getType() == IQ.Type.result) { byte[] _publicKey = p.getPublicKey(); if (_publicKey != null) { String from = XmppStringUtils.parseBareJid(p.getFrom()); boolean selfJid = Authenticator.isSelfJID(getContext(), from); // is this our key? if (selfJid) { byte[] bridgeCertData; try { PersonalKey key = getApplication().getPersonalKey(); bridgeCertData = X509Bridge.createCertificate(_publicKey, key.getAuthKeyPair().getPrivateKey()) .getEncoded(); } catch (Exception e) { Log.e(MessageCenterService.TAG, "error decoding key data", e); bridgeCertData = null; } if (bridgeCertData != null) { // store key data in AccountManager Authenticator.setDefaultPersonalKey( getContext(), _publicKey, null, bridgeCertData, null); // invalidate cached personal key getApplication().invalidatePersonalKey(); Log.v(MessageCenterService.TAG, "personal key updated."); } } String id = p.getStanzaId(); // broadcast key update Intent i = new Intent(ACTION_PUBLICKEY); i.putExtra(EXTRA_PACKET_ID, id); i.putExtra(EXTRA_FROM, p.getFrom()); i.putExtra(EXTRA_TO, p.getTo()); i.putExtra(EXTRA_PUBLIC_KEY, _publicKey); sendBroadcast(i); // if we are not syncing and this is not a response for the Syncer // save the key immediately if (!SyncAdapter.getIQPacketId().equals(id) || !SyncAdapter.isActive(getContext())) { // updating server key if (XmppStringUtils.parseDomain(from).equals(from)) { Log.v("pubkey", "Updating server key for " + from); try { Keyring.setKey(getContext(), from, _publicKey); } catch (Exception e) { // TODO warn user Log.e(MessageCenterService.TAG, "unable to update user key", e); } } else { try { Log.v("pubkey", "Updating key for " + from); Keyring.setKey( getContext(), from, _publicKey, selfJid ? MyUsers.Keys.TRUST_VERIFIED : -1); // update display name with uid (if empty) PGPUserID keyUid = PGP.parseUserId(_publicKey, getConnection().getServiceName()); if (keyUid != null && keyUid.getName() != null) UsersProvider.updateDisplayNameIfEmpty(getContext(), from, keyUid.getName()); // invalidate cache for this user Contact.invalidate(from); } catch (Exception e) { // TODO warn user Log.e(MessageCenterService.TAG, "unable to update user key", e); } } } } } }