From 19072824bada5ae2fcac6e4e991bf300f270b081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 18 May 2014 23:06:50 +0200 Subject: Rename KeyServer to Keyserver --- .../keychain/keyimport/HkpKeyServer.java | 338 --------------------- .../keychain/keyimport/HkpKeyserver.java | 338 +++++++++++++++++++++ .../keychain/keyimport/KeyServer.java | 68 ----- .../keychain/keyimport/KeybaseKeyServer.java | 178 ----------- .../keychain/keyimport/KeybaseKeyserver.java | 175 +++++++++++ .../keychain/keyimport/Keyserver.java | 68 +++++ .../keychain/pgp/PgpImportExport.java | 6 +- .../keychain/service/KeychainIntentService.java | 10 +- .../keychain/ui/ImportKeysListFragment.java | 10 +- .../keychain/ui/KeyListFragment.java | 9 +- .../ui/adapter/ImportKeysListKeybaseLoader.java | 12 +- .../ui/adapter/ImportKeysListServerLoader.java | 12 +- 12 files changed, 610 insertions(+), 614 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyServer.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeyServer.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyServer.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/Keyserver.java (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyServer.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyServer.java deleted file mode 100644 index 8d1e1f460..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyServer.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2011-2014 Thialfihar - * 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.sufficientlysecure.keychain.keyimport; - -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.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.GregorianCalendar; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -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; - - /** - * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% - *
    - *
  • %keyid% = this is either the fingerprint or the key ID of the key. - * Either the 16-digit or 8-digit key IDs are acceptable, but obviously the fingerprint is best. - *
  • - *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). - * See RFC-2440
  • - *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • - *
  • %creationdate% = creation date of the key in standard - * RFC-2440 form (i.e. number of - * seconds since 1/1/1970 UTC time)
  • - *
  • %expirationdate% = expiration date of the key in standard - * RFC-2440 form (i.e. number of - * seconds since 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any - * order. The meaning of "disabled" is implementation-specific. Note that individual flags may - * be unimplemented, so the absence of a given flag does not necessarily mean the absence of the - * detail. - *
      - *
    • r == revoked
    • - *
    • d == disabled
    • - *
    • e == expired
    • - *
    - *
  • - *
- * - * @see - * 5.2. Machine Readable Indexes - * in Internet-Draft OpenPGP HTTP Keyserver Protocol Document - */ - public static final Pattern PUB_KEY_LINE = Pattern - .compile("pub:([0-9a-fA-F]+):([0-9]+):([0-9]+):([0-9]+):([0-9]*):([rde]*)[ \n\r]*" // pub line - + "(uid:(.*):([0-9]+):([0-9]*):([rde]*))+", // one or more uid lines - Pattern.CASE_INSENSITIVE); - - /** - * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% - *
    - *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that - * isn't 7-bit safe as well as for the ":" character. Any other characters may be escaped, as - * desired.
  • - *
  • %creationdate% = creation date of the key in standard - * RFC-2440 form (i.e. number of - * seconds since 1/1/1970 UTC time)
  • - *
  • %expirationdate% = expiration date of the key in standard - * RFC-2440 form (i.e. number of - * seconds since 1/1/1970 UTC time)
  • - *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any - * order. The meaning of "disabled" is implementation-specific. Note that individual flags may - * be unimplemented, so the absence of a given flag does not necessarily mean the absence of - * the detail. - *
      - *
    • r == revoked
    • - *
    • d == disabled
    • - *
    • e == expired
    • - *
    - *
  • - *
- */ - public static final Pattern UID_LINE = Pattern - .compile("uid:(.*):([0-9]+):([0-9]*):([rde]*)", - Pattern.CASE_INSENSITIVE); - - private static final short PORT_DEFAULT = 11371; - - /** - * @param hostAndPort may be just - * "hostname" (eg. "pool.sks-keyservers.net"), then it will - * connect using {@link #PORT_DEFAULT}. However, port may be specified after colon - * ("hostname:port", eg. "p80.pool.sks-keyservers.net:80"). - */ - public HkpKeyServer(String hostAndPort) { - String host = hostAndPort; - short port = PORT_DEFAULT; - final int colonPosition = hostAndPort.lastIndexOf(':'); - if (colonPosition > 0) { - host = hostAndPort.substring(0, colonPosition); - final String portStr = hostAndPort.substring(colonPosition + 1); - port = Short.decode(portStr); - } - mHost = host; - mPort = port; - } - - public HkpKeyServer(String host, short port) { - mHost = host; - mPort = port; - } - - 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; - 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 - } - } - - throw new QueryException("querying server(s) for '" + mHost + "' failed"); - } - - @Override - public ArrayList search(String query) throws QueryException, TooManyResponses, - InsufficientQuery { - ArrayList results = new ArrayList(); - - 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&options=mr&search=" + encodedQuery; - - String data; - try { - data = query(request); - } catch (HttpError e) { - if (e.getCode() == 404) { - return results; - } else { - if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { - return results; - } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { - throw new TooManyResponses(); - } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { - throw new InsufficientQuery(); - } - } - throw new QueryException("querying server(s) for '" + mHost + "' failed"); - } - - final Matcher matcher = PUB_KEY_LINE.matcher(data); - while (matcher.find()) { - final ImportKeysListEntry entry = new ImportKeysListEntry(); - - entry.setBitStrength(Integer.parseInt(matcher.group(3))); - - final int algorithmId = Integer.decode(matcher.group(2)); - entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId)); - - // group 1 contains the full fingerprint (v4) or the long key id if available - // see http://bit.ly/1d4bxbk and http://bit.ly/1gD1wwr - String fingerprintOrKeyId = matcher.group(1); - if (fingerprintOrKeyId.length() > 16) { - entry.setFingerprintHex(fingerprintOrKeyId.toLowerCase(Locale.US)); - entry.setKeyIdHex("0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() - - 16, fingerprintOrKeyId.length())); - } else { - // set key id only - entry.setKeyIdHex("0x" + fingerprintOrKeyId); - } - - final long creationDate = Long.parseLong(matcher.group(4)); - final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - tmpGreg.setTimeInMillis(creationDate * 1000); - entry.setDate(tmpGreg.getTime()); - - entry.setRevoked(matcher.group(6).contains("r")); - - ArrayList userIds = new ArrayList(); - final String uidLines = matcher.group(7); - final Matcher uidMatcher = UID_LINE.matcher(uidLines); - while (uidMatcher.find()) { - String tmp = uidMatcher.group(1).trim(); - if (tmp.contains("%")) { - try { - // converts Strings like "Universit%C3%A4t" to a proper encoding form "Universität". - tmp = (URLDecoder.decode(tmp, "UTF8")); - } catch (UnsupportedEncodingException ignored) { - // will never happen, because "UTF8" is supported - } - } - userIds.add(tmp); - } - entry.setUserIds(userIds); - entry.setPrimaryUserId(userIds.get(0)); - - results.add(entry); - } - return results; - } - - @Override - public String get(String keyIdHex) throws QueryException { - HttpClient client = new DefaultHttpClient(); - try { - String query = "http://" + 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 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 armoredKey) throws AddKeyException { - HttpClient client = new DefaultHttpClient(); - try { - String query = "http://" + mHost + ":" + mPort + "/pks/add"; - HttpPost post = new HttpPost(query); - 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(); - } - } catch (IOException e) { - // nothing to do, better luck on the next keyserver - } finally { - client.getConnectionManager().shutdown(); - } - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java new file mode 100644 index 000000000..1f101f6ef --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2011-2014 Thialfihar + * 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.sufficientlysecure.keychain.keyimport; + +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.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.GregorianCalendar; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +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; + + /** + * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags% + *
    + *
  • %keyid% = this is either the fingerprint or the key ID of the key. + * Either the 16-digit or 8-digit key IDs are acceptable, but obviously the fingerprint is best. + *
  • + *
  • %algo% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc). + * See RFC-2440
  • + *
  • %keylen% = the key length (i.e. 1024, 2048, 4096, etc.)
  • + *
  • %creationdate% = creation date of the key in standard + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any + * order. The meaning of "disabled" is implementation-specific. Note that individual flags may + * be unimplemented, so the absence of a given flag does not necessarily mean the absence of the + * detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • + *
+ * + * @see + * 5.2. Machine Readable Indexes + * in Internet-Draft OpenPGP HTTP Keyserver Protocol Document + */ + public static final Pattern PUB_KEY_LINE = Pattern + .compile("pub:([0-9a-fA-F]+):([0-9]+):([0-9]+):([0-9]+):([0-9]*):([rde]*)[ \n\r]*" // pub line + + "(uid:(.*):([0-9]+):([0-9]*):([rde]*))+", // one or more uid lines + Pattern.CASE_INSENSITIVE); + + /** + * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags% + *
    + *
  • %escaped uid string% = the user ID string, with HTTP %-escaping for anything that + * isn't 7-bit safe as well as for the ":" character. Any other characters may be escaped, as + * desired.
  • + *
  • %creationdate% = creation date of the key in standard + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time)
  • + *
  • %expirationdate% = expiration date of the key in standard + * RFC-2440 form (i.e. number of + * seconds since 1/1/1970 UTC time)
  • + *
  • %flags% = letter codes to indicate details of the key, if any. Flags may be in any + * order. The meaning of "disabled" is implementation-specific. Note that individual flags may + * be unimplemented, so the absence of a given flag does not necessarily mean the absence of + * the detail. + *
      + *
    • r == revoked
    • + *
    • d == disabled
    • + *
    • e == expired
    • + *
    + *
  • + *
+ */ + public static final Pattern UID_LINE = Pattern + .compile("uid:(.*):([0-9]+):([0-9]*):([rde]*)", + Pattern.CASE_INSENSITIVE); + + private static final short PORT_DEFAULT = 11371; + + /** + * @param hostAndPort may be just + * "hostname" (eg. "pool.sks-keyservers.net"), then it will + * connect using {@link #PORT_DEFAULT}. However, port may be specified after colon + * ("hostname:port", eg. "p80.pool.sks-keyservers.net:80"). + */ + public HkpKeyserver(String hostAndPort) { + String host = hostAndPort; + short port = PORT_DEFAULT; + final int colonPosition = hostAndPort.lastIndexOf(':'); + if (colonPosition > 0) { + host = hostAndPort.substring(0, colonPosition); + final String portStr = hostAndPort.substring(colonPosition + 1); + port = Short.decode(portStr); + } + mHost = host; + mPort = port; + } + + public HkpKeyserver(String host, short port) { + mHost = host; + mPort = port; + } + + 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; + 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 + } + } + + throw new QueryException("querying server(s) for '" + mHost + "' failed"); + } + + @Override + public ArrayList search(String query) throws QueryException, TooManyResponses, + InsufficientQuery { + ArrayList results = new ArrayList(); + + 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&options=mr&search=" + encodedQuery; + + String data; + try { + data = query(request); + } catch (HttpError e) { + if (e.getCode() == 404) { + return results; + } else { + if (e.getData().toLowerCase(Locale.US).contains("no keys found")) { + return results; + } else if (e.getData().toLowerCase(Locale.US).contains("too many")) { + throw new TooManyResponses(); + } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) { + throw new InsufficientQuery(); + } + } + throw new QueryException("querying server(s) for '" + mHost + "' failed"); + } + + final Matcher matcher = PUB_KEY_LINE.matcher(data); + while (matcher.find()) { + final ImportKeysListEntry entry = new ImportKeysListEntry(); + + entry.setBitStrength(Integer.parseInt(matcher.group(3))); + + final int algorithmId = Integer.decode(matcher.group(2)); + entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId)); + + // group 1 contains the full fingerprint (v4) or the long key id if available + // see http://bit.ly/1d4bxbk and http://bit.ly/1gD1wwr + String fingerprintOrKeyId = matcher.group(1); + if (fingerprintOrKeyId.length() > 16) { + entry.setFingerprintHex(fingerprintOrKeyId.toLowerCase(Locale.US)); + entry.setKeyIdHex("0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length() + - 16, fingerprintOrKeyId.length())); + } else { + // set key id only + entry.setKeyIdHex("0x" + fingerprintOrKeyId); + } + + final long creationDate = Long.parseLong(matcher.group(4)); + final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + tmpGreg.setTimeInMillis(creationDate * 1000); + entry.setDate(tmpGreg.getTime()); + + entry.setRevoked(matcher.group(6).contains("r")); + + ArrayList userIds = new ArrayList(); + final String uidLines = matcher.group(7); + final Matcher uidMatcher = UID_LINE.matcher(uidLines); + while (uidMatcher.find()) { + String tmp = uidMatcher.group(1).trim(); + if (tmp.contains("%")) { + try { + // converts Strings like "Universit%C3%A4t" to a proper encoding form "Universität". + tmp = (URLDecoder.decode(tmp, "UTF8")); + } catch (UnsupportedEncodingException ignored) { + // will never happen, because "UTF8" is supported + } + } + userIds.add(tmp); + } + entry.setUserIds(userIds); + entry.setPrimaryUserId(userIds.get(0)); + + results.add(entry); + } + return results; + } + + @Override + public String get(String keyIdHex) throws QueryException { + HttpClient client = new DefaultHttpClient(); + try { + String query = "http://" + 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 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 armoredKey) throws AddKeyException { + HttpClient client = new DefaultHttpClient(); + try { + String query = "http://" + mHost + ":" + mPort + "/pks/add"; + HttpPost post = new HttpPost(query); + 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(); + } + } catch (IOException e) { + // nothing to do, better luck on the next keyserver + } finally { + client.getConnectionManager().shutdown(); + } + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeyServer.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeyServer.java deleted file mode 100644 index d6ebca5a6..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeyServer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2011-2014 Thialfihar - * 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.sufficientlysecure.keychain.keyimport; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -public abstract class KeyServer { - public static class QueryException extends Exception { - private static final long serialVersionUID = 2703768928624654512L; - - public QueryException(String message) { - super(message); - } - } - - public static class TooManyResponses extends Exception { - private static final long serialVersionUID = 2703768928624654513L; - } - - public static class InsufficientQuery extends Exception { - private static final long serialVersionUID = 2703768928624654514L; - } - - public static class AddKeyException extends Exception { - private static final long serialVersionUID = -507574859137295530L; - } - - abstract List search(String query) throws QueryException, TooManyResponses, - InsufficientQuery; - - abstract String get(String keyIdHex) throws QueryException; - - abstract void add(String armoredKey) throws AddKeyException; - - public static 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); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyServer.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyServer.java deleted file mode 100644 index 5f729a05c..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyServer.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2014 Tim Bray - * - * 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.keyimport; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.util.JWalk; -import org.sufficientlysecure.keychain.util.Log; - -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.TimeZone; -import java.util.WeakHashMap; - -public class KeybaseKeyServer extends KeyServer { - - @Override - public ArrayList search(String query) throws QueryException, TooManyResponses, - InsufficientQuery { - ArrayList results = new ArrayList(); - - if (query.startsWith("0x")) { - // cut off "0x" if a user is searching for a key id - query = query.substring(2); - } - - JSONObject fromQuery = getFromKeybase("_/api/1.0/user/autocomplete.json?q=", query); - try { - - JSONArray matches = JWalk.getArray(fromQuery, "completions"); - for (int i = 0; i < matches.length(); i++) { - JSONObject match = matches.getJSONObject(i); - - // only list them if they have a key - if (JWalk.optObject(match, "components", "key_fingerprint") != null) { - String keybaseId = JWalk.getString(match, "components", "username", "val"); - String fingerprint = JWalk.getString(match, "components", "key_fingerprint", "val"); - fingerprint = fingerprint.replace(" ", "").toUpperCase(); - - if (keybaseId.equals(query) || fingerprint.startsWith(query.toUpperCase())) { - results.add(makeEntry(match)); - } else { - results.add(makeEntry(match)); - } - } - } - } catch (Exception e) { - Log.e(Constants.TAG, "keybase result parsing error", e); - throw new QueryException("Unexpected structure in keybase search result: " + e.getMessage()); - } - - return results; - } - - private JSONObject getUser(String keybaseId) throws QueryException { - try { - return getFromKeybase("_/api/1.0/user/lookup.json?username=", keybaseId); - } catch (Exception e) { - String detail = ""; - if (keybaseId != null) { - detail = ". Query was for user '" + keybaseId + "'"; - } - throw new QueryException(e.getMessage() + detail); - } - } - - private ImportKeysListEntry makeEntry(JSONObject match) throws QueryException, JSONException { - - final ImportKeysListEntry entry = new ImportKeysListEntry(); - String keybaseId = JWalk.getString(match, "components", "username", "val"); - String fullName = JWalk.getString(match, "components", "full_name", "val"); - String fingerprint = JWalk.getString(match, "components", "key_fingerprint", "val"); - fingerprint = fingerprint.replace(" ", "").toUpperCase(); // not strictly necessary but doesn't hurt - entry.setFingerprintHex(fingerprint); - - // in anticipation of a full fingerprint, only use the last 16 chars as 64-bit key id - entry.setKeyIdHex("0x" + fingerprint.substring(Math.max(0, fingerprint.length() - 16))); - // store extra info, so we can query for the keybase id directly - entry.setExtraData(keybaseId); - - final int algorithmId = JWalk.getInt(match, "components", "key_fingerprint", "algo"); - entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId)); - final int bitStrength = JWalk.getInt(match, "components", "key_fingerprint", "nbits"); - entry.setBitStrength(bitStrength); - - ArrayList userIds = new ArrayList(); - String name = fullName + " "; - userIds.add(name); - try { - userIds.add("github.com/" + JWalk.getString(match, "components", "github", "val")); - } catch (JSONException e) { - // ignore - } - try { - userIds.add("twitter.com/" + JWalk.getString(match, "components", "twitter", "val")); - } catch (JSONException e) { - // ignore - } - try { - JSONArray array = JWalk.getArray(match, "components", "websites"); - JSONObject website = array.getJSONObject(0); - userIds.add(JWalk.getString(website, "val")); - } catch (JSONException e) { - // ignore - } - entry.setUserIds(userIds); - entry.setPrimaryUserId(name); - return entry; - } - - private JSONObject getFromKeybase(String path, String query) throws QueryException { - try { - String url = "https://keybase.io/" + path + URLEncoder.encode(query, "utf8"); - Log.d(Constants.TAG, "keybase query: " + url); - - URL realUrl = new URL(url); - HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); - conn.setConnectTimeout(5000); // TODO: Reasonable values for keybase - conn.setReadTimeout(25000); - conn.connect(); - int response = conn.getResponseCode(); - if (response >= 200 && response < 300) { - String text = readAll(conn.getInputStream(), conn.getContentEncoding()); - try { - JSONObject json = new JSONObject(text); - if (JWalk.getInt(json, "status", "code") != 0) { - throw new QueryException("Keybase autocomplete search failed"); - } - return json; - } catch (JSONException e) { - throw new QueryException("Keybase.io query returned broken JSON"); - } - } else { - String message = readAll(conn.getErrorStream(), conn.getContentEncoding()); - throw new QueryException("Keybase.io query error (status=" + response + - "): " + message); - } - } catch (Exception e) { - throw new QueryException("Keybase.io query error"); - } - } - - @Override - public String get(String id) throws QueryException { - try { - JSONObject user = getUser(id); - return JWalk.getString(user, "them", "public_keys", "primary", "bundle"); - } catch (Exception e) { - throw new QueryException(e.getMessage()); - } - } - - @Override - public void add(String armoredKey) throws AddKeyException { - throw new AddKeyException(); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java new file mode 100644 index 000000000..3094b065e --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2014 Tim Bray + * + * 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.keyimport; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.util.JWalk; +import org.sufficientlysecure.keychain.util.Log; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; + +public class KeybaseKeyserver extends Keyserver { + + @Override + public ArrayList search(String query) throws QueryException, TooManyResponses, + InsufficientQuery { + ArrayList results = new ArrayList(); + + if (query.startsWith("0x")) { + // cut off "0x" if a user is searching for a key id + query = query.substring(2); + } + + JSONObject fromQuery = getFromKeybase("_/api/1.0/user/autocomplete.json?q=", query); + try { + + JSONArray matches = JWalk.getArray(fromQuery, "completions"); + for (int i = 0; i < matches.length(); i++) { + JSONObject match = matches.getJSONObject(i); + + // only list them if they have a key + if (JWalk.optObject(match, "components", "key_fingerprint") != null) { + String keybaseId = JWalk.getString(match, "components", "username", "val"); + String fingerprint = JWalk.getString(match, "components", "key_fingerprint", "val"); + fingerprint = fingerprint.replace(" ", "").toUpperCase(); + + if (keybaseId.equals(query) || fingerprint.startsWith(query.toUpperCase())) { + results.add(makeEntry(match)); + } else { + results.add(makeEntry(match)); + } + } + } + } catch (Exception e) { + Log.e(Constants.TAG, "keybase result parsing error", e); + throw new QueryException("Unexpected structure in keybase search result: " + e.getMessage()); + } + + return results; + } + + private JSONObject getUser(String keybaseId) throws QueryException { + try { + return getFromKeybase("_/api/1.0/user/lookup.json?username=", keybaseId); + } catch (Exception e) { + String detail = ""; + if (keybaseId != null) { + detail = ". Query was for user '" + keybaseId + "'"; + } + throw new QueryException(e.getMessage() + detail); + } + } + + private ImportKeysListEntry makeEntry(JSONObject match) throws QueryException, JSONException { + + final ImportKeysListEntry entry = new ImportKeysListEntry(); + String keybaseId = JWalk.getString(match, "components", "username", "val"); + String fullName = JWalk.getString(match, "components", "full_name", "val"); + String fingerprint = JWalk.getString(match, "components", "key_fingerprint", "val"); + fingerprint = fingerprint.replace(" ", "").toUpperCase(); // not strictly necessary but doesn't hurt + entry.setFingerprintHex(fingerprint); + + // in anticipation of a full fingerprint, only use the last 16 chars as 64-bit key id + entry.setKeyIdHex("0x" + fingerprint.substring(Math.max(0, fingerprint.length() - 16))); + // store extra info, so we can query for the keybase id directly + entry.setExtraData(keybaseId); + + final int algorithmId = JWalk.getInt(match, "components", "key_fingerprint", "algo"); + entry.setAlgorithm(PgpKeyHelper.getAlgorithmInfo(algorithmId)); + final int bitStrength = JWalk.getInt(match, "components", "key_fingerprint", "nbits"); + entry.setBitStrength(bitStrength); + + ArrayList userIds = new ArrayList(); + String name = fullName + " "; + userIds.add(name); + try { + userIds.add("github.com/" + JWalk.getString(match, "components", "github", "val")); + } catch (JSONException e) { + // ignore + } + try { + userIds.add("twitter.com/" + JWalk.getString(match, "components", "twitter", "val")); + } catch (JSONException e) { + // ignore + } + try { + JSONArray array = JWalk.getArray(match, "components", "websites"); + JSONObject website = array.getJSONObject(0); + userIds.add(JWalk.getString(website, "val")); + } catch (JSONException e) { + // ignore + } + entry.setUserIds(userIds); + entry.setPrimaryUserId(name); + return entry; + } + + private JSONObject getFromKeybase(String path, String query) throws QueryException { + try { + String url = "https://keybase.io/" + path + URLEncoder.encode(query, "utf8"); + Log.d(Constants.TAG, "keybase query: " + url); + + URL realUrl = new URL(url); + HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); + conn.setConnectTimeout(5000); // TODO: Reasonable values for keybase + conn.setReadTimeout(25000); + conn.connect(); + int response = conn.getResponseCode(); + if (response >= 200 && response < 300) { + String text = readAll(conn.getInputStream(), conn.getContentEncoding()); + try { + JSONObject json = new JSONObject(text); + if (JWalk.getInt(json, "status", "code") != 0) { + throw new QueryException("Keybase autocomplete search failed"); + } + return json; + } catch (JSONException e) { + throw new QueryException("Keybase.io query returned broken JSON"); + } + } else { + String message = readAll(conn.getErrorStream(), conn.getContentEncoding()); + throw new QueryException("Keybase.io query error (status=" + response + + "): " + message); + } + } catch (Exception e) { + throw new QueryException("Keybase.io query error"); + } + } + + @Override + public String get(String id) throws QueryException { + try { + JSONObject user = getUser(id); + return JWalk.getString(user, "them", "public_keys", "primary", "bundle"); + } catch (Exception e) { + throw new QueryException(e.getMessage()); + } + } + + @Override + public void add(String armoredKey) throws AddKeyException { + throw new AddKeyException(); + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/Keyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/Keyserver.java new file mode 100644 index 000000000..19591eda8 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/Keyserver.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2011-2014 Thialfihar + * 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.sufficientlysecure.keychain.keyimport; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public abstract class Keyserver { + public static class QueryException extends Exception { + private static final long serialVersionUID = 2703768928624654512L; + + public QueryException(String message) { + super(message); + } + } + + public static class TooManyResponses extends Exception { + private static final long serialVersionUID = 2703768928624654513L; + } + + public static class InsufficientQuery extends Exception { + private static final long serialVersionUID = 2703768928624654514L; + } + + public static class AddKeyException extends Exception { + private static final long serialVersionUID = -507574859137295530L; + } + + abstract List search(String query) throws QueryException, TooManyResponses, + InsufficientQuery; + + abstract String get(String keyIdHex) throws QueryException; + + abstract void add(String armoredKey) throws AddKeyException; + + public static 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); + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index ca9edf7ae..f64282f5f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -36,9 +36,9 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; -import org.sufficientlysecure.keychain.keyimport.HkpKeyServer; +import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.util.IterableIterator; -import org.sufficientlysecure.keychain.keyimport.KeyServer.AddKeyException; +import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; import org.sufficientlysecure.keychain.util.Log; import java.io.ByteArrayOutputStream; @@ -100,7 +100,7 @@ public class PgpImportExport { } } - public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) { + public boolean uploadKeyRingToServer(HkpKeyserver server, PGPPublicKeyRing keyring) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ArmoredOutputStream aos = null; try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 805bb9dad..6f38418ff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -39,6 +39,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; @@ -54,9 +55,8 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; -import org.sufficientlysecure.keychain.keyimport.HkpKeyServer; import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.keyimport.KeybaseKeyServer; +import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -724,7 +724,7 @@ public class KeychainIntentService extends IntentService // and dataUri! /* Operation */ - HkpKeyServer server = new HkpKeyServer(keyServer); + HkpKeyserver server = new HkpKeyserver(keyServer); ProviderHelper providerHelper = new ProviderHelper(this); PGPPublicKeyRing keyring = (PGPPublicKeyRing) providerHelper.getPGPKeyRing(dataUri); @@ -746,7 +746,7 @@ public class KeychainIntentService extends IntentService ArrayList entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST); try { - KeybaseKeyServer server = new KeybaseKeyServer(); + KeybaseKeyserver server = new KeybaseKeyserver(); for (ImportKeysListEntry entry : entries) { // the keybase handle is in userId(1) String keybaseId = entry.getExtraData(); @@ -797,7 +797,7 @@ public class KeychainIntentService extends IntentService String keyServer = data.getString(DOWNLOAD_KEY_SERVER); // this downloads the keys and places them into the ImportKeysListEntry entries - HkpKeyServer server = new HkpKeyServer(keyServer); + HkpKeyserver server = new HkpKeyserver(keyServer); for (ImportKeysListEntry entry : entries) { // if available use complete fingerprint for get request diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index bf6abcd6f..e93d717e1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -38,7 +38,7 @@ import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListKeybaseLoader; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListServerLoader; import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.keyimport.KeyServer; +import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.util.Log; import java.io.ByteArrayInputStream; @@ -280,13 +280,13 @@ public class ImportKeysListFragment extends ListFragment implements mAdapter.getCount(), mAdapter.getCount()), AppMsg.STYLE_INFO ).show(); - } else if (error instanceof KeyServer.InsufficientQuery) { + } else if (error instanceof Keyserver.InsufficientQuery) { AppMsg.makeText(getActivity(), R.string.error_keyserver_insufficient_query, AppMsg.STYLE_ALERT).show(); - } else if (error instanceof KeyServer.QueryException) { + } else if (error instanceof Keyserver.QueryException) { AppMsg.makeText(getActivity(), R.string.error_keyserver_query, AppMsg.STYLE_ALERT).show(); - } else if (error instanceof KeyServer.TooManyResponses) { + } else if (error instanceof Keyserver.TooManyResponses) { AppMsg.makeText(getActivity(), R.string.error_keyserver_too_many_responses, AppMsg.STYLE_ALERT).show(); } @@ -300,7 +300,7 @@ public class ImportKeysListFragment extends ListFragment implements mAdapter.getCount(), mAdapter.getCount()), AppMsg.STYLE_INFO ).show(); - } else if (error instanceof KeyServer.QueryException) { + } else if (error instanceof Keyserver.QueryException) { AppMsg.makeText(getActivity(), R.string.error_keyserver_query, AppMsg.STYLE_ALERT).show(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 3fd958bcc..5b936c188 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -130,7 +130,7 @@ public class KeyListFragment extends LoaderFragment /** * Define Adapter and Loader on create of Activity */ - @SuppressLint("NewApi") + @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -141,8 +141,7 @@ public class KeyListFragment extends LoaderFragment mStickyList.setFastScrollEnabled(true); /* - * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only - * available for Android >= 3.0 + * Multi-selection is only available for Android >= 3.0 */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { mStickyList.setFastScrollAlwaysVisible(true); @@ -312,7 +311,7 @@ public class KeyListFragment extends LoaderFragment startActivity(viewIntent); } - @TargetApi(11) + @TargetApi(Build.VERSION_CODES.HONEYCOMB) protected void encrypt(ActionMode mode, long[] masterKeyIds) { Intent intent = new Intent(getActivity(), EncryptActivity.class); intent.setAction(EncryptActivity.ACTION_ENCRYPT); @@ -329,7 +328,7 @@ public class KeyListFragment extends LoaderFragment * @param masterKeyIds * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not */ - @TargetApi(11) + @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) { // Can only work on singular secret keys if(hasSecret && masterKeyIds.length > 1) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListKeybaseLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListKeybaseLoader.java index 420880522..0fdc019d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListKeybaseLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListKeybaseLoader.java @@ -22,8 +22,8 @@ import android.support.v4.content.AsyncTaskLoader; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; -import org.sufficientlysecure.keychain.keyimport.KeyServer; -import org.sufficientlysecure.keychain.keyimport.KeybaseKeyServer; +import org.sufficientlysecure.keychain.keyimport.Keyserver; +import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -86,7 +86,7 @@ public class ImportKeysListKeybaseLoader */ private void queryServer(String query) { - KeybaseKeyServer server = new KeybaseKeyServer(); + KeybaseKeyserver server = new KeybaseKeyserver(); try { ArrayList searchResult = server.search(query); @@ -94,11 +94,11 @@ public class ImportKeysListKeybaseLoader mEntryList.addAll(searchResult); mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, null); - } catch (KeyServer.InsufficientQuery e) { + } catch (Keyserver.InsufficientQuery e) { mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); - } catch (KeyServer.QueryException e) { + } catch (Keyserver.QueryException e) { mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); - } catch (KeyServer.TooManyResponses e) { + } catch (Keyserver.TooManyResponses e) { mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java index d5329e6f6..1b8d7d30e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java @@ -21,9 +21,9 @@ import android.content.Context; import android.support.v4.content.AsyncTaskLoader; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.keyimport.HkpKeyServer; +import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; -import org.sufficientlysecure.keychain.keyimport.KeyServer; +import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -92,7 +92,7 @@ public class ImportKeysListServerLoader * Query keyserver */ private void queryServer(String query, String keyServer, boolean enforceFingerprint) { - HkpKeyServer server = new HkpKeyServer(keyServer); + HkpKeyserver server = new HkpKeyserver(keyServer); try { ArrayList searchResult = server.search(query); @@ -116,11 +116,11 @@ public class ImportKeysListServerLoader mEntryList.addAll(searchResult); } mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, null); - } catch (KeyServer.InsufficientQuery e) { + } catch (Keyserver.InsufficientQuery e) { mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); - } catch (KeyServer.QueryException e) { + } catch (Keyserver.QueryException e) { mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); - } catch (KeyServer.TooManyResponses e) { + } catch (Keyserver.TooManyResponses e) { mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); } } -- cgit v1.2.3