From 6e9146c91ab9ec78837fa9ba7e21e2c01b72907f Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Tue, 17 Aug 2010 01:02:39 +0000 Subject: added initial support for HKP key servers, allowing searching and key import Update issue 9 Can search a key server now, touch a result to import the key. Still needs better error handling and some Intents to import keys based on key ID. Also still need key server preferences. --- src/org/thialfihar/android/apg/HkpKeyServer.java | 119 +++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/org/thialfihar/android/apg/HkpKeyServer.java (limited to 'src/org/thialfihar/android/apg/HkpKeyServer.java') diff --git a/src/org/thialfihar/android/apg/HkpKeyServer.java b/src/org/thialfihar/android/apg/HkpKeyServer.java new file mode 100644 index 000000000..ce65e1da2 --- /dev/null +++ b/src/org/thialfihar/android/apg/HkpKeyServer.java @@ -0,0 +1,119 @@ +package org.thialfihar.android.apg; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import android.text.Html; + +public class HkpKeyServer extends KeyServer { + private String mHost; + private short mPort = 11371; + + // example: + // pub 2048R/9F5C9090 2009-08-17 Jörg Runge <joerg@joergrunge.de> + public static Pattern PUB_KEY_LINE = + Pattern.compile("pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", + Pattern.CASE_INSENSITIVE); + public static Pattern USER_ID_LINE = + Pattern.compile("^ +(.+)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); + + public HkpKeyServer(String host) { + mHost = host; + } + + public HkpKeyServer(String host, short port) { + mHost = host; + mPort = port; + } + + @Override + List search(String query) + throws MalformedURLException, IOException { + Vector results = new Vector(); + + String url = "http://" + mHost + ":" + mPort + "/pks/lookup?op=index&search=" + + URLEncoder.encode(query, "utf8"); + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + InputStream is = conn.getInputStream(); + ByteArrayOutputStream raw = new ByteArrayOutputStream(); + + byte buffer[] = new byte[1 << 16]; + int n = 0; + while ((n = is.read(buffer)) != -1) { + raw.write(buffer, 0, n); + } + + String encoding = conn.getContentEncoding(); + if (encoding == null) { + encoding = "utf8"; + } + String data = raw.toString(encoding); + Matcher matcher = PUB_KEY_LINE.matcher(data); + while (matcher.find()) { + KeyInfo info = new KeyInfo(); + info.size = Integer.parseInt(matcher.group(1)); + info.algorithm = matcher.group(2); + info.keyId = Apg.keyFromHex(matcher.group(3)); + info.fingerPrint = Apg.getFingerPrint(info.keyId); + String chunks[] = matcher.group(4).split("-"); + info.date = new GregorianCalendar(Integer.parseInt(chunks[0]), + Integer.parseInt(chunks[1]), + Integer.parseInt(chunks[2])).getTime(); + info.userIds = new Vector(); + if (matcher.group(5).startsWith("*** KEY")) { + info.revoked = matcher.group(5); + } else { + String tmp = matcher.group(5).replaceAll("<.*?>", ""); + tmp = Html.fromHtml(tmp).toString(); + info.userIds.add(tmp); + } + if (matcher.group(6).length() > 0) { + Matcher matcher2 = USER_ID_LINE.matcher(matcher.group(6)); + while (matcher2.find()) { + String tmp = matcher2.group(1).replaceAll("<.*?>", ""); + tmp = Html.fromHtml(tmp).toString(); + info.userIds.add(tmp); + } + } + results.add(info); + } + + return results; + } + + @Override + String get(long keyId) + throws MalformedURLException, IOException { + String url = "http://" + mHost + ":" + mPort + + "/pks/lookup?op=get&search=0x" + Apg.keyToHex(keyId); + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + InputStream is = conn.getInputStream(); + ByteArrayOutputStream raw = new ByteArrayOutputStream(); + + byte buffer[] = new byte[1 << 16]; + int n = 0; + while ((n = is.read(buffer)) != -1) { + raw.write(buffer, 0, n); + } + + String data = raw.toString(); + Matcher matcher = Apg.PGP_PUBLIC_KEY.matcher(data); + if (matcher.find()) { + return matcher.group(1); + } + + return null; + } +} -- cgit v1.2.3