Add ability to search for keys using WKD protocol

If a search pattern that looks like an email address is found
an additional query using Web Key Directory will be performed.

Implements basic flow described in "Key Discovery" [0] I-D.
Querying SRV records is not supported.

Fixes partially #2270.

[0]: https://tools.ietf.org/html/draft-koch-openpgp-webkey-service-05#section-3.1
This commit is contained in:
Wiktor Kwapisiewicz
2018-05-08 16:08:34 +02:00
parent cfc5cc4c44
commit fa3b32eddc
7 changed files with 235 additions and 5 deletions

View File

@@ -348,6 +348,7 @@ public class Preferences {
return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
mSharedPreferences.getBoolean(Pref.SEARCH_KEYBASE, true),
false,
true,
getPreferredKeyserver());
}
@@ -365,6 +366,7 @@ public class Preferences {
public final boolean searchKeyserver;
public final boolean searchKeybase;
public final boolean searchFacebook;
public final boolean searchWebKeyDirectory;
public final HkpKeyserverAddress keyserver;
/**
@@ -373,10 +375,12 @@ public class Preferences {
* @param keyserver the keyserver url authority to search on
*/
public CloudSearchPrefs(boolean searchKeyserver, boolean searchKeybase,
boolean searchFacebook, HkpKeyserverAddress keyserver) {
boolean searchFacebook, boolean searchWebKeyDirectory,
HkpKeyserverAddress keyserver) {
this.searchKeyserver = searchKeyserver;
this.searchKeybase = searchKeybase;
this.searchFacebook = searchFacebook;
this.searchWebKeyDirectory = searchWebKeyDirectory;
this.keyserver = keyserver;
}
@@ -384,6 +388,7 @@ public class Preferences {
searchKeyserver = in.readByte() != 0x00;
searchKeybase = in.readByte() != 0x00;
searchFacebook = in.readByte() != 0x00;
searchWebKeyDirectory = in.readByte() != 0x00;
keyserver = in.readParcelable(HkpKeyserverAddress.class.getClassLoader());
}
@@ -397,6 +402,7 @@ public class Preferences {
dest.writeByte((byte) (searchKeyserver ? 0x01 : 0x00));
dest.writeByte((byte) (searchKeybase ? 0x01 : 0x00));
dest.writeByte((byte) (searchFacebook ? 0x01 : 0x00));
dest.writeByte((byte) (searchWebKeyDirectory ? 0x01 : 0x00));
dest.writeParcelable(keyserver, flags);
}

View File

@@ -0,0 +1,45 @@
package org.sufficientlysecure.keychain.util;
/**
* Utilities for handling ZBase-32 encoding.
*
* @see <a href="https://tools.ietf.org/html/rfc6189#section-5.1.6">Z-Base32 encoding as used in RFC 6189</a>
*/
public final class ZBase32 {
private static final char[] ALPHABET = "ybndrfg8ejkmcpqxot1uwisza345h769".toCharArray();
private static final int SHIFT = Integer.numberOfTrailingZeros(ALPHABET.length);
private static final int MASK = ALPHABET.length - 1;
public static String encode(byte[] data) {
if (data.length == 0) {
return "";
}
StringBuilder result = new StringBuilder();
int buffer = data[0];
int index = 1;
int bitsLeft = 8;
while (bitsLeft > 0 || index < data.length) {
if (bitsLeft < SHIFT) {
if (index < data.length) {
buffer <<= 8;
buffer |= (data[index++] & 0xff);
bitsLeft += 8;
} else {
int pad = SHIFT - bitsLeft;
buffer <<= pad;
bitsLeft += pad;
}
}
bitsLeft -= SHIFT;
result.append(ALPHABET[MASK & (buffer >> bitsLeft)]);
}
return result.toString();
}
private ZBase32() {
}
}