diff options
author | Thialfihar <thialfihar@gmail.com> | 2010-08-17 01:02:39 +0000 |
---|---|---|
committer | Thialfihar <thialfihar@gmail.com> | 2010-08-17 01:02:39 +0000 |
commit | 6e9146c91ab9ec78837fa9ba7e21e2c01b72907f (patch) | |
tree | 16a80fcda66a9675956a6b007839f650dba363e1 /src/org/thialfihar/android/apg/HkpKeyServer.java | |
parent | b3a63beffcac99d3c80d706f10a0b7144e808fec (diff) | |
download | open-keychain-6e9146c91ab9ec78837fa9ba7e21e2c01b72907f.tar.gz open-keychain-6e9146c91ab9ec78837fa9ba7e21e2c01b72907f.tar.bz2 open-keychain-6e9146c91ab9ec78837fa9ba7e21e2c01b72907f.zip |
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.
Diffstat (limited to 'src/org/thialfihar/android/apg/HkpKeyServer.java')
-rw-r--r-- | src/org/thialfihar/android/apg/HkpKeyServer.java | 119 |
1 files changed, 119 insertions, 0 deletions
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/<a href="/pks/lookup?op=get&search=0x887DF4BE9F5C9090">9F5C9090</a> 2009-08-17 <a href="/pks/lookup?op=vindex&search=0x887DF4BE9F5C9090">Jörg Runge <joerg@joergrunge.de></a> + 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<KeyInfo> search(String query) + throws MalformedURLException, IOException { + Vector<KeyInfo> results = new Vector<KeyInfo>(); + + 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<String>(); + 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; + } +} |