Implement getHandshakeLink().

This commit is contained in:
akwizgran
2019-05-22 13:33:36 +01:00
parent 643270e247
commit af8b7f1130
6 changed files with 110 additions and 17 deletions

View File

@@ -33,23 +33,18 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32_LINK_BYTES;
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNVERIFIED;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED;
import static org.briarproject.bramble.util.StringUtils.getRandomBase32String;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
@ThreadSafe
@NotNullByDefault
class ContactManagerImpl implements ContactManager {
private static final String REMOTE_CONTACT_LINK =
"briar://" + getRandomBase32String(BASE32_LINK_BYTES);
private final DatabaseComponent db;
private final KeyManager keyManager;
private final IdentityManager identityManager;
@@ -120,9 +115,10 @@ class ContactManagerImpl implements ContactManager {
}
@Override
public String getHandshakeLink() {
// TODO replace with real implementation
return REMOTE_CONTACT_LINK;
public String getHandshakeLink() throws DbException {
KeyPair keyPair = db.transactionWithResult(true,
identityManager::getHandshakeKeys);
return pendingContactFactory.createHandshakeLink(keyPair.getPublic());
}
@Override

View File

@@ -3,6 +3,7 @@ package org.briarproject.bramble.contact;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.crypto.PublicKey;
interface PendingContactFactory {
@@ -15,4 +16,9 @@ interface PendingContactFactory {
*/
PendingContact createPendingContact(String link, String alias)
throws FormatException;
/**
* Creates a handshake link from the given public key.
*/
String createHandshakeLink(PublicKey k);
}

View File

@@ -20,6 +20,7 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
import static org.briarproject.bramble.api.crypto.CryptoConstants.KEY_TYPE_AGREEMENT;
class PendingContactFactoryImpl implements PendingContactFactory {
@@ -41,18 +42,31 @@ class PendingContactFactoryImpl implements PendingContactFactory {
return new PendingContact(id, publicKey, alias, timestamp);
}
@Override
public String createHandshakeLink(PublicKey k) {
if (!k.getKeyType().equals(KEY_TYPE_AGREEMENT))
throw new IllegalArgumentException();
byte[] encoded = k.getEncoded();
if (encoded.length != RAW_LINK_BYTES - 1)
throw new IllegalArgumentException();
byte[] raw = new byte[RAW_LINK_BYTES];
raw[0] = FORMAT_VERSION;
arraycopy(encoded, 0, raw, 1, encoded.length);
return "briar://" + Base32.encode(raw).toLowerCase();
}
private PublicKey parseHandshakeLink(String link) throws FormatException {
Matcher matcher = LINK_REGEX.matcher(link);
if (!matcher.find()) throw new FormatException();
// Discard 'briar://' and anything before or after the link
link = matcher.group(2);
byte[] base32 = Base32.decode(link, false);
if (base32.length != RAW_LINK_BYTES) throw new AssertionError();
byte version = base32[0];
byte[] raw = Base32.decode(link, false);
if (raw.length != RAW_LINK_BYTES) throw new AssertionError();
byte version = raw[0];
if (version != FORMAT_VERSION)
throw new UnsupportedVersionException(version < FORMAT_VERSION);
byte[] publicKeyBytes = new byte[base32.length - 1];
arraycopy(base32, 1, publicKeyBytes, 0, publicKeyBytes.length);
byte[] publicKeyBytes = new byte[raw.length - 1];
arraycopy(raw, 1, publicKeyBytes, 0, publicKeyBytes.length);
try {
KeyParser parser = crypto.getAgreementKeyParser();
return parser.parsePublicKey(publicKeyBytes);