Extract out contruction of Web Key Directory URLs
Moves `toWebKeyDirectoryURL` to a separate class adding unit tests for URL correctness as well as support for spaces at the beginning and end of the e-mail. Spaces are frequently automatically inserted by soft keyboards.
This commit is contained in:
@@ -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<ImportKeysListEntry> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <a href="https://tools.ietf.org/html/draft-koch-openpgp-webkey-service-05#section-3.1">Key Discovery</a>
|
||||
*/
|
||||
@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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user