diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/WebKeyDirectoryClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/WebKeyDirectoryClient.java index 06570ea21..e6df3cab9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/WebKeyDirectoryClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/WebKeyDirectoryClient.java @@ -19,30 +19,23 @@ package org.sufficientlysecure.keychain.keyimport; import android.support.annotation.Nullable; - +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; import org.sufficientlysecure.keychain.network.OkHttpClientFactory; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.util.ParcelableProxy; -import org.sufficientlysecure.keychain.util.ZBase32; +import org.sufficientlysecure.keychain.util.WebKeyDirectoryUtil; +import timber.log.Timber; import java.io.IOException; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.Proxy; import java.net.URL; import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Collections; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import timber.log.Timber; /** @@ -59,12 +52,10 @@ public class WebKeyDirectoryClient implements KeyserverClient { private WebKeyDirectoryClient() { } - private static final Pattern EMAIL_PATTERN = Pattern.compile("^\\s*(.+)@(.+)\\s*$"); - @Override public List search(String name, ParcelableProxy proxy) throws QueryFailedException { - URL webKeyDirectoryURL = toWebKeyDirectoryURL(name); + URL webKeyDirectoryURL = WebKeyDirectoryUtil.toWebKeyDirectoryURL(name); if (webKeyDirectoryURL == null) { Timber.d("Name not supported by Web Key Directory Client: " + name); @@ -130,31 +121,4 @@ public class WebKeyDirectoryClient implements KeyserverClient { public void add(String armoredKey, ParcelableProxy proxy) { throw new UnsupportedOperationException("Uploading keys to Web Key Directory is not supported"); } - - @Nullable - private static URL toWebKeyDirectoryURL(String name) { - Matcher matcher = EMAIL_PATTERN.matcher(name); - - if (!matcher.matches()) { - return null; - } - - String localPart = matcher.group(1); - String encodedPart = ZBase32.encode(toSHA1(localPart.toLowerCase().getBytes())); - String domain = matcher.group(2); - - try { - return new URL("https://" + domain + "/.well-known/openpgpkey/hu/" + encodedPart); - } catch (MalformedURLException e) { - return null; - } - } - - private static byte[] toSHA1(byte[] input) { - try { - return MessageDigest.getInstance("SHA-1").digest(input); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError("SHA-1 should always be available"); - } - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/WebKeyDirectoryUtil.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/WebKeyDirectoryUtil.java new file mode 100644 index 000000000..716aee4a0 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/WebKeyDirectoryUtil.java @@ -0,0 +1,52 @@ +package org.sufficientlysecure.keychain.util; + +import android.support.annotation.Nullable; + +import java.net.MalformedURLException; +import java.net.URL; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class WebKeyDirectoryUtil { + + private static final Pattern EMAIL_PATTERN = Pattern.compile("^\\s*([^\\s]+)@([^\\s]+)\\s*$"); + + private WebKeyDirectoryUtil() { + } + + /** + * Tries to construct a Web Key Directory from a given name. + * Returns {@code null} if unsuccessful. + * + * @see Key Discovery + */ + @Nullable + public static URL toWebKeyDirectoryURL(String name) { + Matcher matcher = EMAIL_PATTERN.matcher(name); + + if (!matcher.matches()) { + return null; + } + + String localPart = matcher.group(1); + String encodedPart = ZBase32.encode(toSHA1(localPart.toLowerCase().getBytes())); + String domain = matcher.group(2); + + try { + return new URL("https://" + domain + "/.well-known/openpgpkey/hu/" + encodedPart); + } catch (MalformedURLException e) { + return null; + } + } + + private static byte[] toSHA1(byte[] input) { + try { + return MessageDigest.getInstance("SHA-1").digest(input); + } catch (NoSuchAlgorithmException e) { + throw new AssertionError("SHA-1 should always be available"); + } + } + +} diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/util/WebKeyDirectoryUtilTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/util/WebKeyDirectoryUtilTest.java new file mode 100644 index 000000000..fd0d40b7d --- /dev/null +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/util/WebKeyDirectoryUtilTest.java @@ -0,0 +1,30 @@ +package org.sufficientlysecure.keychain.util; + +import org.junit.Test; + +import java.net.URL; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +public class WebKeyDirectoryUtilTest { + + @Test + public void testWkd() { + URL url = WebKeyDirectoryUtil.toWebKeyDirectoryURL("test-wkd@openkeychain.org"); + assertNotNull(url); + assertEquals("openkeychain.org", url.getHost()); + assertEquals("https", url.getProtocol()); + assertEquals("/.well-known/openpgpkey/hu/4hg7tescnttreaouu4z1izeuuyibwww1", url.getPath()); + } + + @Test + public void testWkdWithSpaces() { + URL url = WebKeyDirectoryUtil.toWebKeyDirectoryURL(" test-wkd@openkeychain.org "); + assertNotNull(url); + assertEquals("openkeychain.org", url.getHost()); + assertEquals("https", url.getProtocol()); + assertEquals("/.well-known/openpgpkey/hu/4hg7tescnttreaouu4z1izeuuyibwww1", url.getPath()); + } + +}