mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 06:09:55 +01:00
Add contact exchange method for pending contacts.
This commit is contained in:
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.crypto.SecretKey;
|
|||||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -13,12 +12,26 @@ import java.io.IOException;
|
|||||||
public interface ContactExchangeManager {
|
public interface ContactExchangeManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchanges contact information with a remote peer.
|
* Exchanges contact information with a remote peer and adds the peer
|
||||||
|
* as a contact.
|
||||||
*
|
*
|
||||||
* @param alice Whether the local peer takes the role of Alice
|
* @param alice Whether the local peer takes the role of Alice
|
||||||
* @return The newly added contact
|
* @return The newly added contact
|
||||||
* @throws ContactExistsException If the contact already exists
|
* @throws ContactExistsException If the contact already exists
|
||||||
*/
|
*/
|
||||||
Contact exchangeContacts(TransportId t, DuplexTransportConnection conn,
|
Contact exchangeContacts(DuplexTransportConnection conn,
|
||||||
SecretKey masterKey, boolean alice) throws IOException, DbException;
|
SecretKey masterKey, boolean alice, boolean verified)
|
||||||
|
throws IOException, DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges contact information with a remote peer and adds the peer
|
||||||
|
* as a contact, replacing the given pending contact.
|
||||||
|
*
|
||||||
|
* @param alice Whether the local peer takes the role of Alice
|
||||||
|
* @return The newly added contact
|
||||||
|
* @throws ContactExistsException If the contact already exists
|
||||||
|
*/
|
||||||
|
Contact exchangeContacts(PendingContactId p, DuplexTransportConnection conn,
|
||||||
|
SecretKey masterKey, boolean alice, boolean verified)
|
||||||
|
throws IOException, DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,18 @@ import org.briarproject.bramble.api.contact.Contact;
|
|||||||
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
@@ -36,20 +37,23 @@ import java.io.EOFException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
||||||
|
import static org.briarproject.bramble.contact.ContactExchangeRecordTypes.CONTACT_INFO;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@Immutable
|
||||||
@ParametersNotNullByDefault
|
@NotNullByDefault
|
||||||
class ContactExchangeManagerImpl implements ContactExchangeManager {
|
class ContactExchangeManagerImpl implements ContactExchangeManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
@@ -104,9 +108,22 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Contact exchangeContacts(TransportId t,
|
public Contact exchangeContacts(DuplexTransportConnection conn,
|
||||||
DuplexTransportConnection conn, SecretKey masterKey, boolean alice)
|
SecretKey masterKey, boolean alice,
|
||||||
throws IOException, DbException {
|
boolean verified) throws IOException, DbException {
|
||||||
|
return exchange(null, conn, masterKey, alice, verified);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Contact exchangeContacts(PendingContactId p,
|
||||||
|
DuplexTransportConnection conn, SecretKey masterKey, boolean alice,
|
||||||
|
boolean verified) throws IOException, DbException {
|
||||||
|
return exchange(p, conn, masterKey, alice, verified);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Contact exchange(@Nullable PendingContactId p,
|
||||||
|
DuplexTransportConnection conn, SecretKey masterKey, boolean alice,
|
||||||
|
boolean verified) throws IOException, DbException {
|
||||||
// Get the transport connection's input and output streams
|
// Get the transport connection's input and output streams
|
||||||
InputStream in = conn.getReader().getInputStream();
|
InputStream in = conn.getReader().getInputStream();
|
||||||
OutputStream out = conn.getWriter().getOutputStream();
|
OutputStream out = conn.getWriter().getOutputStream();
|
||||||
@@ -169,8 +186,8 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
|
long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
|
||||||
|
|
||||||
// Add the contact
|
// Add the contact
|
||||||
Contact contact = addContact(remoteInfo.author, localAuthor,
|
Contact contact = addContact(p, remoteInfo.author, localAuthor,
|
||||||
masterKey, timestamp, alice, remoteInfo.properties);
|
masterKey, timestamp, alice, verified, remoteInfo.properties);
|
||||||
|
|
||||||
// Contact exchange succeeded
|
// Contact exchange succeeded
|
||||||
LOG.info("Contact exchange succeeded");
|
LOG.info("Contact exchange succeeded");
|
||||||
@@ -207,18 +224,34 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
|||||||
return new ContactInfo(author, properties, signature, timestamp);
|
return new ContactInfo(author, properties, signature, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Contact addContact(Author remoteAuthor, LocalAuthor localAuthor,
|
private Contact addContact(@Nullable PendingContactId pendingContactId,
|
||||||
SecretKey masterKey, long timestamp, boolean alice,
|
Author remoteAuthor, LocalAuthor localAuthor, SecretKey masterKey,
|
||||||
|
long timestamp, boolean alice, boolean verified,
|
||||||
Map<TransportId, TransportProperties> remoteProperties)
|
Map<TransportId, TransportProperties> remoteProperties)
|
||||||
throws DbException {
|
throws DbException, FormatException {
|
||||||
return db.transactionWithResult(false, txn -> {
|
Transaction txn = db.startTransaction(false);
|
||||||
ContactId contactId = contactManager.addContact(txn, remoteAuthor,
|
try {
|
||||||
localAuthor.getId(), masterKey, timestamp, alice,
|
ContactId contactId;
|
||||||
true, true);
|
if (pendingContactId == null) {
|
||||||
|
contactId = contactManager.addContact(txn, remoteAuthor,
|
||||||
|
localAuthor.getId(), masterKey, timestamp, alice,
|
||||||
|
verified, true);
|
||||||
|
} else {
|
||||||
|
contactId = contactManager.addContact(txn, pendingContactId,
|
||||||
|
remoteAuthor, localAuthor.getId(), masterKey,
|
||||||
|
timestamp, alice, verified, true);
|
||||||
|
}
|
||||||
transportPropertyManager.addRemoteProperties(txn, contactId,
|
transportPropertyManager.addRemoteProperties(txn, contactId,
|
||||||
remoteProperties);
|
remoteProperties);
|
||||||
return contactManager.getContact(txn, contactId);
|
Contact contact = contactManager.getContact(txn, contactId);
|
||||||
});
|
db.commitTransaction(txn);
|
||||||
|
return contact;
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
// Pending contact's public key is invalid
|
||||||
|
throw new FormatException();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ContactInfo {
|
private static class ContactInfo {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
package org.briarproject.bramble.contact;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record types for the contact exchange protocol.
|
* Record types for the contact exchange protocol.
|
||||||
*/
|
*/
|
||||||
public interface RecordTypes {
|
interface ContactExchangeRecordTypes {
|
||||||
|
|
||||||
byte CONTACT_INFO = 0;
|
byte CONTACT_INFO = 0;
|
||||||
}
|
}
|
||||||
@@ -58,8 +58,8 @@ class ContactExchangeViewModel extends AndroidViewModel {
|
|||||||
SecretKey masterKey, boolean alice) {
|
SecretKey masterKey, boolean alice) {
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
Contact contact = contactExchangeManager.exchangeContacts(t,
|
Contact contact = contactExchangeManager.exchangeContacts(conn,
|
||||||
conn, masterKey, alice);
|
masterKey, alice, true);
|
||||||
// Reuse the connection as a transport connection
|
// Reuse the connection as a transport connection
|
||||||
connectionManager.manageOutgoingConnection(contact.getId(),
|
connectionManager.manageOutgoingConnection(contact.getId(),
|
||||||
t, conn);
|
t, conn);
|
||||||
|
|||||||
Reference in New Issue
Block a user