From c5ed6ce6f7dcb892cbdfac5bd591cb4e6e798961 Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 20 Jun 2012 15:27:45 +0300 Subject: seperating intent action constants into activities as it is best practice, restructering... --- org_apg/AndroidManifest.xml | 2 +- .../src/org/thialfihar/android/apg/Constants.java | 14 ++ .../org/thialfihar/android/apg/HkpKeyServer.java | 259 --------------------- .../src/org/thialfihar/android/apg/KeyServer.java | 62 ----- .../org/thialfihar/android/apg/PausableThread.java | 49 ---- .../org/thialfihar/android/apg/Preferences.java | 170 -------------- .../android/apg/deprecated/ApgService2.java | 2 +- .../android/apg/deprecated/GeneralActivity.java | 196 ++++++++++++++++ .../android/apg/deprecated/PausableThread.java | 49 ++++ .../thialfihar/android/apg/helper/PGPHelper.java | 34 +-- .../thialfihar/android/apg/helper/Preferences.java | 176 ++++++++++++++ .../apg/passphrase/PassphraseCacheService.java | 2 +- .../thialfihar/android/apg/service/ApgService.java | 2 +- .../thialfihar/android/apg/ui/BaseActivity.java | 4 +- .../thialfihar/android/apg/ui/DecryptActivity.java | 34 ++- .../thialfihar/android/apg/ui/EditKeyActivity.java | 25 +- .../thialfihar/android/apg/ui/EncryptActivity.java | 35 +-- .../thialfihar/android/apg/ui/GeneralActivity.java | 191 --------------- .../android/apg/ui/ImportFromQRCodeActivity.java | 103 ++++---- .../thialfihar/android/apg/ui/KeyListActivity.java | 5 +- .../android/apg/ui/KeyServerExportActivity.java | 6 +- .../android/apg/ui/KeyServerQueryActivity.java | 24 +- .../android/apg/ui/MailListActivity.java | 4 +- .../thialfihar/android/apg/ui/MainActivity.java | 6 +- .../android/apg/ui/PreferencesActivity.java | 2 +- .../android/apg/ui/PublicKeyListActivity.java | 8 +- .../android/apg/ui/SecretKeyListActivity.java | 4 +- .../apg/ui/SelectPublicKeyListActivity.java | 6 + .../apg/ui/SelectSecretKeyListActivity.java | 6 + .../thialfihar/android/apg/ui/SignKeyActivity.java | 2 +- .../thialfihar/android/apg/util/HkpKeyServer.java | 259 +++++++++++++++++++++ .../org/thialfihar/android/apg/util/KeyServer.java | 62 +++++ 32 files changed, 927 insertions(+), 876 deletions(-) delete mode 100644 org_apg/src/org/thialfihar/android/apg/HkpKeyServer.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/KeyServer.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/PausableThread.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/Preferences.java create mode 100644 org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/deprecated/PausableThread.java create mode 100644 org_apg/src/org/thialfihar/android/apg/helper/Preferences.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/ui/GeneralActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java create mode 100644 org_apg/src/org/thialfihar/android/apg/util/KeyServer.java diff --git a/org_apg/AndroidManifest.xml b/org_apg/AndroidManifest.xml index 34d34c4ae..4b38560ae 100644 --- a/org_apg/AndroidManifest.xml +++ b/org_apg/AndroidManifest.xml @@ -169,7 +169,7 @@ diff --git a/org_apg/src/org/thialfihar/android/apg/Constants.java b/org_apg/src/org/thialfihar/android/apg/Constants.java index a9c4d04df..58a4ecbe7 100644 --- a/org_apg/src/org/thialfihar/android/apg/Constants.java +++ b/org_apg/src/org/thialfihar/android/apg/Constants.java @@ -21,6 +21,20 @@ import android.os.Environment; public final class Constants { public static final String TAG = "APG"; + + public static final String PACKAGE_NAME = "org.thialfihar.android.apg"; + + /* + * TODO: + * + * better naming scheme would be: + * + * - x.action.DECRYPT (with action as preferred in Android) + * + * - even better and shorter (without .android.): org.apg.action.DECRYPT + */ + public static final String INTENT_PREFIX = "org.thialfihar.android.apg.intent."; + public static final class path { public static final String APP_DIR = Environment.getExternalStorageDirectory() + "/APG"; diff --git a/org_apg/src/org/thialfihar/android/apg/HkpKeyServer.java b/org_apg/src/org/thialfihar/android/apg/HkpKeyServer.java deleted file mode 100644 index aa3131a92..000000000 --- a/org_apg/src/org/thialfihar/android/apg/HkpKeyServer.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2011 Senecaso - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLEncoder; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; -import org.thialfihar.android.apg.helper.PGPHelper; - -import android.text.Html; - -public class HkpKeyServer extends KeyServer { - private static class HttpError extends Exception { - private static final long serialVersionUID = 1718783705229428893L; - private int mCode; - private String mData; - - public HttpError(int code, String data) { - super("" + code + ": " + data); - mCode = code; - mData = data; - } - - public int getCode() { - return mCode; - } - - public String getData() { - return mData; - } - } - - private String mHost; - private short mPort = 11371; - - // example: - // pub 2048R/9F5C9090 2009-08-17 Jörg Runge - // <joerg@joergrunge.de> - public static Pattern PUB_KEY_LINE = Pattern - .compile( - "pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", - Pattern.CASE_INSENSITIVE); - public static Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE - | Pattern.CASE_INSENSITIVE); - - public HkpKeyServer(String host) { - mHost = host; - } - - public HkpKeyServer(String host, short port) { - mHost = host; - mPort = port; - } - - static private String readAll(InputStream in, String encoding) throws IOException { - ByteArrayOutputStream raw = new ByteArrayOutputStream(); - - byte buffer[] = new byte[1 << 16]; - int n = 0; - while ((n = in.read(buffer)) != -1) { - raw.write(buffer, 0, n); - } - - if (encoding == null) { - encoding = "utf8"; - } - return raw.toString(encoding); - } - - // TODO: replace this with httpclient - private String query(String request) throws QueryException, HttpError { - InetAddress ips[]; - try { - ips = InetAddress.getAllByName(mHost); - } catch (UnknownHostException e) { - throw new QueryException(e.toString()); - } - for (int i = 0; i < ips.length; ++i) { - try { - String url = "http://" + ips[i].getHostAddress() + ":" + mPort + request; - URL realUrl = new URL(url); - HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); - conn.setConnectTimeout(5000); - conn.setReadTimeout(25000); - conn.connect(); - int response = conn.getResponseCode(); - if (response >= 200 && response < 300) { - return readAll(conn.getInputStream(), conn.getContentEncoding()); - } else { - String data = readAll(conn.getErrorStream(), conn.getContentEncoding()); - throw new HttpError(response, data); - } - } catch (MalformedURLException e) { - // nothing to do, try next IP - } catch (IOException e) { - // nothing to do, try next IP - } - } - - throw new QueryException("querying server(s) for '" + mHost + "' failed"); - } - - // TODO: replace this with httpclient - @Override - public List search(String query) throws QueryException, TooManyResponses, - InsufficientQuery { - Vector results = new Vector(); - - if (query.length() < 3) { - throw new InsufficientQuery(); - } - - String encodedQuery; - try { - encodedQuery = URLEncoder.encode(query, "utf8"); - } catch (UnsupportedEncodingException e) { - return null; - } - String request = "/pks/lookup?op=index&search=" + encodedQuery; - - String data = null; - try { - data = query(request); - } catch (HttpError e) { - if (e.getCode() == 404) { - return results; - } else { - if (e.getData().toLowerCase().contains("no keys found")) { - return results; - } else if (e.getData().toLowerCase().contains("too many")) { - throw new TooManyResponses(); - } else if (e.getData().toLowerCase().contains("insufficient")) { - throw new InsufficientQuery(); - } - } - throw new QueryException("querying server(s) for '" + mHost + "' failed"); - } - - Matcher matcher = PUB_KEY_LINE.matcher(data); - while (matcher.find()) { - KeyInfo info = new KeyInfo(); - info.size = Integer.parseInt(matcher.group(1)); - info.algorithm = matcher.group(2); - info.keyId = PGPHelper.keyFromHex(matcher.group(3)); - info.fingerPrint = PGPHelper.getSmallFingerPrint(info.keyId); - String chunks[] = matcher.group(4).split("-"); - info.date = new GregorianCalendar(Integer.parseInt(chunks[0]), - Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime(); - info.userIds = new Vector(); - if (matcher.group(5).startsWith("*** KEY")) { - info.revoked = matcher.group(5); - } else { - String tmp = matcher.group(5).replaceAll("<.*?>", ""); - tmp = Html.fromHtml(tmp).toString(); - info.userIds.add(tmp); - } - if (matcher.group(6).length() > 0) { - Matcher matcher2 = USER_ID_LINE.matcher(matcher.group(6)); - while (matcher2.find()) { - String tmp = matcher2.group(1).replaceAll("<.*?>", ""); - tmp = Html.fromHtml(tmp).toString(); - info.userIds.add(tmp); - } - } - results.add(info); - } - - return results; - } - - @Override - public String get(long keyId) throws QueryException { - HttpClient client = new DefaultHttpClient(); - try { - HttpGet get = new HttpGet("http://" + mHost + ":" + mPort - + "/pks/lookup?op=get&search=0x" + PGPHelper.keyToHex(keyId)); - - HttpResponse response = client.execute(get); - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - throw new QueryException("not found"); - } - - HttpEntity entity = response.getEntity(); - InputStream is = entity.getContent(); - String data = readAll(is, EntityUtils.getContentCharSet(entity)); - Matcher matcher = PGPHelper.PGP_PUBLIC_KEY.matcher(data); - if (matcher.find()) { - return matcher.group(1); - } - } catch (IOException e) { - // nothing to do, better luck on the next keyserver - } finally { - client.getConnectionManager().shutdown(); - } - - return null; - } - - @Override - public void add(String armouredText) throws AddKeyException { - HttpClient client = new DefaultHttpClient(); - try { - HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add"); - - List nameValuePairs = new ArrayList(2); - nameValuePairs.add(new BasicNameValuePair("keytext", armouredText)); - post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - - HttpResponse response = client.execute(post); - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - throw new AddKeyException(); - } - } catch (IOException e) { - // nothing to do, better luck on the next keyserver - } finally { - client.getConnectionManager().shutdown(); - } - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/KeyServer.java b/org_apg/src/org/thialfihar/android/apg/KeyServer.java deleted file mode 100644 index b1420ad0f..000000000 --- a/org_apg/src/org/thialfihar/android/apg/KeyServer.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 Senecaso - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg; - -import java.io.Serializable; -import java.util.Date; -import java.util.List; -import java.util.Vector; - -public abstract class KeyServer { - static public class QueryException extends Exception { - private static final long serialVersionUID = 2703768928624654512L; - - public QueryException(String message) { - super(message); - } - } - - static public class TooManyResponses extends Exception { - private static final long serialVersionUID = 2703768928624654513L; - } - - static public class InsufficientQuery extends Exception { - private static final long serialVersionUID = 2703768928624654514L; - } - - static public class AddKeyException extends Exception { - private static final long serialVersionUID = -507574859137295530L; - } - - static public class KeyInfo implements Serializable { - private static final long serialVersionUID = -7797972113284992662L; - public Vector userIds; - public String revoked; - public Date date; - public String fingerPrint; - public long keyId; - public int size; - public String algorithm; - } - - abstract List search(String query) throws QueryException, TooManyResponses, - InsufficientQuery; - - abstract String get(long keyId) throws QueryException; - - abstract void add(String armouredText) throws AddKeyException; -} diff --git a/org_apg/src/org/thialfihar/android/apg/PausableThread.java b/org_apg/src/org/thialfihar/android/apg/PausableThread.java deleted file mode 100644 index 87e7c7ee9..000000000 --- a/org_apg/src/org/thialfihar/android/apg/PausableThread.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg; - -public class PausableThread extends Thread { - private boolean mPaused = false; - - public PausableThread(Runnable runnable) { - super(runnable); - } - - public void pause() { - synchronized (this) { - mPaused = true; - while (mPaused) { - try { - wait(); - } catch (InterruptedException e) { - // ignore - } - } - } - } - - public void unpause() { - synchronized (this) { - mPaused = false; - notify(); - } - } - - public boolean isPaused() { - synchronized (this) { - return mPaused; - } - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/Preferences.java b/org_apg/src/org/thialfihar/android/apg/Preferences.java deleted file mode 100644 index 5c7c348ed..000000000 --- a/org_apg/src/org/thialfihar/android/apg/Preferences.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2012 Dominik Schürmann - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg; - -import org.spongycastle.bcpg.HashAlgorithmTags; -import org.spongycastle.openpgp.PGPEncryptedData; - -import android.content.Context; -import android.content.SharedPreferences; - -import java.util.Vector; - -/** - * Singleton Implementation of a Preference Helper - */ -public class Preferences { - private static Preferences mPreferences; - private SharedPreferences mSharedPreferences; - - public static synchronized Preferences getPreferences(Context context) { - return getPreferences(context, false); - } - - public static synchronized Preferences getPreferences(Context context, boolean force_new) { - if (mPreferences == null || force_new) { - mPreferences = new Preferences(context); - } - return mPreferences; - } - - private Preferences(Context context) { - mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE); - } - - public String getLanguage() { - return mSharedPreferences.getString(Constants.pref.LANGUAGE, ""); - } - - public void setLanguage(String value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putString(Constants.pref.LANGUAGE, value); - editor.commit(); - } - - public int getPassPhraseCacheTtl() { - int ttl = mSharedPreferences.getInt(Constants.pref.PASS_PHRASE_CACHE_TTL, 180); - // fix the value if it was set to "never" in previous versions, which currently is not - // supported - if (ttl == 0) { - ttl = 180; - } - return ttl; - } - - public void setPassPhraseCacheTtl(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Constants.pref.PASS_PHRASE_CACHE_TTL, value); - editor.commit(); - } - - public int getDefaultEncryptionAlgorithm() { - return mSharedPreferences.getInt(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM, - PGPEncryptedData.AES_256); - } - - public void setDefaultEncryptionAlgorithm(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM, value); - editor.commit(); - } - - public int getDefaultHashAlgorithm() { - return mSharedPreferences.getInt(Constants.pref.DEFAULT_HASH_ALGORITHM, - HashAlgorithmTags.SHA256); - } - - public void setDefaultHashAlgorithm(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Constants.pref.DEFAULT_HASH_ALGORITHM, value); - editor.commit(); - } - - public int getDefaultMessageCompression() { - return mSharedPreferences.getInt(Constants.pref.DEFAULT_MESSAGE_COMPRESSION, - Id.choice.compression.zlib); - } - - public void setDefaultMessageCompression(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Constants.pref.DEFAULT_MESSAGE_COMPRESSION, value); - editor.commit(); - } - - public int getDefaultFileCompression() { - return mSharedPreferences.getInt(Constants.pref.DEFAULT_FILE_COMPRESSION, - Id.choice.compression.none); - } - - public void setDefaultFileCompression(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Constants.pref.DEFAULT_FILE_COMPRESSION, value); - editor.commit(); - } - - public boolean getDefaultAsciiArmour() { - return mSharedPreferences.getBoolean(Constants.pref.DEFAULT_ASCII_ARMOUR, false); - } - - public void setDefaultAsciiArmour(boolean value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putBoolean(Constants.pref.DEFAULT_ASCII_ARMOUR, value); - editor.commit(); - } - - public boolean getForceV3Signatures() { - return mSharedPreferences.getBoolean(Constants.pref.FORCE_V3_SIGNATURES, false); - } - - public void setForceV3Signatures(boolean value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putBoolean(Constants.pref.FORCE_V3_SIGNATURES, value); - editor.commit(); - } - - public String[] getKeyServers() { - String rawData = mSharedPreferences.getString(Constants.pref.KEY_SERVERS, - Constants.defaults.KEY_SERVERS); - Vector servers = new Vector(); - String chunks[] = rawData.split(","); - for (int i = 0; i < chunks.length; ++i) { - String tmp = chunks[i].trim(); - if (tmp.length() > 0) { - servers.add(tmp); - } - } - return servers.toArray(chunks); - } - - public void setKeyServers(String[] value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - String rawData = ""; - for (int i = 0; i < value.length; ++i) { - String tmp = value[i].trim(); - if (tmp.length() == 0) { - continue; - } - if (!"".equals(rawData)) { - rawData += ","; - } - rawData += tmp; - } - editor.putString(Constants.pref.KEY_SERVERS, rawData); - editor.commit(); - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java b/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java index e424c200c..955d9c8ff 100644 --- a/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java +++ b/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java @@ -27,12 +27,12 @@ import java.util.Iterator; import org.thialfihar.android.apg.deprecated.IApgService2; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.deprecated.IApgService2.Stub; import org.thialfihar.android.apg.Id.database; import org.thialfihar.android.apg.R.string; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.passphrase.PassphraseCacheService; import org.thialfihar.android.apg.provider.KeyRings; import org.thialfihar.android.apg.provider.Keys; diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java b/org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java new file mode 100644 index 000000000..7a3d99232 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java @@ -0,0 +1,196 @@ +///* +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.thialfihar.android.apg.deprecated; +// +//import java.io.ByteArrayInputStream; +//import java.io.FileNotFoundException; +//import java.io.IOException; +//import java.io.InputStream; +//import java.util.Vector; +// +//import org.thialfihar.android.apg.R; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.helper.PGPHelper; +//import org.thialfihar.android.apg.ui.BaseActivity; +//import org.thialfihar.android.apg.ui.DecryptActivity; +//import org.thialfihar.android.apg.ui.EncryptActivity; +//import org.thialfihar.android.apg.ui.PublicKeyListActivity; +//import org.thialfihar.android.apg.ui.SecretKeyListActivity; +//import org.thialfihar.android.apg.util.Choice; +// +//import android.content.Intent; +//import android.net.Uri; +//import android.os.Bundle; +//import android.view.View; +//import android.view.View.OnClickListener; +//import android.widget.AdapterView; +//import android.widget.AdapterView.OnItemClickListener; +//import android.widget.ArrayAdapter; +//import android.widget.Button; +//import android.widget.ListView; +//import android.widget.Toast; +// +//public class GeneralActivity extends BaseActivity { +// private Intent mIntent; +// private ArrayAdapter mAdapter; +// private ListView mList; +// private Button mCancelButton; +// private String mDataString; +// private Uri mDataUri; +// +// @Override +// protected void onCreate(Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// +// setContentView(R.layout.general); +// +// mIntent = getIntent(); +// +// InputStream inStream = null; +// { +// String data = mIntent.getStringExtra(Intent.EXTRA_TEXT); +// if (data != null) { +// mDataString = data; +// inStream = new ByteArrayInputStream(data.getBytes()); +// } +// } +// +// if (inStream == null) { +// Uri data = mIntent.getData(); +// if (data != null) { +// mDataUri = data; +// try { +// inStream = getContentResolver().openInputStream(data); +// } catch (FileNotFoundException e) { +// // didn't work +// Toast.makeText(this, "failed to open stream", Toast.LENGTH_SHORT).show(); +// } +// } +// } +// +// if (inStream == null) { +// Toast.makeText(this, "no data found", Toast.LENGTH_SHORT).show(); +// finish(); +// return; +// } +// +// int contentType = Id.content.unknown; +// try { +// contentType = PGPHelper.getStreamContent(this, inStream); +// inStream.close(); +// } catch (IOException e) { +// // just means that there's no PGP data in there +// } +// +// mList = (ListView) findViewById(R.id.options); +// Vector choices = new Vector(); +// +// if (contentType == Id.content.keys) { +// choices.add(new Choice(Id.choice.action.import_public, +// getString(R.string.action_importPublic))); +// choices.add(new Choice(Id.choice.action.import_secret, +// getString(R.string.action_importSecret))); +// } +// +// if (contentType == Id.content.encrypted_data) { +// choices.add(new Choice(Id.choice.action.decrypt, getString(R.string.action_decrypt))); +// } +// +// if (contentType == Id.content.unknown) { +// choices.add(new Choice(Id.choice.action.encrypt, getString(R.string.action_encrypt))); +// } +// +// mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, choices); +// mList.setAdapter(mAdapter); +// +// mList.setOnItemClickListener(new OnItemClickListener() { +// public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { +// clicked(mAdapter.getItem(arg2).getId()); +// } +// }); +// +// mCancelButton = (Button) findViewById(R.id.btn_cancel); +// mCancelButton.setOnClickListener(new OnClickListener() { +// public void onClick(View v) { +// GeneralActivity.this.finish(); +// } +// }); +// +// if (choices.size() == 1) { +// clicked(choices.get(0).getId()); +// } +// } +// +// private void clicked(int id) { +// Intent intent = new Intent(); +// switch (id) { +// case Id.choice.action.encrypt: { +// intent.setClass(this, EncryptActivity.class); +// if (mDataString != null) { +// intent.setAction(EncryptActivity.ENCRYPT); +// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); +// } else if (mDataUri != null) { +// intent.setAction(EncryptActivity.ENCRYPT_FILE); +// intent.setDataAndType(mDataUri, mIntent.getType()); +// } +// +// break; +// } +// +// case Id.choice.action.decrypt: { +// intent.setClass(this, DecryptActivity.class); +// if (mDataString != null) { +// intent.setAction(DecryptActivity.DECRYPT); +// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); +// } else if (mDataUri != null) { +// intent.setAction(DecryptActivity.DECRYPT_FILE); +// intent.setDataAndType(mDataUri, mIntent.getType()); +// } +// +// break; +// } +// +// case Id.choice.action.import_public: { +// intent.setClass(this, PublicKeyListActivity.class); +// intent.setAction(PublicKeyListActivity.IMPORT); +// if (mDataString != null) { +// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); +// } else if (mDataUri != null) { +// intent.setDataAndType(mDataUri, mIntent.getType()); +// } +// break; +// } +// +// case Id.choice.action.import_secret: { +// intent.setClass(this, SecretKeyListActivity.class); +// intent.setAction(SecretKeyListActivity.IMPORT); +// if (mDataString != null) { +// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); +// } else if (mDataUri != null) { +// intent.setDataAndType(mDataUri, mIntent.getType()); +// } +// break; +// } +// +// default: { +// // shouldn't happen +// return; +// } +// } +// +// startActivity(intent); +// finish(); +// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/PausableThread.java b/org_apg/src/org/thialfihar/android/apg/deprecated/PausableThread.java new file mode 100644 index 000000000..a4541c2ae --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/deprecated/PausableThread.java @@ -0,0 +1,49 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.deprecated; + +public class PausableThread extends Thread { + private boolean mPaused = false; + + public PausableThread(Runnable runnable) { + super(runnable); + } + + public void pause() { + synchronized (this) { + mPaused = true; + while (mPaused) { + try { + wait(); + } catch (InterruptedException e) { + // ignore + } + } + } + } + + public void unpause() { + synchronized (this) { + mPaused = false; + notify(); + } + } + + public boolean isPaused() { + synchronized (this) { + return mPaused; + } + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java index 5eb83363f..a0cbaac0c 100644 --- a/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java +++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java @@ -72,7 +72,6 @@ import org.thialfihar.android.apg.Id.type; import org.thialfihar.android.apg.Id.choice.algorithm; import org.thialfihar.android.apg.Id.choice.compression; import org.thialfihar.android.apg.Id.choice.usage; -import org.thialfihar.android.apg.KeyServer.AddKeyException; import org.thialfihar.android.apg.R.string; import org.thialfihar.android.apg.passphrase.CachedPassPhrase; import org.thialfihar.android.apg.provider.DataProvider; @@ -85,14 +84,15 @@ import org.thialfihar.android.apg.ui.BaseActivity; import org.thialfihar.android.apg.ui.widget.KeyEditor; import org.thialfihar.android.apg.ui.widget.SectionView; import org.thialfihar.android.apg.ui.widget.UserIdEditor; +import org.thialfihar.android.apg.util.HkpKeyServer; import org.thialfihar.android.apg.util.InputData; import org.thialfihar.android.apg.util.IterableIterator; +import org.thialfihar.android.apg.util.KeyServer; import org.thialfihar.android.apg.util.PositionAwareInputStream; import org.thialfihar.android.apg.util.Primes; +import org.thialfihar.android.apg.util.KeyServer.AddKeyException; import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.HkpKeyServer; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.KeyServer; import org.thialfihar.android.apg.ProgressDialogUpdater; import org.thialfihar.android.apg.R; @@ -155,30 +155,6 @@ public class PGPHelper { Security.addProvider(new BouncyCastleProvider()); } - public static final String PACKAGE_NAME = "org.thialfihar.android.apg"; - - private static final String INTENT_PREFIX = "org.thialfihar.android.apg.intent."; - - public static class Intent { - public static final String DECRYPT = INTENT_PREFIX + "DECRYPT"; - public static final String ENCRYPT = INTENT_PREFIX + "ENCRYPT"; - public static final String DECRYPT_FILE = INTENT_PREFIX + "DECRYPT_FILE"; - public static final String ENCRYPT_FILE = INTENT_PREFIX + "ENCRYPT_FILE"; - public static final String DECRYPT_AND_RETURN = INTENT_PREFIX + "DECRYPT_AND_RETURN"; - public static final String ENCRYPT_AND_RETURN = INTENT_PREFIX + "ENCRYPT_AND_RETURN"; - public static final String SELECT_PUBLIC_KEYS = INTENT_PREFIX + "SELECT_PUBLIC_KEYS"; - public static final String SELECT_SECRET_KEY = INTENT_PREFIX + "SELECT_SECRET_KEY"; - public static final String IMPORT = INTENT_PREFIX + "IMPORT"; - public static final String LOOK_UP_KEY_ID = INTENT_PREFIX + "LOOK_UP_KEY_ID"; - public static final String LOOK_UP_KEY_ID_AND_RETURN = INTENT_PREFIX - + "LOOK_UP_KEY_ID_AND_RETURN"; - public static final String GENERATE_SIGNATURE = INTENT_PREFIX + "GENERATE_SIGNATURE"; - public static final String EXPORT_KEY_TO_SERVER = INTENT_PREFIX + "EXPORT_KEY_TO_SERVER"; - public static final String IMPORT_FROM_QR_CODE = INTENT_PREFIX + "IMPORT_FROM_QR_CODE"; - public static final String CREATE_KEY = INTENT_PREFIX + "CREATE_KEY"; - public static final String EDIT_KEY = INTENT_PREFIX + "EDIT_KEY"; - } - public static final String EXTRA_TEXT = "text"; public static final String EXTRA_DATA = "data"; public static final String EXTRA_ERROR = "error"; @@ -2267,7 +2243,7 @@ public class PGPHelper { public static boolean isReleaseVersion(Context context) { try { - PackageInfo pi = context.getPackageManager().getPackageInfo(PACKAGE_NAME, 0); + PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0); if (pi.versionCode % 100 == 99) { return true; } else { @@ -2284,7 +2260,7 @@ public class PGPHelper { return VERSION; } try { - PackageInfo pi = context.getPackageManager().getPackageInfo(PACKAGE_NAME, 0); + PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0); VERSION = pi.versionName; return VERSION; } catch (NameNotFoundException e) { diff --git a/org_apg/src/org/thialfihar/android/apg/helper/Preferences.java b/org_apg/src/org/thialfihar/android/apg/helper/Preferences.java new file mode 100644 index 000000000..f4e15e134 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/helper/Preferences.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2012 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.helper; + +import org.spongycastle.bcpg.HashAlgorithmTags; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.Constants.defaults; +import org.thialfihar.android.apg.Constants.pref; +import org.thialfihar.android.apg.Id.choice; +import org.thialfihar.android.apg.Id.choice.compression; + +import android.content.Context; +import android.content.SharedPreferences; + +import java.util.Vector; + +/** + * Singleton Implementation of a Preference Helper + */ +public class Preferences { + private static Preferences mPreferences; + private SharedPreferences mSharedPreferences; + + public static synchronized Preferences getPreferences(Context context) { + return getPreferences(context, false); + } + + public static synchronized Preferences getPreferences(Context context, boolean force_new) { + if (mPreferences == null || force_new) { + mPreferences = new Preferences(context); + } + return mPreferences; + } + + private Preferences(Context context) { + mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE); + } + + public String getLanguage() { + return mSharedPreferences.getString(Constants.pref.LANGUAGE, ""); + } + + public void setLanguage(String value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putString(Constants.pref.LANGUAGE, value); + editor.commit(); + } + + public int getPassPhraseCacheTtl() { + int ttl = mSharedPreferences.getInt(Constants.pref.PASS_PHRASE_CACHE_TTL, 180); + // fix the value if it was set to "never" in previous versions, which currently is not + // supported + if (ttl == 0) { + ttl = 180; + } + return ttl; + } + + public void setPassPhraseCacheTtl(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Constants.pref.PASS_PHRASE_CACHE_TTL, value); + editor.commit(); + } + + public int getDefaultEncryptionAlgorithm() { + return mSharedPreferences.getInt(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM, + PGPEncryptedData.AES_256); + } + + public void setDefaultEncryptionAlgorithm(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM, value); + editor.commit(); + } + + public int getDefaultHashAlgorithm() { + return mSharedPreferences.getInt(Constants.pref.DEFAULT_HASH_ALGORITHM, + HashAlgorithmTags.SHA256); + } + + public void setDefaultHashAlgorithm(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Constants.pref.DEFAULT_HASH_ALGORITHM, value); + editor.commit(); + } + + public int getDefaultMessageCompression() { + return mSharedPreferences.getInt(Constants.pref.DEFAULT_MESSAGE_COMPRESSION, + Id.choice.compression.zlib); + } + + public void setDefaultMessageCompression(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Constants.pref.DEFAULT_MESSAGE_COMPRESSION, value); + editor.commit(); + } + + public int getDefaultFileCompression() { + return mSharedPreferences.getInt(Constants.pref.DEFAULT_FILE_COMPRESSION, + Id.choice.compression.none); + } + + public void setDefaultFileCompression(int value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putInt(Constants.pref.DEFAULT_FILE_COMPRESSION, value); + editor.commit(); + } + + public boolean getDefaultAsciiArmour() { + return mSharedPreferences.getBoolean(Constants.pref.DEFAULT_ASCII_ARMOUR, false); + } + + public void setDefaultAsciiArmour(boolean value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putBoolean(Constants.pref.DEFAULT_ASCII_ARMOUR, value); + editor.commit(); + } + + public boolean getForceV3Signatures() { + return mSharedPreferences.getBoolean(Constants.pref.FORCE_V3_SIGNATURES, false); + } + + public void setForceV3Signatures(boolean value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.putBoolean(Constants.pref.FORCE_V3_SIGNATURES, value); + editor.commit(); + } + + public String[] getKeyServers() { + String rawData = mSharedPreferences.getString(Constants.pref.KEY_SERVERS, + Constants.defaults.KEY_SERVERS); + Vector servers = new Vector(); + String chunks[] = rawData.split(","); + for (int i = 0; i < chunks.length; ++i) { + String tmp = chunks[i].trim(); + if (tmp.length() > 0) { + servers.add(tmp); + } + } + return servers.toArray(chunks); + } + + public void setKeyServers(String[] value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + String rawData = ""; + for (int i = 0; i < value.length; ++i) { + String tmp = value[i].trim(); + if (tmp.length() == 0) { + continue; + } + if (!"".equals(rawData)) { + rawData += ","; + } + rawData += tmp; + } + editor.putString(Constants.pref.KEY_SERVERS, rawData); + editor.commit(); + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java b/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java index d38d0391f..9325268fa 100644 --- a/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java +++ b/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java @@ -14,8 +14,8 @@ package org.thialfihar.android.apg.passphrase; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import android.app.Service; import android.content.Context; diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java index ca9d7a817..43b13ba77 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java +++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java @@ -30,11 +30,11 @@ import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.ProgressDialogUpdater; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.helper.FileHelper; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.helper.PGPHelper.GeneralException; import org.thialfihar.android.apg.helper.PGPConversionHelper; import org.thialfihar.android.apg.provider.DataProvider; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java index 39fc30347..fb61cb427 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java @@ -23,10 +23,10 @@ import java.io.IOException; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.PausableThread; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.ProgressDialogUpdater; +import org.thialfihar.android.apg.deprecated.PausableThread; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.passphrase.AskForPassphrase; import org.thialfihar.android.apg.passphrase.PassphraseCacheService; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java index a19f6c5b6..a753eada0 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java @@ -16,17 +16,11 @@ package org.thialfihar.android.apg.ui; -import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.PausableThread; import org.thialfihar.android.apg.helper.FileHelper; import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.OtherHelper; -import org.thialfihar.android.apg.helper.PGPHelper.GeneralException; -import org.thialfihar.android.apg.provider.DataProvider; import org.thialfihar.android.apg.service.ApgHandler; import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment; @@ -34,7 +28,6 @@ import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment; import org.thialfihar.android.apg.util.Compatibility; -import org.thialfihar.android.apg.util.InputData; import org.thialfihar.android.apg.R; import com.actionbarsherlock.app.ActionBar; @@ -45,7 +38,6 @@ import com.actionbarsherlock.view.MenuItem; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; -import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; @@ -73,12 +65,16 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; -import java.security.Security; -import java.security.SignatureException; import java.util.regex.Matcher; public class DecryptActivity extends SherlockFragmentActivity { + + // possible intent actions for this activity + public static final String ACTION_DECRYPT = Constants.INTENT_PREFIX + "DECRYPT"; + public static final String ACTION_DECRYPT_FILE = Constants.INTENT_PREFIX + "DECRYPT_FILE"; + public static final String ACTION_DECRYPT_AND_RETURN = Constants.INTENT_PREFIX + + "DECRYPT_AND_RETURN"; + private long mSignatureKeyId = 0; private Intent mIntent; @@ -191,7 +187,7 @@ public class DecryptActivity extends SherlockFragmentActivity { final ActionBar actionBar = getSupportActionBar(); Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)=" + getCallingPackage()); - if (getCallingPackage() != null && getCallingPackage().equals(PGPHelper.PACKAGE_NAME)) { + if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); } else { @@ -282,7 +278,7 @@ public class DecryptActivity extends SherlockFragmentActivity { } catch (IOException e) { // ignore, then } - } else if (PGPHelper.Intent.DECRYPT.equals(mIntent.getAction())) { + } else if (ACTION_DECRYPT.equals(mIntent.getAction())) { Log.d(Constants.TAG, "Apg Intent DECRYPT startet"); Bundle extras = mIntent.getExtras(); if (extras == null) { @@ -328,7 +324,7 @@ public class DecryptActivity extends SherlockFragmentActivity { } mReplyTo = extras.getString(PGPHelper.EXTRA_REPLY_TO); mSubject = extras.getString(PGPHelper.EXTRA_SUBJECT); - } else if (PGPHelper.Intent.DECRYPT_FILE.equals(mIntent.getAction())) { + } else if (ACTION_DECRYPT_FILE.equals(mIntent.getAction())) { mInputFilename = mIntent.getDataString(); if ("file".equals(mIntent.getScheme())) { mInputFilename = Uri.decode(mInputFilename.substring(7)); @@ -340,7 +336,7 @@ public class DecryptActivity extends SherlockFragmentActivity { while (mSource.getCurrentView().getId() != R.id.sourceFile) { mSource.showNext(); } - } else if (PGPHelper.Intent.DECRYPT_AND_RETURN.equals(mIntent.getAction())) { + } else if (ACTION_DECRYPT_AND_RETURN.equals(mIntent.getAction())) { mContentUri = mIntent.getData(); Bundle extras = mIntent.getExtras(); if (extras == null) { @@ -405,7 +401,7 @@ public class DecryptActivity extends SherlockFragmentActivity { PGPPublicKeyRing key = PGPHelper.getPublicKeyRing(mSignatureKeyId); if (key != null) { Intent intent = new Intent(DecryptActivity.this, KeyServerQueryActivity.class); - intent.setAction(PGPHelper.Intent.LOOK_UP_KEY_ID); + intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID); intent.putExtra(PGPHelper.EXTRA_KEY_ID, mSignatureKeyId); startActivity(intent); } @@ -521,7 +517,7 @@ public class DecryptActivity extends SherlockFragmentActivity { mSignedOnly = false; getDecryptionKeyFromInputStream(); - + Log.d(Constants.TAG, "secretKeyId: " + getSecretKeyId()); // if we need a symmetric passphrase or a passphrase to use a sekret key ask for it @@ -633,7 +629,7 @@ public class DecryptActivity extends SherlockFragmentActivity { private void replyClicked() { Intent intent = new Intent(this, EncryptActivity.class); - intent.setAction(PGPHelper.Intent.ENCRYPT); + intent.setAction(EncryptActivity.ACTION_ENCRYPT); String data = mMessage.getText().toString(); data = data.replaceAll("(?m)^", "> "); data = "\n\n" + data; @@ -1047,7 +1043,7 @@ public class DecryptActivity extends SherlockFragmentActivity { public void onClick(DialogInterface dialog, int id) { removeDialog(Id.dialog.lookup_unknown_key); Intent intent = new Intent(DecryptActivity.this, KeyServerQueryActivity.class); - intent.setAction(PGPHelper.Intent.LOOK_UP_KEY_ID); + intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID); intent.putExtra(PGPHelper.EXTRA_KEY_ID, mUnknownSignatureKeyId); startActivityForResult(intent, Id.request.look_up_key_id); } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java index 7870a80c3..6ceca2004 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java @@ -64,6 +64,11 @@ import java.util.Iterator; import java.util.Vector; public class EditKeyActivity extends SherlockFragmentActivity { + + // possible intent actions for this activity + public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY"; + public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEY"; + private Intent mIntent = null; private ActionBar mActionBar; @@ -133,7 +138,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { mActionBar.setDisplayShowTitleEnabled(true); // set actionbar without home button if called from another app - if (getCallingPackage() != null && getCallingPackage().equals(PGPHelper.PACKAGE_NAME)) { + if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) { mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setHomeButtonEnabled(true); } else { @@ -154,8 +159,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { // Handle intents Bundle extras = mIntent.getExtras(); - if (PGPHelper.Intent.CREATE_KEY.equals(mIntent.getAction())) { - + if (ACTION_CREATE_KEY.equals(mIntent.getAction())) { mActionBar.setTitle(R.string.title_createKey); mCurrentPassPhrase = ""; @@ -244,8 +248,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { } } } - } else if (PGPHelper.Intent.EDIT_KEY.equals(mIntent.getAction())) { - + } else if (ACTION_EDIT_KEY.equals(mIntent.getAction())) { mActionBar.setTitle(R.string.title_editKey); mCurrentPassPhrase = PGPHelper.getEditPassPhrase(); @@ -468,8 +471,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { * @param userIdsView * @return */ - private Vector getUserIds(SectionView userIdsView) - throws PGPHelper.GeneralException { + private Vector getUserIds(SectionView userIdsView) throws PGPHelper.GeneralException { Vector userIds = new Vector(); ViewGroup userIdEditors = userIdsView.getEditors(); @@ -507,8 +509,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { } if (!gotMainUserId) { - throw new PGPHelper.GeneralException( - getString(R.string.error_mainUserIdMustNotBeEmpty)); + throw new PGPHelper.GeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty)); } return userIds; @@ -520,8 +521,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { * @param keysView * @return */ - private Vector getKeys(SectionView keysView) - throws PGPHelper.GeneralException { + private Vector getKeys(SectionView keysView) throws PGPHelper.GeneralException { Vector keys = new Vector(); ViewGroup keyEditors = keysView.getEditors(); @@ -544,8 +544,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { * @param keysView * @return */ - private Vector getKeysUsages(SectionView keysView) - throws PGPHelper.GeneralException { + private Vector getKeysUsages(SectionView keysView) throws PGPHelper.GeneralException { Vector getKeysUsages = new Vector(); ViewGroup keyEditors = keysView.getEditors(); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java index 2d365f926..d088cd11e 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java @@ -23,9 +23,9 @@ import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.helper.FileHelper; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.service.ApgHandler; import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment; @@ -67,6 +67,15 @@ import java.io.File; import java.util.Vector; public class EncryptActivity extends SherlockFragmentActivity { + + // possible intent actions for this activity + public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT"; + public static final String ACTION_ENCRYPT_FILE = Constants.INTENT_PREFIX + "ENCRYPT_FILE"; + public static final String ACTION_ENCRYPT_AND_RETURN = Constants.INTENT_PREFIX + + "ENCRYPT_AND_RETURN"; + public static final String ACTION_GENERATE_SIGNATURE = Constants.INTENT_PREFIX + + "GENERATE_SIGNATURE"; + private Intent mIntent = null; private String mSubject = null; private String mSendTo = null; @@ -185,7 +194,7 @@ public class EncryptActivity extends SherlockFragmentActivity { final ActionBar actionBar = getSupportActionBar(); Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)=" + getCallingPackage()); - if (getCallingPackage() != null && getCallingPackage().equals(PGPHelper.PACKAGE_NAME)) { + if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); } else { @@ -335,22 +344,22 @@ public class EncryptActivity extends SherlockFragmentActivity { }); mIntent = getIntent(); - if (PGPHelper.Intent.ENCRYPT.equals(mIntent.getAction()) - || PGPHelper.Intent.ENCRYPT_FILE.equals(mIntent.getAction()) - || PGPHelper.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) - || PGPHelper.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (ACTION_ENCRYPT.equals(mIntent.getAction()) + || ACTION_ENCRYPT_FILE.equals(mIntent.getAction()) + || ACTION_ENCRYPT_AND_RETURN.equals(mIntent.getAction()) + || ACTION_GENERATE_SIGNATURE.equals(mIntent.getAction())) { mContentUri = mIntent.getData(); Bundle extras = mIntent.getExtras(); if (extras == null) { extras = new Bundle(); } - if (PGPHelper.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) - || PGPHelper.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (ACTION_ENCRYPT_AND_RETURN.equals(mIntent.getAction()) + || ACTION_GENERATE_SIGNATURE.equals(mIntent.getAction())) { mReturnResult = true; } - if (PGPHelper.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (ACTION_GENERATE_SIGNATURE.equals(mIntent.getAction())) { mGenerateSignature = true; mOverrideAsciiArmour = true; mAsciiArmourDemand = false; @@ -411,9 +420,9 @@ public class EncryptActivity extends SherlockFragmentActivity { } } - if (PGPHelper.Intent.ENCRYPT.equals(mIntent.getAction()) - || PGPHelper.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) - || PGPHelper.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (ACTION_ENCRYPT.equals(mIntent.getAction()) + || ACTION_ENCRYPT_AND_RETURN.equals(mIntent.getAction()) + || ACTION_GENERATE_SIGNATURE.equals(mIntent.getAction())) { if (textData != null) { mMessage.setText(textData); } @@ -422,7 +431,7 @@ public class EncryptActivity extends SherlockFragmentActivity { while (mSource.getCurrentView().getId() != R.id.sourceMessage) { mSource.showNext(); } - } else if (PGPHelper.Intent.ENCRYPT_FILE.equals(mIntent.getAction())) { + } else if (ACTION_ENCRYPT_FILE.equals(mIntent.getAction())) { if ("file".equals(mIntent.getScheme())) { mInputFilename = Uri.decode(mIntent.getDataString().replace("file://", "")); mFilename.setText(mInputFilename); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/GeneralActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/GeneralActivity.java deleted file mode 100644 index dde247bdf..000000000 --- a/org_apg/src/org/thialfihar/android/apg/ui/GeneralActivity.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.ui; - -import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Vector; - -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.util.Choice; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.ListView; -import android.widget.Toast; - -public class GeneralActivity extends BaseActivity { - private Intent mIntent; - private ArrayAdapter mAdapter; - private ListView mList; - private Button mCancelButton; - private String mDataString; - private Uri mDataUri; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.general); - - mIntent = getIntent(); - - InputStream inStream = null; - { - String data = mIntent.getStringExtra(Intent.EXTRA_TEXT); - if (data != null) { - mDataString = data; - inStream = new ByteArrayInputStream(data.getBytes()); - } - } - - if (inStream == null) { - Uri data = mIntent.getData(); - if (data != null) { - mDataUri = data; - try { - inStream = getContentResolver().openInputStream(data); - } catch (FileNotFoundException e) { - // didn't work - Toast.makeText(this, "failed to open stream", Toast.LENGTH_SHORT).show(); - } - } - } - - if (inStream == null) { - Toast.makeText(this, "no data found", Toast.LENGTH_SHORT).show(); - finish(); - return; - } - - int contentType = Id.content.unknown; - try { - contentType = PGPHelper.getStreamContent(this, inStream); - inStream.close(); - } catch (IOException e) { - // just means that there's no PGP data in there - } - - mList = (ListView) findViewById(R.id.options); - Vector choices = new Vector(); - - if (contentType == Id.content.keys) { - choices.add(new Choice(Id.choice.action.import_public, - getString(R.string.action_importPublic))); - choices.add(new Choice(Id.choice.action.import_secret, - getString(R.string.action_importSecret))); - } - - if (contentType == Id.content.encrypted_data) { - choices.add(new Choice(Id.choice.action.decrypt, getString(R.string.action_decrypt))); - } - - if (contentType == Id.content.unknown) { - choices.add(new Choice(Id.choice.action.encrypt, getString(R.string.action_encrypt))); - } - - mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, choices); - mList.setAdapter(mAdapter); - - mList.setOnItemClickListener(new OnItemClickListener() { - public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { - clicked(mAdapter.getItem(arg2).getId()); - } - }); - - mCancelButton = (Button) findViewById(R.id.btn_cancel); - mCancelButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - GeneralActivity.this.finish(); - } - }); - - if (choices.size() == 1) { - clicked(choices.get(0).getId()); - } - } - - private void clicked(int id) { - Intent intent = new Intent(); - switch (id) { - case Id.choice.action.encrypt: { - intent.setClass(this, EncryptActivity.class); - if (mDataString != null) { - intent.setAction(PGPHelper.Intent.ENCRYPT); - intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); - } else if (mDataUri != null) { - intent.setAction(PGPHelper.Intent.ENCRYPT_FILE); - intent.setDataAndType(mDataUri, mIntent.getType()); - } - - break; - } - - case Id.choice.action.decrypt: { - intent.setClass(this, DecryptActivity.class); - if (mDataString != null) { - intent.setAction(PGPHelper.Intent.DECRYPT); - intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); - } else if (mDataUri != null) { - intent.setAction(PGPHelper.Intent.DECRYPT_FILE); - intent.setDataAndType(mDataUri, mIntent.getType()); - } - - break; - } - - case Id.choice.action.import_public: { - intent.setClass(this, PublicKeyListActivity.class); - intent.setAction(PGPHelper.Intent.IMPORT); - if (mDataString != null) { - intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); - } else if (mDataUri != null) { - intent.setDataAndType(mDataUri, mIntent.getType()); - } - break; - } - - case Id.choice.action.import_secret: { - intent.setClass(this, SecretKeyListActivity.class); - intent.setAction(PGPHelper.Intent.IMPORT); - if (mDataString != null) { - intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString); - } else if (mDataUri != null) { - intent.setDataAndType(mDataUri, mIntent.getType()); - } - break; - } - - default: { - // shouldn't happen - return; - } - } - - startActivity(intent); - finish(); - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java index c9fb89cc7..6eddc4ea3 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java @@ -22,10 +22,10 @@ import java.io.IOException; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.HkpKeyServer; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.KeyServer.QueryException; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.util.HkpKeyServer; +import org.thialfihar.android.apg.util.KeyServer.QueryException; import org.thialfihar.android.apg.R; import android.content.Intent; @@ -38,6 +38,11 @@ import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; public class ImportFromQRCodeActivity extends BaseActivity { + + // Not used in sourcode, but listed in AndroidManifest! + public static final String IMPORT_FROM_QR_CODE = Constants.INTENT_PREFIX + + "IMPORT_FROM_QR_CODE"; + private static final String TAG = "ImportFromQRCodeActivity"; private final Bundle status = new Bundle(); @@ -52,34 +57,46 @@ public class ImportFromQRCodeActivity extends BaseActivity { private void importAndSign(final long keyId, final String expectedFingerprint) { if (expectedFingerprint != null && expectedFingerprint.length() > 0) { - + Thread t = new Thread() { @Override public void run() { try { // TODO: display some sort of spinner here while the user waits - - HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]); // TODO: there should be only 1 + + HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]); // TODO: + // there + // should + // be + // only + // 1 String encodedKey = server.get(keyId); - PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream(encodedKey.getBytes())); + PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream( + encodedKey.getBytes())); if (keyring != null && keyring instanceof PGPPublicKeyRing) { PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring; // make sure the fingerprints match before we cache this thing - String actualFingerprint = PGPHelper.convertToHex(publicKeyRing.getPublicKey().getFingerprint()); + String actualFingerprint = PGPHelper.convertToHex(publicKeyRing + .getPublicKey().getFingerprint()); if (expectedFingerprint.equals(actualFingerprint)) { // store the signed key in our local cache int retval = PGPHelper.storeKeyRingInCache(publicKeyRing); - if (retval != Id.return_value.ok && retval != Id.return_value.updated) { - status.putString(PGPHelper.EXTRA_ERROR, "Failed to store signed key in local cache"); + if (retval != Id.return_value.ok + && retval != Id.return_value.updated) { + status.putString(PGPHelper.EXTRA_ERROR, + "Failed to store signed key in local cache"); } else { - Intent intent = new Intent(ImportFromQRCodeActivity.this, SignKeyActivity.class); + Intent intent = new Intent(ImportFromQRCodeActivity.this, + SignKeyActivity.class); intent.putExtra(PGPHelper.EXTRA_KEY_ID, keyId); startActivityForResult(intent, Id.request.sign_key); } } else { - status.putString(PGPHelper.EXTRA_ERROR, "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key."); + status.putString( + PGPHelper.EXTRA_ERROR, + "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key."); } } } catch (QueryException e) { @@ -103,48 +120,52 @@ public class ImportFromQRCodeActivity extends BaseActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case IntentIntegrator.REQUEST_CODE: { - boolean debug = true; // TODO: remove this!!! - IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); - if (debug || (scanResult != null && scanResult.getFormatName() != null)) { - String[] bits = debug ? new String[] { "5993515643896327656", "0816 F68A 6816 68FB 01BF 2CA5 532D 3EB9 1E2F EDE8" } : scanResult.getContents().split(","); - if (bits.length != 2) { - return; // dont know how to handle this. Not a valid code - } - - long keyId = Long.parseLong(bits[0]); - String expectedFingerprint = bits[1]; - - importAndSign(keyId, expectedFingerprint); - - break; + case IntentIntegrator.REQUEST_CODE: { + boolean debug = true; // TODO: remove this!!! + IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, + data); + if (debug || (scanResult != null && scanResult.getFormatName() != null)) { + String[] bits = debug ? new String[] { "5993515643896327656", + "0816 F68A 6816 68FB 01BF 2CA5 532D 3EB9 1E2F EDE8" } : scanResult + .getContents().split(","); + if (bits.length != 2) { + return; // dont know how to handle this. Not a valid code } - } - - case Id.request.sign_key: { - // signals the end of processing. Signature was either applied, or it wasnt - status.putInt(Constants.extras.STATUS, Id.message.done); - - msg.setData(status); - sendMessage(msg); - + + long keyId = Long.parseLong(bits[0]); + String expectedFingerprint = bits[1]; + + importAndSign(keyId, expectedFingerprint); + break; } + } - default: { - super.onActivityResult(requestCode, resultCode, data); - } + case Id.request.sign_key: { + // signals the end of processing. Signature was either applied, or it wasnt + status.putInt(Constants.extras.STATUS, Id.message.done); + + msg.setData(status); + sendMessage(msg); + + break; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + } } } - + @Override public void doneCallback(Message msg) { super.doneCallback(msg); - + Bundle data = msg.getData(); String error = data.getString(PGPHelper.EXTRA_ERROR); if (error != null) { - Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT) + .show(); return; } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java index 8e2bcaecb..a96f6a21c 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java @@ -69,6 +69,9 @@ import java.io.OutputStream; import java.util.Vector; public class KeyListActivity extends BaseActivity { + + public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT"; + protected ExpandableListView mList; protected KeyListAdapter mListAdapter; protected View mFilterLayout; @@ -139,7 +142,7 @@ public class KeyListActivity extends BaseActivity { mListAdapter = new KeyListAdapter(this, searchString); mList.setAdapter(mListAdapter); - if (PGPHelper.Intent.IMPORT.equals(intent.getAction())) { + if (ACTION_IMPORT.equals(intent.getAction())) { if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { mImportFilename = Uri.decode(intent.getDataString().replace("file://", "")); } else { diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java index 17d80296b..df9f2c09c 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java @@ -19,10 +19,10 @@ package org.thialfihar.android.apg.ui; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.HkpKeyServer; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.util.HkpKeyServer; import com.actionbarsherlock.view.MenuItem; @@ -43,6 +43,10 @@ import android.widget.Toast; */ public class KeyServerExportActivity extends BaseActivity { + // Not used in sourcode, but listed in AndroidManifest! + public static final String ACTION_EXPORT_KEY_TO_SERVER = Constants.INTENT_PREFIX + + "EXPORT_KEY_TO_SERVER"; + private Button export; private Spinner keyServer; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java index 7a1b94335..cda362eaf 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java @@ -19,13 +19,13 @@ import java.util.Vector; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.HkpKeyServer; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.KeyServer.InsufficientQuery; -import org.thialfihar.android.apg.KeyServer.KeyInfo; -import org.thialfihar.android.apg.KeyServer.QueryException; -import org.thialfihar.android.apg.KeyServer.TooManyResponses; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.util.HkpKeyServer; +import org.thialfihar.android.apg.util.KeyServer.InsufficientQuery; +import org.thialfihar.android.apg.util.KeyServer.KeyInfo; +import org.thialfihar.android.apg.util.KeyServer.QueryException; +import org.thialfihar.android.apg.util.KeyServer.TooManyResponses; import com.actionbarsherlock.view.MenuItem; @@ -54,6 +54,12 @@ import android.widget.TextView; import android.widget.Toast; public class KeyServerQueryActivity extends BaseActivity { + + // possible intent actions for this activity + public static final String ACTION_LOOK_UP_KEY_ID = Constants.INTENT_PREFIX + "LOOK_UP_KEY_ID"; + public static final String ACTION_LOOK_UP_KEY_ID_AND_RETURN = Constants.INTENT_PREFIX + + "LOOK_UP_KEY_ID_AND_RETURN"; + private ListView mList; private EditText mQuery; private Button mSearch; @@ -121,8 +127,8 @@ public class KeyServerQueryActivity extends BaseActivity { }); Intent intent = getIntent(); - if (PGPHelper.Intent.LOOK_UP_KEY_ID.equals(intent.getAction()) - || PGPHelper.Intent.LOOK_UP_KEY_ID_AND_RETURN.equals(intent.getAction())) { + if (ACTION_LOOK_UP_KEY_ID.equals(intent.getAction()) + || ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(intent.getAction())) { long keyId = intent.getLongExtra(PGPHelper.EXTRA_KEY_ID, 0); if (keyId != 0) { String query = "0x" + PGPHelper.keyToHex(keyId); @@ -208,7 +214,7 @@ public class KeyServerQueryActivity extends BaseActivity { } } else if (mQueryType == Id.keyserver.get) { Intent orgIntent = getIntent(); - if (PGPHelper.Intent.LOOK_UP_KEY_ID_AND_RETURN.equals(orgIntent.getAction())) { + if (ACTION_LOOK_UP_KEY_ID_AND_RETURN.equals(orgIntent.getAction())) { if (mKeyData != null) { Intent intent = new Intent(); intent.putExtra(PGPHelper.EXTRA_TEXT, mKeyData); @@ -220,7 +226,7 @@ public class KeyServerQueryActivity extends BaseActivity { } else { if (mKeyData != null) { Intent intent = new Intent(this, PublicKeyListActivity.class); - intent.setAction(PGPHelper.Intent.IMPORT); + intent.setAction(KeyListActivity.ACTION_IMPORT); intent.putExtra(PGPHelper.EXTRA_TEXT, mKeyData); startActivity(intent); } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java index fd8efb530..d79d067d4 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java @@ -20,8 +20,8 @@ import java.util.Vector; import java.util.regex.Matcher; import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import android.app.ListActivity; import android.content.Context; @@ -149,7 +149,7 @@ public class MailListActivity extends ListActivity { getListView().setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView arg0, View v, int position, long id) { Intent intent = new Intent(MailListActivity.this, DecryptActivity.class); - intent.setAction(PGPHelper.Intent.DECRYPT); + intent.setAction(DecryptActivity.ACTION_DECRYPT); Message message = (Message) ((MailboxAdapter) getListAdapter()).getItem(position); intent.putExtra(PGPHelper.EXTRA_TEXT, message.data); intent.putExtra(PGPHelper.EXTRA_SUBJECT, message.subject); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java index 24d636627..465daf5c9 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java @@ -48,19 +48,19 @@ public class MainActivity extends SherlockActivity { public void encryptOnClick(View view) { Intent intent = new Intent(MainActivity.this, EncryptActivity.class); - intent.setAction(PGPHelper.Intent.ENCRYPT); + intent.setAction(EncryptActivity.ACTION_ENCRYPT); startActivityForResult(intent, 0); // used instead of startActivity to get callingPackage } public void decryptOnClick(View view) { Intent intent = new Intent(MainActivity.this, DecryptActivity.class); - intent.setAction(PGPHelper.Intent.DECRYPT); + intent.setAction(DecryptActivity.ACTION_DECRYPT); startActivityForResult(intent, 0); // used instead of startActivity to get callingPackage } public void scanQrcodeOnClick(View view) { Intent intent = new Intent(this, ImportFromQRCodeActivity.class); - intent.setAction(PGPHelper.Intent.IMPORT_FROM_QR_CODE); + intent.setAction(ImportFromQRCodeActivity.IMPORT_FROM_QR_CODE); startActivityForResult(intent, Id.request.import_from_qr_code); } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java index 3cc6155b0..837976fee 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java @@ -20,8 +20,8 @@ import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.openpgp.PGPEncryptedData; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.passphrase.PassphraseCacheService; import org.thialfihar.android.apg.ui.widget.IntegerListPreference; import org.thialfihar.android.apg.R; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java index 21a7ddee5..9e11cc85c 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java @@ -71,7 +71,7 @@ public class PublicKeyListActivity extends KeyListActivity { } case Id.menu.option.scanQRCode: { Intent intent = new Intent(this, ImportFromQRCodeActivity.class); - intent.setAction(PGPHelper.Intent.IMPORT_FROM_QR_CODE); + intent.setAction(ImportFromQRCodeActivity.IMPORT_FROM_QR_CODE); startActivityForResult(intent, Id.request.import_from_qr_code); return true; @@ -124,7 +124,7 @@ public class PublicKeyListActivity extends KeyListActivity { } Intent intent = new Intent(this, KeyServerQueryActivity.class); - intent.setAction(PGPHelper.Intent.LOOK_UP_KEY_ID_AND_RETURN); + intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID_AND_RETURN); intent.putExtra(PGPHelper.EXTRA_KEY_ID, keyId); startActivityForResult(intent, Id.request.look_up_key_id); @@ -136,7 +136,7 @@ public class PublicKeyListActivity extends KeyListActivity { final int keyRingId = mListAdapter.getKeyRingId(groupPosition); Intent intent = new Intent(this, KeyServerExportActivity.class); - intent.setAction(PGPHelper.Intent.EXPORT_KEY_TO_SERVER); + intent.setAction(KeyServerExportActivity.ACTION_EXPORT_KEY_TO_SERVER); intent.putExtra(PGPHelper.EXTRA_KEY_ID, keyRingId); startActivityForResult(intent, Id.request.export_to_server); @@ -180,7 +180,7 @@ public class PublicKeyListActivity extends KeyListActivity { } Intent intent = new Intent(this, PublicKeyListActivity.class); - intent.setAction(PGPHelper.Intent.IMPORT); + intent.setAction(PublicKeyListActivity.ACTION_IMPORT); intent.putExtra(PGPHelper.EXTRA_TEXT, data.getStringExtra(PGPHelper.EXTRA_TEXT)); handleIntent(intent); break; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java index 290fe7479..ad51ce4da 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java @@ -164,13 +164,13 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli private void createKey() { PGPHelper.setEditPassPhrase(""); - Intent intent = new Intent(PGPHelper.Intent.CREATE_KEY); + Intent intent = new Intent(EditKeyActivity.ACTION_CREATE_KEY); startActivityForResult(intent, Id.message.create_key); } private void editKey() { long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); - Intent intent = new Intent(PGPHelper.Intent.EDIT_KEY); + Intent intent = new Intent(EditKeyActivity.ACTION_EDIT_KEY); intent.putExtra(PGPHelper.EXTRA_KEY_ID, keyId); startActivityForResult(intent, Id.message.edit_key); } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java index 93434912d..5330e1573 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java @@ -18,6 +18,7 @@ package org.thialfihar.android.apg.ui; import java.util.Vector; +import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.helper.PGPHelper; @@ -37,6 +38,11 @@ import android.widget.ListView; import android.widget.TextView; public class SelectPublicKeyListActivity extends BaseActivity { + + // Not used in sourcode, but listed in AndroidManifest! + public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX + + "SELECT_PUBLIC_KEYS"; + protected ListView mList; protected SelectPublicKeyListAdapter mListAdapter; protected View mFilterLayout; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java index 1f5607d94..41ea57bc6 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java @@ -16,6 +16,7 @@ package org.thialfihar.android.apg.ui; +import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.helper.PGPHelper; @@ -36,6 +37,11 @@ import android.widget.ListView; import android.widget.TextView; public class SelectSecretKeyListActivity extends BaseActivity { + + // Not used in sourcode, but listed in AndroidManifest! + public static final String ACTION_SELECT_SECRET_KEY = Constants.INTENT_PREFIX + + "SELECT_SECRET_KEY"; + protected ListView mList; protected SelectSecretKeyListAdapter mListAdapter; protected View mFilterLayout; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java index 43c481a74..df18b1d26 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java @@ -33,10 +33,10 @@ import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketVector; import org.spongycastle.openpgp.PGPUtil; import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.HkpKeyServer; import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.util.HkpKeyServer; import com.actionbarsherlock.view.MenuItem; diff --git a/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java b/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java new file mode 100644 index 000000000..38f3e2dc3 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2011 Senecaso + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.thialfihar.android.apg.helper.PGPHelper; + +import android.text.Html; + +public class HkpKeyServer extends KeyServer { + private static class HttpError extends Exception { + private static final long serialVersionUID = 1718783705229428893L; + private int mCode; + private String mData; + + public HttpError(int code, String data) { + super("" + code + ": " + data); + mCode = code; + mData = data; + } + + public int getCode() { + return mCode; + } + + public String getData() { + return mData; + } + } + + private String mHost; + private short mPort = 11371; + + // example: + // pub 2048R/9F5C9090 2009-08-17 Jörg Runge + // <joerg@joergrunge.de> + public static Pattern PUB_KEY_LINE = Pattern + .compile( + "pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", + Pattern.CASE_INSENSITIVE); + public static Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE + | Pattern.CASE_INSENSITIVE); + + public HkpKeyServer(String host) { + mHost = host; + } + + public HkpKeyServer(String host, short port) { + mHost = host; + mPort = port; + } + + static private String readAll(InputStream in, String encoding) throws IOException { + ByteArrayOutputStream raw = new ByteArrayOutputStream(); + + byte buffer[] = new byte[1 << 16]; + int n = 0; + while ((n = in.read(buffer)) != -1) { + raw.write(buffer, 0, n); + } + + if (encoding == null) { + encoding = "utf8"; + } + return raw.toString(encoding); + } + + // TODO: replace this with httpclient + private String query(String request) throws QueryException, HttpError { + InetAddress ips[]; + try { + ips = InetAddress.getAllByName(mHost); + } catch (UnknownHostException e) { + throw new QueryException(e.toString()); + } + for (int i = 0; i < ips.length; ++i) { + try { + String url = "http://" + ips[i].getHostAddress() + ":" + mPort + request; + URL realUrl = new URL(url); + HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(25000); + conn.connect(); + int response = conn.getResponseCode(); + if (response >= 200 && response < 300) { + return readAll(conn.getInputStream(), conn.getContentEncoding()); + } else { + String data = readAll(conn.getErrorStream(), conn.getContentEncoding()); + throw new HttpError(response, data); + } + } catch (MalformedURLException e) { + // nothing to do, try next IP + } catch (IOException e) { + // nothing to do, try next IP + } + } + + throw new QueryException("querying server(s) for '" + mHost + "' failed"); + } + + // TODO: replace this with httpclient + @Override + public List search(String query) throws QueryException, TooManyResponses, + InsufficientQuery { + Vector results = new Vector(); + + if (query.length() < 3) { + throw new InsufficientQuery(); + } + + String encodedQuery; + try { + encodedQuery = URLEncoder.encode(query, "utf8"); + } catch (UnsupportedEncodingException e) { + return null; + } + String request = "/pks/lookup?op=index&search=" + encodedQuery; + + String data = null; + try { + data = query(request); + } catch (HttpError e) { + if (e.getCode() == 404) { + return results; + } else { + if (e.getData().toLowerCase().contains("no keys found")) { + return results; + } else if (e.getData().toLowerCase().contains("too many")) { + throw new TooManyResponses(); + } else if (e.getData().toLowerCase().contains("insufficient")) { + throw new InsufficientQuery(); + } + } + throw new QueryException("querying server(s) for '" + mHost + "' failed"); + } + + Matcher matcher = PUB_KEY_LINE.matcher(data); + while (matcher.find()) { + KeyInfo info = new KeyInfo(); + info.size = Integer.parseInt(matcher.group(1)); + info.algorithm = matcher.group(2); + info.keyId = PGPHelper.keyFromHex(matcher.group(3)); + info.fingerPrint = PGPHelper.getSmallFingerPrint(info.keyId); + String chunks[] = matcher.group(4).split("-"); + info.date = new GregorianCalendar(Integer.parseInt(chunks[0]), + Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime(); + info.userIds = new Vector(); + if (matcher.group(5).startsWith("*** KEY")) { + info.revoked = matcher.group(5); + } else { + String tmp = matcher.group(5).replaceAll("<.*?>", ""); + tmp = Html.fromHtml(tmp).toString(); + info.userIds.add(tmp); + } + if (matcher.group(6).length() > 0) { + Matcher matcher2 = USER_ID_LINE.matcher(matcher.group(6)); + while (matcher2.find()) { + String tmp = matcher2.group(1).replaceAll("<.*?>", ""); + tmp = Html.fromHtml(tmp).toString(); + info.userIds.add(tmp); + } + } + results.add(info); + } + + return results; + } + + @Override + public String get(long keyId) throws QueryException { + HttpClient client = new DefaultHttpClient(); + try { + HttpGet get = new HttpGet("http://" + mHost + ":" + mPort + + "/pks/lookup?op=get&search=0x" + PGPHelper.keyToHex(keyId)); + + HttpResponse response = client.execute(get); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + throw new QueryException("not found"); + } + + HttpEntity entity = response.getEntity(); + InputStream is = entity.getContent(); + String data = readAll(is, EntityUtils.getContentCharSet(entity)); + Matcher matcher = PGPHelper.PGP_PUBLIC_KEY.matcher(data); + if (matcher.find()) { + return matcher.group(1); + } + } catch (IOException e) { + // nothing to do, better luck on the next keyserver + } finally { + client.getConnectionManager().shutdown(); + } + + return null; + } + + @Override + public void add(String armouredText) throws AddKeyException { + HttpClient client = new DefaultHttpClient(); + try { + HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add"); + + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("keytext", armouredText)); + post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + HttpResponse response = client.execute(post); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + throw new AddKeyException(); + } + } catch (IOException e) { + // nothing to do, better luck on the next keyserver + } finally { + client.getConnectionManager().shutdown(); + } + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/util/KeyServer.java b/org_apg/src/org/thialfihar/android/apg/util/KeyServer.java new file mode 100644 index 000000000..56a5fd8c1 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/util/KeyServer.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 Senecaso + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.util; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.Vector; + +public abstract class KeyServer { + static public class QueryException extends Exception { + private static final long serialVersionUID = 2703768928624654512L; + + public QueryException(String message) { + super(message); + } + } + + static public class TooManyResponses extends Exception { + private static final long serialVersionUID = 2703768928624654513L; + } + + static public class InsufficientQuery extends Exception { + private static final long serialVersionUID = 2703768928624654514L; + } + + static public class AddKeyException extends Exception { + private static final long serialVersionUID = -507574859137295530L; + } + + static public class KeyInfo implements Serializable { + private static final long serialVersionUID = -7797972113284992662L; + public Vector userIds; + public String revoked; + public Date date; + public String fingerPrint; + public long keyId; + public int size; + public String algorithm; + } + + abstract List search(String query) throws QueryException, TooManyResponses, + InsufficientQuery; + + abstract String get(long keyId) throws QueryException; + + abstract void add(String armouredText) throws AddKeyException; +} -- cgit v1.2.3