diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-10-05 18:35:16 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-10-05 18:35:16 +0200 |
commit | bef6977aade3a901ac17ed1e31de22c8de066921 (patch) | |
tree | acf212a4fdf11391a2e380fd2795fd9573b48df4 /OpenPGP-Keychain/src/org/sufficientlysecure | |
parent | c75c00f935faf02e65c1a6cb165ea6cf6b236432 (diff) | |
download | open-keychain-bef6977aade3a901ac17ed1e31de22c8de066921.tar.gz open-keychain-bef6977aade3a901ac17ed1e31de22c8de066921.tar.bz2 open-keychain-bef6977aade3a901ac17ed1e31de22c8de066921.zip |
New API version, import from clipboard
Diffstat (limited to 'OpenPGP-Keychain/src/org/sufficientlysecure')
3 files changed, 189 insertions, 41 deletions
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 50e49a2ab..9f302459c 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -25,9 +25,12 @@ import java.util.ArrayList; import java.util.regex.Matcher; import org.openintents.openpgp.IOpenPgpCallback; +import org.openintents.openpgp.IOpenPgpKeyIdsCallback; import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.OpenPgpData; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; +import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -114,8 +117,8 @@ public class OpenPgpService extends RemoteService { * @param encryptionUserIds * @return */ - private long[] getKeyIdsFromEmails(String[] encryptionUserIds, long ownKeyId, - boolean allowUserInteraction) throws UserInteractionRequiredException { + private long[] getKeyIdsFromEmails(String[] encryptionUserIds, boolean allowUserInteraction) + throws UserInteractionRequiredException { // find key ids to given emails in database ArrayList<Long> keyIds = new ArrayList<Long>(); @@ -142,9 +145,6 @@ public class OpenPgpService extends RemoteService { } } - // also encrypt to our self (so that we can decrypt it later!) - keyIds.add(ownKeyId); - // convert to long[] long[] keyIdsArray = new long[keyIds.size()]; for (int i = 0; i < keyIdsArray.length; i++) { @@ -215,24 +215,47 @@ public class OpenPgpService extends RemoteService { } }; - private synchronized void encryptAndSignSafe(byte[] inputBytes, String[] encryptionUserIds, - boolean asciiArmor, boolean allowUserInteraction, IOpenPgpCallback callback, - AppSettings appSettings, boolean sign) { + private synchronized void getKeyIdsSafe(String[] userIds, boolean allowUserInteraction, + IOpenPgpKeyIdsCallback callback, AppSettings appSettings) { try { + long[] keyIds = getKeyIdsFromEmails(userIds, allowUserInteraction); + if (keyIds == null) { + throw new NoUserIdsException("No user ids!"); + } + + callback.onSuccess(keyIds); + } catch (UserInteractionRequiredException e) { + callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); + } catch (NoUserIdsException e) { + callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage()); + } catch (Exception e) { + callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage()); + } + } + + private synchronized void encryptAndSignSafe(OpenPgpData inputData, + final OpenPgpData outputData, long[] keyIds, boolean allowUserInteraction, + IOpenPgpCallback callback, AppSettings appSettings, boolean sign) { + try { + // TODO: other options of OpenPgpData! + byte[] inputBytes = getInput(inputData); + boolean asciiArmor = false; + if (outputData.getType() == OpenPgpData.TYPE_STRING) { + asciiArmor = true; + } + + // add own key for encryption + keyIds = Arrays.copyOf(keyIds, keyIds.length + 1); + keyIds[keyIds.length - 1] = appSettings.getKeyId(); + // build InputData and write into OutputStream InputStream inputStream = new ByteArrayInputStream(inputBytes); long inputLength = inputBytes.length; - InputData inputData = new InputData(inputStream, inputLength); + InputData inputDt = new InputData(inputStream, inputLength); OutputStream outputStream = new ByteArrayOutputStream(); - long[] keyIds = getKeyIdsFromEmails(encryptionUserIds, appSettings.getKeyId(), - allowUserInteraction); - if (keyIds == null) { - throw new NoUserIdsException("No user ids!"); - } - - PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream); + PgpOperation operation = new PgpOperation(getContext(), null, inputDt, outputStream); if (sign) { String passphrase = getCachedPassphrase(appSettings.getKeyId(), allowUserInteraction); @@ -253,12 +276,17 @@ public class OpenPgpService extends RemoteService { byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); + OpenPgpData output = null; + if (asciiArmor) { + output = new OpenPgpData(new String(outputBytes)); + } else { + output = new OpenPgpData(outputBytes); + } + // return over handler on client side - callback.onSuccess(outputBytes, null); + callback.onSuccess(output, null); } catch (UserInteractionRequiredException e) { callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); - } catch (NoUserIdsException e) { - callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage()); } catch (WrongPassphraseException e) { callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage()); } catch (Exception e) { @@ -289,9 +317,10 @@ public class OpenPgpService extends RemoteService { outputStream.close(); byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); + OpenPgpData output = new OpenPgpData(new String(outputBytes)); // return over handler on client side - callback.onSuccess(outputBytes, null); + callback.onSuccess(output, null); } catch (UserInteractionRequiredException e) { callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); } catch (WrongPassphraseException e) { @@ -406,8 +435,8 @@ public class OpenPgpService extends RemoteService { OpenPgpSignatureResult sigResult = null; if (signature) { - // long signatureKeyId = outputBundle - // .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID); + long signatureKeyId = outputBundle + .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID); String signatureUserId = outputBundle .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID); boolean signatureSuccess = outputBundle @@ -422,11 +451,13 @@ public class OpenPgpService extends RemoteService { signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY; } - sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, signedOnly); + sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, + signedOnly, signatureKeyId); } + OpenPgpData output = new OpenPgpData(new String(outputBytes)); // return over handler on client side - callback.onSuccess(outputBytes, sigResult); + callback.onSuccess(output, sigResult); } catch (UserInteractionRequiredException e) { callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); } catch (WrongPassphraseException e) { @@ -452,18 +483,26 @@ public class OpenPgpService extends RemoteService { } } + private void callbackOpenPgpError(IOpenPgpKeyIdsCallback callback, int errorId, String message) { + try { + callback.onError(new OpenPgpError(0, message)); + } catch (Exception t) { + Log.e(Constants.TAG, + "Exception while returning OpenPgpError to client via callback.onError()", t); + } + } + private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() { @Override - public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds, - final boolean asciiArmor, final IOpenPgpCallback callback) throws RemoteException { + public void encrypt(final OpenPgpData input, final OpenPgpData output, final long[] keyIds, + final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, true, callback, - settings, false); + encryptAndSignSafe(input, output, keyIds, true, callback, settings, false); } }; @@ -471,15 +510,14 @@ public class OpenPgpService extends RemoteService { } @Override - public void signAndEncrypt(final byte[] inputBytes, final String[] encryptionUserIds, - final boolean asciiArmor, final IOpenPgpCallback callback) throws RemoteException { + public void signAndEncrypt(final OpenPgpData input, final OpenPgpData output, + final long[] keyIds, final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, true, callback, - settings, true); + encryptAndSignSafe(input, output, keyIds, true, callback, settings, true); } }; @@ -487,14 +525,14 @@ public class OpenPgpService extends RemoteService { } @Override - public void sign(final byte[] inputBytes, boolean asciiArmor, + public void sign(final OpenPgpData input, final OpenPgpData output, final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - signSafe(inputBytes, true, callback, settings); + signSafe(getInput(input), true, callback, settings); } }; @@ -502,15 +540,15 @@ public class OpenPgpService extends RemoteService { } @Override - public void decryptAndVerify(final byte[] inputBytes, final IOpenPgpCallback callback) - throws RemoteException { + public void decryptAndVerify(final OpenPgpData input, final OpenPgpData output, + final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - decryptAndVerifySafe(inputBytes, true, callback, settings); + decryptAndVerifySafe(getInput(input), true, callback, settings); } }; @@ -518,13 +556,44 @@ public class OpenPgpService extends RemoteService { } @Override - public boolean isKeyAvailable(String[] userIds) throws RemoteException { - // TODO - return false; + public void getKeyIds(final String[] userIds, final boolean allowUserInteraction, + final IOpenPgpKeyIdsCallback callback) throws RemoteException { + + final AppSettings settings = getAppSettings(); + + Runnable r = new Runnable() { + @Override + public void run() { + getKeyIdsSafe(userIds, allowUserInteraction, callback, settings); + } + }; + + checkAndEnqueue(r); } }; + private static byte[] getInput(OpenPgpData data) { + // TODO: support Uri and ParcelFileDescriptor + + byte[] inBytes = null; + switch (data.getType()) { + case OpenPgpData.TYPE_STRING: + inBytes = data.getString().getBytes(); + break; + + case OpenPgpData.TYPE_BYTE_ARRAY: + inBytes = data.getBytes(); + break; + + default: + Log.e(Constants.TAG, "Uri and ParcelFileDescriptor not supported right now!"); + break; + } + + return inBytes; + } + @Override public IBinder onBind(Intent intent) { return mBinder; diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 132e644bc..b9348cdaf 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -166,7 +166,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa mListFragment = ImportKeysListFragment.newInstance(bytes, filename); // Add the fragment to the 'fragment_container' FrameLayout - // NOTE: We use commitAllowingStateLoss() to prevent wierd crashes! + // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! getSupportFragmentManager().beginTransaction() .replace(R.id.import_keys_list_container, mListFragment) .commitAllowingStateLoss(); @@ -189,6 +189,9 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]); break; case 3: + loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]); + break; + case 4: loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]); break; diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java new file mode 100644 index 000000000..dcb7dbcc6 --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Button; + +public class ImportKeysClipboardFragment extends Fragment { + + private ImportKeysActivity mImportActivity; + private Button mButton; + + /** + * Creates new instance of this fragment + */ + public static ImportKeysClipboardFragment newInstance() { + ImportKeysClipboardFragment frag = new ImportKeysClipboardFragment(); + + Bundle args = new Bundle(); + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.import_keys_clipboard_fragment, container, false); + + mButton = (Button) view.findViewById(R.id.import_clipboard_button); + mButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity()); + + mImportActivity.loadCallback(clipboardText.toString().getBytes(), null); + } + }); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mImportActivity = (ImportKeysActivity) getActivity(); + } + +} |