From a5d85b367dd885221f3f36eca82bfb3ec2b701c4 Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Sun, 22 Jun 2014 19:43:36 +0100 Subject: add OpenPGP-Haskell to test collateral --- OpenKeychain/src/test/resources/extern/OpenPGP-Haskell | 1 + 1 file changed, 1 insertion(+) create mode 160000 OpenKeychain/src/test/resources/extern/OpenPGP-Haskell (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/test/resources/extern/OpenPGP-Haskell b/OpenKeychain/src/test/resources/extern/OpenPGP-Haskell new file mode 160000 index 000000000..eba7e4fdc --- /dev/null +++ b/OpenKeychain/src/test/resources/extern/OpenPGP-Haskell @@ -0,0 +1 @@ +Subproject commit eba7e4fdce3de6622b4ec3862b405b0acd016377 -- cgit v1.2.3 From 13f785d0b04582bf4ccde97ab21eef40824df09d Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Sun, 22 Jun 2014 20:40:29 +0100 Subject: borrow tests from Haskell OpenPGP --- .../keychain/testsupport/KeyringTestingHelper.java | 10 ++-- .../keychain/testsupport/TestDataUtil.java | 21 ++++++- .../test/java/tests/ProviderHelperKeyringTest.java | 68 +++++++++++++++++++++- 3 files changed, 92 insertions(+), 7 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/KeyringTestingHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/KeyringTestingHelper.java index d4bc6c541..a565f0707 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/KeyringTestingHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/KeyringTestingHelper.java @@ -5,9 +5,10 @@ import android.content.Context; import org.sufficientlysecure.keychain.pgp.NullProgressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.service.OperationResults; +import java.util.Collection; + /** * Helper for tests of the Keyring import in ProviderHelper. */ @@ -19,13 +20,11 @@ public class KeyringTestingHelper { this.context = robolectricContext; } - public boolean addKeyring() throws Exception { + public boolean addKeyring(Collection blobFiles) throws Exception { ProviderHelper providerHelper = new ProviderHelper(context); -// providerHelper.insertApiApp(new AppSettings("robo-test-package", new byte[]{5, 4, 3, 2, 1})); - - byte[] data = TestDataUtil.readFully(getClass().getResourceAsStream("/public-key-for-sample.blob")); + byte[] data = TestDataUtil.readAllFully(blobFiles); UncachedKeyRing ring = UncachedKeyRing.decodeFromData(data); long masterKeyId = ring.getMasterKeyId(); @@ -45,6 +44,7 @@ public class KeyringTestingHelper { return saveSuccess; } + private void retrieveKeyAndExpectNotFound(ProviderHelper providerHelper, long masterKeyId) { try { providerHelper.getWrappedPublicKeyRing(masterKeyId); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/TestDataUtil.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/TestDataUtil.java index 06dc08eab..9e6ede761 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/TestDataUtil.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/testsupport/TestDataUtil.java @@ -3,6 +3,7 @@ package org.sufficientlysecure.keychain.testsupport; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Collection; /** * Misc support functions. Would just use Guava / Apache Commons but @@ -10,9 +11,14 @@ import java.io.InputStream; */ public class TestDataUtil { public static byte[] readFully(InputStream input) { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + appendToOutput(input, output); + return output.toByteArray(); + } + + private static void appendToOutput(InputStream input, ByteArrayOutputStream output) { byte[] buffer = new byte[8192]; int bytesRead; - ByteArrayOutputStream output = new ByteArrayOutputStream(); try { while ((bytesRead = input.read(buffer)) != -1) { output.write(buffer, 0, bytesRead); @@ -20,6 +26,19 @@ public class TestDataUtil { } catch (IOException e) { throw new RuntimeException(e); } + } + + public static byte[] readAllFully(Collection inputResources) { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + + for (String inputResource : inputResources) { + appendToOutput(getResourceAsStream(inputResource), output); + } return output.toByteArray(); } + + + public static InputStream getResourceAsStream(String resourceName) { + return TestDataUtil.class.getResourceAsStream(resourceName); + } } diff --git a/OpenKeychain/src/test/java/tests/ProviderHelperKeyringTest.java b/OpenKeychain/src/test/java/tests/ProviderHelperKeyringTest.java index 265e01170..3d48c2f97 100644 --- a/OpenKeychain/src/test/java/tests/ProviderHelperKeyringTest.java +++ b/OpenKeychain/src/test/java/tests/ProviderHelperKeyringTest.java @@ -1,5 +1,10 @@ package tests; +import java.util.Collections; +import java.util.Arrays; +import java.util.Collection; +import java.util.ArrayList; + import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -14,7 +19,68 @@ public class ProviderHelperKeyringTest { @Test public void testSavePublicKeyring() throws Exception { - Assert.assertTrue(new KeyringTestingHelper(Robolectric.application).addKeyring()); + Assert.assertTrue(new KeyringTestingHelper(Robolectric.application).addKeyring(Collections.singleton( + "/public-key-for-sample.blob" + ))); + } + + @Test + public void testSavePublicKeyringRsa() throws Exception { + Assert.assertTrue(new KeyringTestingHelper(Robolectric.application).addKeyring(prependResourcePath(Arrays.asList( + "000001-006.public_key", + "000002-013.user_id", + "000003-002.sig", + "000004-012.ring_trust", + "000005-002.sig", + "000006-012.ring_trust", + "000007-002.sig", + "000008-012.ring_trust", + "000009-002.sig", + "000010-012.ring_trust", + "000011-002.sig", + "000012-012.ring_trust", + "000013-014.public_subkey", + "000014-002.sig", + "000015-012.ring_trust" + )))); } + @Test + public void testSavePublicKeyringDsa() throws Exception { + Assert.assertTrue(new KeyringTestingHelper(Robolectric.application).addKeyring(prependResourcePath(Arrays.asList( + "000016-006.public_key", + "000017-002.sig", + "000018-012.ring_trust", + "000019-013.user_id", + "000020-002.sig", + "000021-012.ring_trust", + "000022-002.sig", + "000023-012.ring_trust", + "000024-014.public_subkey", + "000025-002.sig", + "000026-012.ring_trust" + )))); + } + + @Test + public void testSavePublicKeyringDsa2() throws Exception { + Assert.assertTrue(new KeyringTestingHelper(Robolectric.application).addKeyring(prependResourcePath(Arrays.asList( + "000027-006.public_key", + "000028-002.sig", + "000029-012.ring_trust", + "000030-013.user_id", + "000031-002.sig", + "000032-012.ring_trust", + "000033-002.sig", + "000034-012.ring_trust" + )))); + } + + private static Collection prependResourcePath(Collection files) { + Collection prependedFiles = new ArrayList(); + for (String file: files) { + prependedFiles.add("/extern/OpenPGP-Haskell/tests/data/" + file); + } + return prependedFiles; + } } -- cgit v1.2.3 From b92a389ebcf372ed7c3c8debe0776d9c426b2ce7 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Mon, 23 Jun 2014 01:59:20 +0200 Subject: Add TlsHelper (designed to be used with sks-keyservers.net) We can't use the AndroidPinning library for this, because it requires the certificate to be signed using a system CA, sks-keyservers.net uses there own CA --- .../keychain/helper/TlsHelper.java | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java new file mode 100644 index 000000000..96df7cf2f --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.helper; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.*; + +public class TlsHelper { + public static class TlsHelperException extends Exception { + public TlsHelperException(Exception e) { + super(e); + } + } + + /** + * Opens a Connection that will only accept certificates signed with a specific CA and skips common name check. + * This is required for some distributed Keyserver networks like sks-keyservers.net + * + * @param certificate The X.509 certificate used to sign the servers certificate + * @param url Connection target + */ + public static HttpsURLConnection openCAConnection(byte[] certificate, URL url) + throws TlsHelperException, IOException { + try { + // Load CA + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate ca = cf.generateCertificate(new ByteArrayInputStream(certificate)); + + // Create a KeyStore containing our trusted CAs + String keyStoreType = KeyStore.getDefaultType(); + KeyStore keyStore = KeyStore.getInstance(keyStoreType); + keyStore.load(null, null); + keyStore.setCertificateEntry("ca", ca); + + // Create a TrustManager that trusts the CAs in our KeyStore + String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); + tmf.init(keyStore); + + // Create an SSLContext that uses our TrustManager + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, tmf.getTrustManagers(), null); + + // Tell the URLConnection to use a SocketFactory from our SSLContext + HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); + urlConnection.setSSLSocketFactory(context.getSocketFactory()); + + return urlConnection; + } catch (CertificateException e) { + throw new TlsHelperException(e); + } catch (NoSuchAlgorithmException e) { + throw new TlsHelperException(e); + } catch (KeyStoreException e) { + throw new TlsHelperException(e); + } catch (KeyManagementException e) { + throw new TlsHelperException(e); + } + } +} -- cgit v1.2.3 From 3ebbaae253cee615a8e132c9967ad390926bb095 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Mon, 23 Jun 2014 22:25:42 +0200 Subject: Add hkps support for sks-keyservers.net --- .../org/sufficientlysecure/keychain/Constants.java | 35 +++++++ .../keychain/keyimport/HkpKeyserver.java | 107 ++++++++------------- 2 files changed, 77 insertions(+), 65 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 319ac2873..efb378bc8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -49,6 +49,41 @@ public final class Constants { public static final String CUSTOM_CONTACT_DATA_MIME_TYPE = "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.key"; + // TODO: Resource/Asset? + public static final String SKS_KEYSERVERS_NET_CA = + "-----BEGIN CERTIFICATE-----" + + "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" + + "-----END CERTIFICATE-----"; + public static boolean KITKAT = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; public static final class Path { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index 1949c9f19..a101d91d9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -22,32 +22,26 @@ import de.measite.minidns.Client; import de.measite.minidns.Question; import de.measite.minidns.Record; import de.measite.minidns.record.SRV; -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.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.helper.TlsHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.Log; 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.URLDecoder; import java.net.URLEncoder; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -200,48 +194,39 @@ public class HkpKeyserver extends Keyserver { return mSecure ? "https://" : "http://"; } - private String query(String request) throws QueryFailedException, HttpError { - List urls = new ArrayList(); - if (mSecure) { - urls.add(getUrlPrefix() + mHost + ":" + mPort + request); - } else { - InetAddress ips[]; + private HttpURLConnection openConnection(URL url) throws IOException { + HttpURLConnection conn = null; + if (mHost.endsWith("pool.sks-keyservers.net") && mSecure) { try { - ips = InetAddress.getAllByName(mHost); - } catch (UnknownHostException e) { - throw new QueryFailedException(e.toString()); - } - for (InetAddress ip : ips) { - // Note: This is actually not HTTP 1.1 compliant, as we hide the real "Host" value, - // but Android's HTTPUrlConnection does not support any other way to set - // Socket's remote IP address... - urls.add(getUrlPrefix() + ip.getHostAddress() + ":" + mPort + request); + conn = TlsHelper.openCAConnection(Constants.SKS_KEYSERVERS_NET_CA.getBytes(), url); + } catch (TlsHelper.TlsHelperException e) { + Log.w(Constants.TAG, e); } } + if (conn == null) { + conn = (HttpURLConnection) url.openConnection(); + } + conn.setConnectTimeout(5000); + conn.setReadTimeout(25000); + return conn; + } - for (String url : urls) { - try { - Log.d(Constants.TAG, "hkp keyserver query: " + url); - 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 + private String query(String request) throws QueryFailedException, HttpError { + try { + URL url = new URL(getUrlPrefix() + mHost + ":" + mPort + request); + Log.d(Constants.TAG, "hkp keyserver query: " + url); + HttpURLConnection conn = openConnection(url); + 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 (IOException e) { + throw new QueryFailedException("querying server(s) for '" + mHost + "' failed"); } - - throw new QueryFailedException("querying server(s) for '" + mHost + "' failed"); } @Override @@ -335,33 +320,25 @@ public class HkpKeyserver extends Keyserver { @Override public String get(String keyIdHex) throws QueryFailedException { - HttpClient client = new DefaultHttpClient(); + String query = getUrlPrefix() + mHost + ":" + mPort + + "/pks/lookup?op=get&options=mr&search=" + keyIdHex; + Log.d(Constants.TAG, "hkp keyserver get: " + query); + String data; try { - String query = getUrlPrefix() + mHost + ":" + mPort + - "/pks/lookup?op=get&options=mr&search=" + keyIdHex; - Log.d(Constants.TAG, "hkp keyserver get: " + query); - HttpGet get = new HttpGet(query); - HttpResponse response = client.execute(get); - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - throw new QueryFailedException("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(); + data = query(query); + } catch (HttpError httpError) { + throw new QueryFailedException("not found"); + } + Matcher matcher = PgpHelper.PGP_PUBLIC_KEY.matcher(data); + if (matcher.find()) { + return matcher.group(1); } - return null; } + /* + * TODO Use openConnection + */ @Override public void add(String armoredKey) throws AddKeyException { HttpClient client = new DefaultHttpClient(); -- cgit v1.2.3 From e6629b53a2b80ec0d94b102fc9e51d1431d258a4 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Mon, 23 Jun 2014 22:46:59 +0200 Subject: Few fixes on hkps TODO: Fix add as well --- .../org/sufficientlysecure/keychain/Constants.java | 62 +++++++++++----------- .../keychain/keyimport/HkpKeyserver.java | 7 ++- 2 files changed, 34 insertions(+), 35 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index efb378bc8..639b70043 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -51,37 +51,37 @@ public final class Constants { // TODO: Resource/Asset? public static final String SKS_KEYSERVERS_NET_CA = - "-----BEGIN CERTIFICATE-----" + - "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" + + "-----BEGIN CERTIFICATE-----\n" + + "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\n" + "-----END CERTIFICATE-----"; public static boolean KITKAT = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index a101d91d9..09bd34fc9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -320,12 +320,11 @@ public class HkpKeyserver extends Keyserver { @Override public String get(String keyIdHex) throws QueryFailedException { - String query = getUrlPrefix() + mHost + ":" + mPort + - "/pks/lookup?op=get&options=mr&search=" + keyIdHex; - Log.d(Constants.TAG, "hkp keyserver get: " + query); + String request = "/pks/lookup?op=get&options=mr&search=" + keyIdHex; + Log.d(Constants.TAG, "hkp keyserver get: " + request); String data; try { - data = query(query); + data = query(request); } catch (HttpError httpError) { throw new QueryFailedException("not found"); } -- cgit v1.2.3 From 9a7fc6d464dbcf8fb6c6fd1ca4df252f4e320f7c Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 24 Jun 2014 00:57:04 +0200 Subject: Rewrote hkp add to work with hkps as well. Also removes HttpClient dependency (deprecated for android) --- .../keychain/keyimport/HkpKeyserver.java | 37 ++++++++-------------- 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index 09bd34fc9..2af69c3d9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -18,24 +18,18 @@ package org.sufficientlysecure.keychain.keyimport; +import android.net.Uri; import de.measite.minidns.Client; import de.measite.minidns.Question; import de.measite.minidns.Record; import de.measite.minidns.record.SRV; -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.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.helper.TlsHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.util.Log; +import java.io.DataOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; @@ -46,7 +40,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.GregorianCalendar; -import java.util.List; import java.util.Locale; import java.util.TimeZone; import java.util.regex.Matcher; @@ -335,28 +328,24 @@ public class HkpKeyserver extends Keyserver { return null; } - /* - * TODO Use openConnection - */ @Override public void add(String armoredKey) throws AddKeyException { - HttpClient client = new DefaultHttpClient(); try { String query = getUrlPrefix() + mHost + ":" + mPort + "/pks/add"; - HttpPost post = new HttpPost(query); + String params = "keytext=" + Uri.encode(armoredKey); Log.d(Constants.TAG, "hkp keyserver add: " + query); - List nameValuePairs = new ArrayList(2); - nameValuePairs.add(new BasicNameValuePair("keytext", armoredKey)); - post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - HttpResponse response = client.execute(post); - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - throw new AddKeyException(); - } + HttpURLConnection connection = openConnection(new URL(query)); + connection.setRequestMethod("POST"); + connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.setRequestProperty("Content-Length", Integer.toString(params.getBytes().length)); + connection.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); + wr.writeBytes(params); + wr.flush(); + wr.close(); } catch (IOException e) { - // nothing to do, better luck on the next keyserver - } finally { - client.getConnectionManager().shutdown(); + throw new AddKeyException(); } } -- cgit v1.2.3 From f039ef81aebcaed1f321baa7734d57b1e58ffb15 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 24 Jun 2014 01:31:06 +0200 Subject: Use URLEncoder instead of Uri.encode --- .../org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index 2af69c3d9..56a5bc508 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.keyimport; -import android.net.Uri; import de.measite.minidns.Client; import de.measite.minidns.Question; import de.measite.minidns.Record; @@ -332,7 +331,12 @@ public class HkpKeyserver extends Keyserver { public void add(String armoredKey) throws AddKeyException { try { String query = getUrlPrefix() + mHost + ":" + mPort + "/pks/add"; - String params = "keytext=" + Uri.encode(armoredKey); + String params; + try { + params = "keytext=" + URLEncoder.encode(armoredKey, "utf8"); + } catch (UnsupportedEncodingException e) { + throw new AddKeyException(); + } Log.d(Constants.TAG, "hkp keyserver add: " + query); HttpURLConnection connection = openConnection(new URL(query)); -- cgit v1.2.3 From 04e64ac84e6cda3da380905eb36e1aa50810226a Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 24 Jun 2014 11:26:52 +0200 Subject: Update Keyservers to use hkps as needed --- .../org/sufficientlysecure/keychain/Constants.java | 4 +++- .../keychain/KeychainApplication.java | 5 ++++- .../keychain/helper/Preferences.java | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 639b70043..110a7f980 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -102,10 +102,12 @@ public final class Constants { public static final String LANGUAGE = "language"; public static final String FORCE_V3_SIGNATURES = "forceV3Signatures"; public static final String KEY_SERVERS = "keyServers"; + public static final String KEY_SERVERS_DEFAULT_VERSION = "keyServersDefaultVersion"; } public static final class Defaults { - public static final String KEY_SERVERS = "pool.sks-keyservers.net, subkeys.pgp.net, pgp.mit.edu"; + public static final String KEY_SERVERS = "hkps://pool.sks-keyservers.net, subkeys.pgp.net, hkps://pgp.mit.edu"; + public static final int KEY_SERVERS_VERSION = 2; } public static final class DrawerItems { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 5d6a62f9c..9d355564f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -26,7 +26,7 @@ import android.graphics.drawable.Drawable; import android.os.Environment; import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.sufficientlysecure.keychain.helper.ContactHelper; +import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PRNGFixes; @@ -81,6 +81,9 @@ public class KeychainApplication extends Application { getApplicationContext().getResources().getColor(R.color.emphasis)); setupAccountAsNeeded(this); + + // Update keyserver list as needed + Preferences.getPreferences(this).updateKeyServers(); } public static void setupAccountAsNeeded(Context context) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index c82c5e115..6f3d38ccd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -169,4 +169,22 @@ public class Preferences { editor.putString(Constants.Pref.KEY_SERVERS, rawData); editor.commit(); } + + public void updateKeyServers() { + if (mSharedPreferences.getInt(Constants.Pref.KEY_SERVERS_DEFAULT_VERSION, 0) != + Constants.Defaults.KEY_SERVERS_VERSION) { + String[] servers = getKeyServers(); + for (int i = 0; i < servers.length; i++) { + if (servers[i].equals("pool.sks-keyservers.net")) { + servers[i] = "hkps://hkps.pool.sks-keyservers.net"; + } else if (servers[i].equals("pgp.mit.edu")) { + servers[i] = "hkps://pgp.mit.edu"; + } + } + setKeyServers(servers); + mSharedPreferences.edit() + .putInt(Constants.Pref.KEY_SERVERS_DEFAULT_VERSION, Constants.Defaults.KEY_SERVERS_VERSION) + .commit(); + } + } } -- cgit v1.2.3 From 97de1592f05f9fbe2f23cd68ff9040db3f575ee0 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 24 Jun 2014 11:27:35 +0200 Subject: Fix sks-keyservers.net sub pool --- .../src/main/java/org/sufficientlysecure/keychain/Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 110a7f980..1ddb3d632 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -106,7 +106,7 @@ public final class Constants { } public static final class Defaults { - public static final String KEY_SERVERS = "hkps://pool.sks-keyservers.net, subkeys.pgp.net, hkps://pgp.mit.edu"; + public static final String KEY_SERVERS = "hkps://hkps.pool.sks-keyservers.net, subkeys.pgp.net, hkps://pgp.mit.edu"; public static final int KEY_SERVERS_VERSION = 2; } -- cgit v1.2.3 From e84aa5a69d0d6f17699ed2af2bcb0561b31ac90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 24 Jun 2014 13:54:24 +0200 Subject: Rename registered apps to apps --- OpenKeychain/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index e24ac6925..a6b16a421 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -10,7 +10,7 @@ Create Key Edit Key Preferences - Registered Applications + Apps Keyserver Preference Change Passphrase Set Passphrase @@ -476,7 +476,7 @@ Sign and Encrypt Decrypt and Verify Import Keys - Registered Apps + Apps Open navigation drawer Close navigation drawer Edit -- cgit v1.2.3 From 02bcd391bfcc2f1bef65353ad1933129730581af Mon Sep 17 00:00:00 2001 From: Daniel Albert Date: Tue, 24 Jun 2014 20:15:48 +0200 Subject: Fix for #687 --- .../org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java index eccd2a5e5..52b573f47 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java @@ -152,7 +152,11 @@ public class ViewKeyShareFragment extends LoaderFragment implements KeyRings.buildUnifiedKeyRingUri(dataUri), Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB); String fingerprint = PgpKeyHelper.convertFingerprintToHex(data); - content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; + if(!toClipboard){ + content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint; + } else { + content = fingerprint; + } } else { // get public keyring as ascii armored string Uri uri = KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri); -- cgit v1.2.3 From a1bcbe72a3c52d416b3dfe5c0cc96b65739641ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 24 Jun 2014 22:58:28 +0200 Subject: new edit key: first version to add user ids --- .../keychain/ui/EditKeyActivityNew.java | 25 ---- .../keychain/ui/EditKeyFragment.java | 18 ++- .../keychain/ui/adapter/UserIdsAdapter.java | 3 +- .../keychain/ui/adapter/UserIdsArrayAdapter.java | 131 +++++++++++++++++++++ .../ui/dialog/AddUserIdDialogFragment.java | 117 +++++++++++++----- .../src/main/res/layout/add_user_id_dialog.xml | 60 ++++++++++ .../src/main/res/layout/edit_key_fragment.xml | 10 ++ 7 files changed, 306 insertions(+), 58 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsArrayAdapter.java create mode 100644 OpenKeychain/src/main/res/layout/add_user_id_dialog.xml (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityNew.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityNew.java index f2b5e68eb..b45e8a6bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityNew.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityNew.java @@ -20,19 +20,13 @@ package org.sufficientlysecure.keychain.ui; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; -import android.view.View; -import android.view.View.OnClickListener; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; -import org.sufficientlysecure.keychain.remote.ui.AccountsListFragment; import org.sufficientlysecure.keychain.util.Log; public class EditKeyActivityNew extends ActionBarActivity { - private Uri mDataUri; - private EditKeyFragment mEditKeyFragment; @Override @@ -41,25 +35,6 @@ public class EditKeyActivityNew extends ActionBarActivity { setContentView(R.layout.edit_key_activity_new); -// // Inflate a "Done"/"Cancel" custom action bar view -// ActionBarHelper.setTwoButtonView(getSupportActionBar(), -// R.string.btn_save, R.drawable.ic_action_save, -// new OnClickListener() { -// @Override -// public void onClick(View v) { -// // Save -// -// } -// }, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel, -// new OnClickListener() { -// @Override -// public void onClick(View v) { -// // Cancel -// -// } -// } -// ); - Uri dataUri = getIntent().getData(); if (dataUri == null) { Log.e(Constants.TAG, "Data missing. Should be Uri of key!"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index ac4390eac..3f330ee94 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -27,6 +27,7 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v7.app.ActionBarActivity; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -45,6 +46,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; +import org.sufficientlysecure.keychain.ui.adapter.UserIdsArrayAdapter; import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; @@ -68,6 +70,7 @@ public class EditKeyFragment extends LoaderFragment implements private UserIdsAdapter mUserIdsAdapter; private SubkeysAdapter mKeysAdapter; + private UserIdsArrayAdapter mUserIdsAddedAdapter; private Uri mDataUri; @@ -180,6 +183,10 @@ public class EditKeyFragment extends LoaderFragment implements } }); + mUserIdsAddedAdapter = new UserIdsArrayAdapter(getActivity()); + mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter); + mUserIdsAddedAdapter.setData(mSaveKeyringParcel.addUserIds); + mKeysAdapter = new SubkeysAdapter(getActivity(), null, 0); mKeysList.setAdapter(mKeysAdapter); @@ -321,9 +328,17 @@ public class EditKeyFragment extends LoaderFragment implements Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { - if (message.what == AddUserIdDialogFragment.MESSAGE_OK) { + switch (message.what) { + case AddUserIdDialogFragment.MESSAGE_OKAY: + Bundle data = message.getData(); + String userId = data.getString(AddUserIdDialogFragment.MESSAGE_DATA_USER_ID); + if (userId != null) { + mSaveKeyringParcel.addUserIds.add(userId); + mUserIdsAddedAdapter.setData(mSaveKeyringParcel.addUserIds); + } } + getLoaderManager().getLoader(LOADER_ID_USER_IDS).forceLoad(); } }; @@ -345,5 +360,4 @@ public class EditKeyFragment extends LoaderFragment implements // TODO } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java index 7a7acfe89..7fc78dc41 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -144,7 +144,6 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC vComment.setVisibility(View.GONE); } - // show small star icon for primary user ids boolean isPrimary = cursor.getInt(mIsPrimary) != 0; boolean isRevoked = cursor.getInt(mIsRevoked) > 0; @@ -185,6 +184,8 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC vName.setEnabled(true); vAddress.setEnabled(true); + // verified: has been verified + // isPrimary: show small star icon for primary user ids int verified = cursor.getInt(mVerifiedId); switch (verified) { case Certs.VERIFIED_SECRET: diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsArrayAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsArrayAdapter.java new file mode 100644 index 000000000..e6445c074 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsArrayAdapter.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2013-2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui.adapter; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.KeyRing; + +import java.util.List; + +public class UserIdsArrayAdapter extends ArrayAdapter { + protected LayoutInflater mInflater; + protected Activity mActivity; + + protected List mData; + + static class ViewHolder { + public TextView vName; + public TextView vAddress; + public TextView vComment; + public ImageView vVerified; + public ImageView vHasChanges; + public CheckBox vCheckBox; + } + + public UserIdsArrayAdapter(Activity activity) { + super(activity, -1); + mActivity = activity; + mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public void setData(List data) { + clear(); + if (data != null) { + this.mData = data; + + // add data to extended ArrayAdapter + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + addAll(data); + } else { + for (String entry : data) { + add(entry); + } + } + } + } + + public List getData() { + return mData; + } + + @Override + public boolean hasStableIds() { + return true; + } + + public View getView(int position, View convertView, ViewGroup parent) { + String entry = mData.get(position); + ViewHolder holder; + if (convertView == null) { + holder = new ViewHolder(); + convertView = mInflater.inflate(R.layout.view_key_userids_item, null); + holder.vName = (TextView) convertView.findViewById(R.id.userId); + holder.vAddress = (TextView) convertView.findViewById(R.id.address); + holder.vComment = (TextView) convertView.findViewById(R.id.comment); + holder.vVerified = (ImageView) convertView.findViewById(R.id.certified); + holder.vHasChanges = (ImageView) convertView.findViewById(R.id.has_changes); + holder.vCheckBox = (CheckBox) convertView.findViewById(R.id.checkBox); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + // user id + String[] splitUserId = KeyRing.splitUserId(entry); + if (splitUserId[0] != null) { + holder.vName.setText(splitUserId[0]); + } else { + holder.vName.setText(R.string.user_id_no_name); + } + if (splitUserId[1] != null) { + holder.vAddress.setText(splitUserId[1]); + holder.vAddress.setVisibility(View.VISIBLE); + } else { + holder.vAddress.setVisibility(View.GONE); + } + if (splitUserId[2] != null) { + holder.vComment.setText(splitUserId[2]); + holder.vComment.setVisibility(View.VISIBLE); + } else { + holder.vComment.setVisibility(View.GONE); + } + + holder.vCheckBox.setVisibility(View.GONE); + + holder.vVerified.setImageResource(R.drawable.key_certify_ok_depth0); + + // all items are "new" + holder.vHasChanges.setVisibility(View.VISIBLE); + + return convertView; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java index db7c38e71..c27266e3f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java @@ -24,17 +24,32 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.DialogFragment; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.util.Log; -public class AddUserIdDialogFragment extends DialogFragment { +public class AddUserIdDialogFragment extends DialogFragment implements EditText.OnEditorActionListener { private static final String ARG_MESSENGER = "messenger"; - public static final int MESSAGE_OK = 1; + public static final int MESSAGE_OKAY = 1; + + public static final String MESSAGE_DATA_USER_ID = "user_id"; private Messenger mMessenger; + EditText mName; + EditText mAddress; + EditText mComment; + /** * Creates new instance of this dialog fragment */ @@ -55,34 +70,75 @@ public class AddUserIdDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { mMessenger = getArguments().getParcelable(ARG_MESSENGER); - CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity()); -// CharSequence[] array = {"change to primary user id", "revoke"}; -// -// builder.setTitle("select action!"); -// builder.setItems(array, new DialogInterface.OnClickListener() { -// -// @Override -// public void onClick(DialogInterface dialog, int which) { -// switch (which) { -// case 0: -// sendMessageToHandler(MESSAGE_CHANGE_PRIMARY_USER_ID, null); -// break; -// case 1: -// sendMessageToHandler(MESSAGE_REVOKE, null); -// break; -// default: -// break; -// } -// } -// }); -// builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() { -// @Override -// public void onClick(DialogInterface dialog, int id) { -// dismiss(); -// } -// }); - - return builder.show(); + CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + View view = inflater.inflate(R.layout.add_user_id_dialog, null); + alert.setView(view); + alert.setTitle("Add Identity"); + + mName = (EditText) view.findViewById(R.id.name); + mAddress = (EditText) view.findViewById(R.id.address); + mComment = (EditText) view.findViewById(R.id.comment); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int id) { + done(); + } + }); + + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + + + return alert.show(); + } + + @Override + public void onActivityCreated(Bundle arg0) { + super.onActivityCreated(arg0); + // Show soft keyboard automatically + mName.requestFocus(); + getDialog().getWindow().setSoftInputMode( + WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + mComment.setOnEditorActionListener(this); + } + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (EditorInfo.IME_ACTION_DONE == actionId) { + done(); + return true; + } + return false; + } + + private void done() { + String name = mName.getText().toString(); + String email = mAddress.getText().toString(); + String comment = mComment.getText().toString(); + + String userId = null; + if (!TextUtils.isEmpty(name)) { + userId = name; + if (!TextUtils.isEmpty(comment)) { + userId += " (" + comment + ")"; + } + if (!TextUtils.isEmpty(email)) { + userId += " <" + email + ">"; + } + } + Bundle data = new Bundle(); + data.putString(MESSAGE_DATA_USER_ID, userId); + sendMessageToHandler(MESSAGE_OKAY, data); + + this.dismiss(); } /** @@ -105,4 +161,5 @@ public class AddUserIdDialogFragment extends DialogFragment { Log.w(Constants.TAG, "Messenger is null!", e); } } + } diff --git a/OpenKeychain/src/main/res/layout/add_user_id_dialog.xml b/OpenKeychain/src/main/res/layout/add_user_id_dialog.xml new file mode 100644 index 000000000..502ca1c70 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/add_user_id_dialog.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/edit_key_fragment.xml b/OpenKeychain/src/main/res/layout/edit_key_fragment.xml index f652269e5..7f94cb3cd 100644 --- a/OpenKeychain/src/main/res/layout/edit_key_fragment.xml +++ b/OpenKeychain/src/main/res/layout/edit_key_fragment.xml @@ -45,6 +45,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + Date: Wed, 25 Jun 2014 00:37:01 +0200 Subject: Move sks-keyservers.net CA into assets folder --- .../src/main/assets/sks-keyservers.netCA.cer | 32 +++++++++++++++ .../org/sufficientlysecure/keychain/Constants.java | 35 ---------------- .../keychain/KeychainApplication.java | 3 ++ .../keychain/helper/TlsHelper.java | 46 ++++++++++++++++++++++ .../keychain/keyimport/HkpKeyserver.java | 10 ++--- 5 files changed, 85 insertions(+), 41 deletions(-) create mode 100644 OpenKeychain/src/main/assets/sks-keyservers.netCA.cer (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/assets/sks-keyservers.netCA.cer b/OpenKeychain/src/main/assets/sks-keyservers.netCA.cer new file mode 100644 index 000000000..24a2ad2e8 --- /dev/null +++ b/OpenKeychain/src/main/assets/sks-keyservers.netCA.cer @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFizCCA3OgAwIBAgIJAK9zyLTPn4CPMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNV +BAYTAk5PMQ0wCwYDVQQIDARPc2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5u +ZXQgQ0ExHjAcBgNVBAMMFXNrcy1rZXlzZXJ2ZXJzLm5ldCBDQTAeFw0xMjEwMDkw +MDMzMzdaFw0yMjEwMDcwMDMzMzdaMFwxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARP +c2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5uZXQgQ0ExHjAcBgNVBAMMFXNr +cy1rZXlzZXJ2ZXJzLm5ldCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBANdsWy4PXWNUCkS3L//nrd0GqN3dVwoBGZ6w94Tw2jPDPifegwxQozFXkG6I +6A4TK1CJLXPvfz0UP0aBYyPmTNadDinaB9T4jIwd4rnxl+59GiEmqkN3IfPsv5Jj +MkKUmJnvOT0DEVlEaO1UZIwx5WpfprB3mR81/qm4XkAgmYrmgnLXd/pJDAMk7y1F +45b5zWofiD5l677lplcIPRbFhpJ6kDTODXh/XEdtF71EAeaOdEGOvyGDmCO0GWqS +FDkMMPTlieLA/0rgFTcz4xwUYj/cD5e0ZBuSkYsYFAU3hd1cGfBue0cPZaQH2HYx +Qk4zXD8S3F4690fRhr+tki5gyG6JDR67aKp3BIGLqm7f45WkX1hYp+YXywmEziM4 +aSbGYhx8hoFGfq9UcfPEvp2aoc8u5sdqjDslhyUzM1v3m3ZGbhwEOnVjljY6JJLx +MxagxnZZSAY424ZZ3t71E/Mn27dm2w+xFRuoy8JEjv1d+BT3eChM5KaNwrj0IO/y +u8kFIgWYA1vZ/15qMT+tyJTfyrNVV/7Df7TNeWyNqjJ5rBmt0M6NpHG7CrUSkBy9 +p8JhimgjP5r0FlEkgg+lyD+V79H98gQfVgP3pbJICz0SpBQf2F/2tyS4rLm+49rP +fcOajiXEuyhpcmzgusAj/1FjrtlynH1r9mnNaX4e+rLWzvU5AgMBAAGjUDBOMB0G +A1UdDgQWBBTkwyoJFGfYTVISTpM8E+igjdq28zAfBgNVHSMEGDAWgBTkwyoJFGfY +TVISTpM8E+igjdq28zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQAR +OXnYwu3g1ZjHyley3fZI5aLPsaE17cOImVTehC8DcIphm2HOMR/hYTTL+V0G4P+u +gH+6xeRLKSHMHZTtSBIa6GDL03434y9CBuwGvAFCMU2GV8w92/Z7apkAhdLToZA/ +X/iWP2jeaVJhxgEcH8uPrnSlqoPBcKC9PrgUzQYfSZJkLmB+3jEa3HKruy1abJP5 +gAdQvwvcPpvYRnIzUc9fZODsVmlHVFBCl2dlu/iHh2h4GmL4Da2rRkUMlbVTdioB +UYIvMycdOkpH5wJftzw7cpjsudGas0PARDXCFfGyKhwBRFY7Xp7lbjtU5Rz0Gc04 +lPrhDf0pFE98Aw4jJRpFeWMjpXUEaG1cq7D641RpgcMfPFvOHY47rvDTS7XJOaUT +BwRjmDt896s6vMDcaG/uXJbQjuzmmx3W2Idyh3s5SI0GTHb0IwMKYb4eBUIpQOnB +cE77VnCYqKvN1NVYAqhWjXbY7XasZvszCRcOG+W3FqNaHOK/n/0ueb0uijdLan+U +f4p1bjbAox8eAOQS/8a3bzkJzdyBNUKGx1BIK2IBL9bn/HravSDOiNRSnZ/R3l9G +ZauX0tu7IIDlRCILXSyeazu0aj/vdT3YFQXPcvt5Fkf5wiNTo53f72/jYEJd6qph +WrpoKqrwGwTpRUCMhYIUt65hsTxCiJJ5nKe39h46sg== +-----END CERTIFICATE----- diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 1ddb3d632..e1bf1afa4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -49,41 +49,6 @@ public final class Constants { public static final String CUSTOM_CONTACT_DATA_MIME_TYPE = "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.key"; - // TODO: Resource/Asset? - public static final String SKS_KEYSERVERS_NET_CA = - "-----BEGIN CERTIFICATE-----\n" + - "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\n" + - "-----END CERTIFICATE-----"; - public static boolean KITKAT = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; public static final class Path { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index 9d355564f..dfd39b345 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -27,6 +27,7 @@ import android.os.Environment; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.helper.TlsHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PRNGFixes; @@ -84,6 +85,8 @@ public class KeychainApplication extends Application { // Update keyserver list as needed Preferences.getPreferences(this).updateKeyServers(); + + TlsHelper.addStaticCA("pool.sks-keyservers.net", getAssets(), "sks-keyservers.netCA.cer"); } public static void setupAccountAsNeeded(Context context) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java index 96df7cf2f..4b09af04d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/TlsHelper.java @@ -17,25 +17,71 @@ package org.sufficientlysecure.keychain.helper; +import android.content.res.AssetManager; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.util.Log; + import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URL; +import java.net.URLConnection; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.*; +import java.util.HashMap; +import java.util.Map; public class TlsHelper { + public static class TlsHelperException extends Exception { public TlsHelperException(Exception e) { super(e); } } + private static Map sStaticCA = new HashMap(); + + public static void addStaticCA(String domain, byte[] certificate) { + sStaticCA.put(domain, certificate); + } + + public static void addStaticCA(String domain, AssetManager assetManager, String name) { + try { + InputStream is = assetManager.open(name); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int reads = is.read(); + + while(reads != -1){ + baos.write(reads); + reads = is.read(); + } + + is.close(); + + addStaticCA(domain, baos.toByteArray()); + } catch (IOException e) { + Log.w(Constants.TAG, e); + } + } + + public static URLConnection openConnection(URL url) throws IOException, TlsHelperException { + if (url.getProtocol().equals("https")) { + for (String domain : sStaticCA.keySet()) { + if (url.getHost().endsWith(domain)) { + return openCAConnection(sStaticCA.get(domain), url); + } + } + } + return url.openConnection(); + } + /** * Opens a Connection that will only accept certificates signed with a specific CA and skips common name check. * This is required for some distributed Keyserver networks like sks-keyservers.net diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index b048a2cea..44679ba18 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -188,12 +188,10 @@ public class HkpKeyserver extends Keyserver { private HttpURLConnection openConnection(URL url) throws IOException { HttpURLConnection conn = null; - if (mHost.endsWith("pool.sks-keyservers.net") && mSecure) { - try { - conn = TlsHelper.openCAConnection(Constants.SKS_KEYSERVERS_NET_CA.getBytes(), url); - } catch (TlsHelper.TlsHelperException e) { - Log.w(Constants.TAG, e); - } + try { + conn = (HttpURLConnection) TlsHelper.openConnection(url); + } catch (TlsHelper.TlsHelperException e) { + Log.w(Constants.TAG, e); } if (conn == null) { conn = (HttpURLConnection) url.openConnection(); -- cgit v1.2.3 From 607af7bcca09df0e41ffb3b79d6bddc48f07e492 Mon Sep 17 00:00:00 2001 From: Daniel Albert Date: Wed, 25 Jun 2014 19:20:17 +0200 Subject: Temporary fix for #648 --- OpenKeychain/src/main/res/raw/help_faq.html | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/res/raw/help_faq.html b/OpenKeychain/src/main/res/raw/help_faq.html index e6757d0da..6f8763f36 100644 --- a/OpenKeychain/src/main/res/raw/help_faq.html +++ b/OpenKeychain/src/main/res/raw/help_faq.html @@ -12,5 +12,13 @@ And don't add newlines before or after p tags because of transifex -->

A wrong primary user id is shown when searching on a Keyserver

Unfortunately, this is a bug in the SKS Keyserver software. Its machine-readable output returns the user ids in an arbitrary order. Read the related bug report for more information.

+

How do I activate OpenKeychain in K9-Mail?

+

To use OpenKeychain with K9-Mail, you want to follow these steps:

+
    +
  1. Open K9-Mail and long-tap on the account you want to use OpenKeychain with.
  2. +
  3. Select "Account settings" and scroll to the very bottom and click "Cryptography".
  4. +
  5. Click on "OpenPGP Provider" and select OpenKeychain from the list.
  6. +
+

Thats it.

-- cgit v1.2.3 From 1b90b46b00802c07f68843897fb9e7b5afa29460 Mon Sep 17 00:00:00 2001 From: Daniel Albert Date: Thu, 26 Jun 2014 21:33:42 +0200 Subject: Swapped out FontawesomeText with normal ImageView --- OpenKeychain/src/main/res/layout/drawer_list_item.xml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/res/layout/drawer_list_item.xml b/OpenKeychain/src/main/res/layout/drawer_list_item.xml index 72f4fec50..158e72c01 100644 --- a/OpenKeychain/src/main/res/layout/drawer_list_item.xml +++ b/OpenKeychain/src/main/res/layout/drawer_list_item.xml @@ -3,17 +3,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + android:layout_centerVertical="true" /> + android:layout_alignParentTop="true" /> -- cgit v1.2.3 From 567e5cc6a52277dce4f3e1214ff3b247ca26f68f Mon Sep 17 00:00:00 2001 From: Daniel Albert Date: Fri, 27 Jun 2014 21:03:19 +0200 Subject: Added unlock icon, fixed drawer items, switched to icons from resource in drawer --- .../keychain/ui/DrawerActivity.java | 26 ++++++++++++--------- .../res/drawable-hdpi/ic_action_not_secure.png | Bin 0 -> 373 bytes .../res/drawable-mdpi/ic_action_not_secure.png | Bin 0 -> 321 bytes .../res/drawable-xhdpi/ic_action_not_secure.png | Bin 0 -> 483 bytes .../res/drawable-xxhdpi/ic_action_not_secure.png | Bin 0 -> 619 bytes .../src/main/res/layout/drawer_list_item.xml | 8 ++++--- 6 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_action_not_secure.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_action_not_secure.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_action_not_secure.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_not_secure.png (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java index 9a5050eba..586442bb0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java @@ -37,8 +37,7 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; - -import com.beardedhen.androidbootstrap.FontAwesomeText; +import android.widget.ImageView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -79,10 +78,10 @@ public class DrawerActivity extends ActionBarActivity { } NavItem mItemIconTexts[] = new NavItem[]{ - new NavItem("fa-user", getString(R.string.nav_keys)), - new NavItem("fa-lock", getString(R.string.nav_encrypt)), - new NavItem("fa-unlock", getString(R.string.nav_decrypt)), - new NavItem("fa-android", getString(R.string.nav_apps))}; + new NavItem(R.drawable.ic_action_person, getString(R.string.nav_keys)), + new NavItem(R.drawable.ic_action_secure, getString(R.string.nav_encrypt)), + new NavItem(R.drawable.ic_action_not_secure, getString(R.string.nav_decrypt)), + new NavItem(R.drawable.ic_action_view_as_list, getString(R.string.nav_apps))}; mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.drawer_list_item, mItemIconTexts)); @@ -239,10 +238,15 @@ public class DrawerActivity extends ActionBarActivity { } private class NavItem { - public String icon; + public int icon; // res-id public String title; - public NavItem(String icon, String title) { + /** + * NavItem constructor + * @param icon The icons resource-id + * @param title The title of the menu entry + */ + public NavItem(int icon, String title) { super(); this.icon = icon; this.title = title; @@ -271,7 +275,7 @@ public class DrawerActivity extends ActionBarActivity { row = inflater.inflate(mLayoutResourceId, parent, false); holder = new NavItemHolder(); - holder.mImg = (FontAwesomeText) row.findViewById(R.id.drawer_item_icon); + holder.mImg = (ImageView) row.findViewById(R.id.drawer_item_icon); holder.mTxtTitle = (TextView) row.findViewById(R.id.drawer_item_text); row.setTag(holder); @@ -281,7 +285,7 @@ public class DrawerActivity extends ActionBarActivity { NavItem item = mData[position]; holder.mTxtTitle.setText(item.title); - holder.mImg.setIcon(item.icon); + holder.mImg.setImageResource(item.icon); return row; } @@ -289,7 +293,7 @@ public class DrawerActivity extends ActionBarActivity { } static class NavItemHolder { - FontAwesomeText mImg; + ImageView mImg; TextView mTxtTitle; } diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_not_secure.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_not_secure.png new file mode 100644 index 000000000..5ee148080 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_not_secure.png differ diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_not_secure.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_not_secure.png new file mode 100644 index 000000000..dd5289ee4 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_not_secure.png differ diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_not_secure.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_not_secure.png new file mode 100644 index 000000000..312a230e7 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xhdpi/ic_action_not_secure.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_not_secure.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_not_secure.png new file mode 100644 index 000000000..4aa9dc85c Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_not_secure.png differ diff --git a/OpenKeychain/src/main/res/layout/drawer_list_item.xml b/OpenKeychain/src/main/res/layout/drawer_list_item.xml index 158e72c01..4719483da 100644 --- a/OpenKeychain/src/main/res/layout/drawer_list_item.xml +++ b/OpenKeychain/src/main/res/layout/drawer_list_item.xml @@ -4,9 +4,10 @@ android:layout_height="wrap_content"> + android:layout_alignParentTop="true" + android:layout_toRightOf="@id/drawer_item_icon"/> -- cgit v1.2.3 From 9fe07478e7fe683223310d017f162f5bcb467d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 27 Jun 2014 21:40:18 +0200 Subject: Start work on a first-time wizard --- OpenKeychain/src/main/AndroidManifest.xml | 5 + .../keychain/ui/KeyListActivity.java | 8 +- .../keychain/ui/WizardActivity.java | 395 +++++++++++++++++++++ .../src/main/res/layout/wizard_activity.xml | 98 +++++ .../main/res/layout/wizard_create_key_fragment.xml | 41 +++ .../main/res/layout/wizard_generic_fragment.xml | 15 + .../src/main/res/layout/wizard_start_fragment.xml | 63 ++++ OpenKeychain/src/main/res/values/strings.xml | 1 + 8 files changed, 622 insertions(+), 4 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/WizardActivity.java create mode 100644 OpenKeychain/src/main/res/layout/wizard_activity.xml create mode 100644 OpenKeychain/src/main/res/layout/wizard_create_key_fragment.xml create mode 100644 OpenKeychain/src/main/res/layout/wizard_generic_fragment.xml create mode 100644 OpenKeychain/src/main/res/layout/wizard_start_fragment.xml (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index c6e528f4d..d5f031ecc 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -79,6 +79,11 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.ActionBarActivity; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Patterns; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.RadioGroup; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ContactHelper; + +import java.util.regex.Matcher; + + +public class WizardActivity extends ActionBarActivity { + + private State mCurrentState; + + // values for mCurrentScreen + private enum State { + START, CREATE_KEY, NFC, FINISH + } + + Button mBackButton; + Button mNextButton; + StartFragment mStartFragment; + CreateKeyFragment mCreateKeyFragment; + GenericFragment mNFCFragment; + GenericFragment mFinishFragment; + + LinearLayout mProgressLayout; + View mProgressLine; + ProgressBar mProgressBar; + ImageView mProgressImage; + TextView mProgressText; + + /** + * Checks if text of given EditText is not empty. If it is empty an error is + * set and the EditText gets the focus. + * + * @param context + * @param editText + * @return true if EditText is not empty + */ + private static boolean isEditTextNotEmpty(Context context, EditText editText) { + boolean output = true; + if (editText.getText().toString().length() == 0) { + editText.setError("empty!"); + editText.requestFocus(); + output = false; + } else { + editText.setError(null); + } + + return output; + } + + public static class StartFragment extends Fragment { + public static StartFragment newInstance() { + StartFragment myFragment = new StartFragment(); + + Bundle args = new Bundle(); + myFragment.setArguments(args); + + return myFragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.wizard_start_fragment, + container, false); + } + } + + public static class CreateKeyFragment extends Fragment { + public static CreateKeyFragment newInstance() { + CreateKeyFragment myFragment = new CreateKeyFragment(); + + Bundle args = new Bundle(); + myFragment.setArguments(args); + + return myFragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.wizard_create_key_fragment, + container, false); + + final AutoCompleteTextView emailView = (AutoCompleteTextView) view.findViewById(R.id.email); + emailView.setThreshold(1); // Start working from first character + emailView.setAdapter( + new ArrayAdapter + (getActivity(), android.R.layout.simple_dropdown_item_1line, + ContactHelper.getMailAccounts(getActivity()) + ) + ); + emailView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } + + @Override + public void afterTextChanged(Editable editable) { + String email = editable.toString(); + if (email.length() > 0) { + Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email); + if (emailMatcher.matches()) { + emailView.setCompoundDrawablesWithIntrinsicBounds(0, 0, + R.drawable.uid_mail_ok, 0); + } else { + emailView.setCompoundDrawablesWithIntrinsicBounds(0, 0, + R.drawable.uid_mail_bad, 0); + } + } else { + // remove drawable if email is empty + emailView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); + } +// if (mEditorListener != null) { +// mEditorListener.onEdited(); +// } + } + }); + return view; + } + } + + public static class GenericFragment extends Fragment { + public static GenericFragment newInstance(String text) { + GenericFragment myFragment = new GenericFragment(); + + Bundle args = new Bundle(); + args.putString("text", text); + myFragment.setArguments(args); + + return myFragment; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.wizard_generic_fragment, + container, false); + + TextView text = (TextView) v + .findViewById(R.id.fragment_vehicle_reg_generic_text); + text.setText(getArguments().getString("text")); + + return v; + } + + } + + /** + * Loads new fragment + * + * @param fragment + */ + private void loadFragment(Fragment fragment) { + FragmentManager fragmentManager = getSupportFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager + .beginTransaction(); + fragmentTransaction.replace(R.id.wizard_container, + fragment); + fragmentTransaction.commit(); + } + + /** + * Instantiate View and initialize fragments for this Activity + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.wizard_activity); + mBackButton = (Button) findViewById(R.id.wizard_back); + mNextButton = (Button) findViewById(R.id.wizard_next); + + // progress layout + mProgressLayout = (LinearLayout) findViewById(R.id.wizard_progress); + mProgressLine = findViewById(R.id.wizard_progress_line); + mProgressBar = (ProgressBar) findViewById(R.id.wizard_progress_progressbar); + mProgressImage = (ImageView) findViewById(R.id.wizard_progress_image); + mProgressText = (TextView) findViewById(R.id.wizard_progress_text); + + mStartFragment = StartFragment.newInstance(); + loadFragment(mStartFragment); + mCurrentState = State.START; + } + + private enum ProgressState { + WORKING, ENABLED, DISABLED, ERROR + } + + private void showProgress(ProgressState state, String text) { + switch (state) { + case WORKING: + mProgressBar.setVisibility(View.VISIBLE); + mProgressImage.setVisibility(View.GONE); + break; + case ENABLED: + mProgressBar.setVisibility(View.GONE); + mProgressImage.setVisibility(View.VISIBLE); +// mProgressImage.setImageDrawable(getResources().getDrawable( +// R.drawable.status_enabled)); + break; + case DISABLED: + mProgressBar.setVisibility(View.GONE); + mProgressImage.setVisibility(View.VISIBLE); +// mProgressImage.setImageDrawable(getResources().getDrawable( +// R.drawable.status_disabled)); + break; + case ERROR: + mProgressBar.setVisibility(View.GONE); + mProgressImage.setVisibility(View.VISIBLE); +// mProgressImage.setImageDrawable(getResources().getDrawable( +// R.drawable.status_fail)); + break; + + default: + break; + } + mProgressText.setText(text); + + mProgressLine.setVisibility(View.VISIBLE); + mProgressLayout.setVisibility(View.VISIBLE); + } + + private void hideProgress() { + mProgressLine.setVisibility(View.GONE); + mProgressLayout.setVisibility(View.GONE); + } + + public void nextOnClick(View view) { + // close keyboard + if (getCurrentFocus() != null) { + InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.hideSoftInputFromWindow(getCurrentFocus() + .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + } + + switch (mCurrentState) { + + case START: { + RadioGroup radioGroup = (RadioGroup) findViewById(R.id.wizard_start_radio_group); + int selectedId = radioGroup.getCheckedRadioButtonId(); + switch (selectedId) { + case R.id.wizard_start_new_key: { + mCurrentState = State.CREATE_KEY; + mCreateKeyFragment = CreateKeyFragment.newInstance(); + loadFragment(mCreateKeyFragment); + break; + } + } + + mBackButton.setText(R.string.btn_back); + +// if (isEditTextNotEmpty(this, asd)) { +// mLicensePlate = asd.getText().toString(); +// +// showProgress(ProgressState.WORKING, +// "doing something"; +// } + break; + } + case CREATE_KEY: + + AsyncTask generateTask = new AsyncTask() { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + showProgress(ProgressState.WORKING, "generating key..."); + } + + @Override + protected Boolean doInBackground(String... params) { + return false; + } + + @Override + protected void onPostExecute(Boolean result) { + super.onPostExecute(result); + +// if (result) { +// showProgress( +// ProgressState.WORKING, +// "asd"); +// +// } else { +// showProgress( +// ProgressState.ERROR, "asd"); +// } + } + + }; + + generateTask.execute(""); + + break; + case NFC: + + mCurrentState = State.FINISH; + hideProgress(); + mFinishFragment = GenericFragment + .newInstance("asd"); + loadFragment(mFinishFragment); + mNextButton.setText("finish"); + + break; + case FINISH: + finish(); + break; + default: + break; + } + } + + public void backOnClick(View view) { + switch (mCurrentState) { + case START: + finish(); + break; + + case CREATE_KEY: + loadFragment(mStartFragment); + mCurrentState = State.START; + mBackButton.setText(android.R.string.cancel); + mNextButton.setText(R.string.btn_next); + break; + case NFC: + loadFragment(mCreateKeyFragment); + mCurrentState = State.CREATE_KEY; + mBackButton.setText(R.string.btn_back); + mNextButton.setText(R.string.btn_next); + break; + case FINISH: + loadFragment(mNFCFragment); + mCurrentState = State.NFC; + mBackButton.setText(R.string.btn_back); + mNextButton.setText(R.string.btn_next); + break; + + default: + loadFragment(mStartFragment); + mCurrentState = State.START; + mBackButton.setText(android.R.string.cancel); + mNextButton.setText(R.string.btn_next); + break; + } + } + +} diff --git a/OpenKeychain/src/main/res/layout/wizard_activity.xml b/OpenKeychain/src/main/res/layout/wizard_activity.xml new file mode 100644 index 000000000..299d07a76 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/wizard_activity.xml @@ -0,0 +1,98 @@ + + + + + +