mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 07:09:56 +01:00
Invitation protocol was proceeding after confirmation timed out.
Both sides now close the connection after exchanging confirmation results unless both results are positive.
This commit is contained in:
@@ -288,9 +288,11 @@ implements InvitationListener {
|
|||||||
if(code == remoteConfirmationCode) {
|
if(code == remoteConfirmationCode) {
|
||||||
localMatched = true;
|
localMatched = true;
|
||||||
if(remoteMatched) setView(new ContactDetailsView(this));
|
if(remoteMatched) setView(new ContactDetailsView(this));
|
||||||
|
else if(remoteCompared) setView(new CodesDoNotMatchView(this));
|
||||||
else setView(new WaitForContactView(this));
|
else setView(new WaitForContactView(this));
|
||||||
task.localConfirmationSucceeded();
|
task.localConfirmationSucceeded();
|
||||||
} else {
|
} else {
|
||||||
|
localMatched = false;
|
||||||
setView(new CodesDoNotMatchView(this));
|
setView(new CodesDoNotMatchView(this));
|
||||||
task.localConfirmationFailed();
|
task.localConfirmationFailed();
|
||||||
}
|
}
|
||||||
@@ -353,6 +355,7 @@ implements InvitationListener {
|
|||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
remoteCompared = true;
|
remoteCompared = true;
|
||||||
|
remoteMatched = false;
|
||||||
if(localMatched)
|
if(localMatched)
|
||||||
setView(new CodesDoNotMatchView(AddContactActivity.this));
|
setView(new CodesDoNotMatchView(AddContactActivity.this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,23 +106,30 @@ class AliceConnector extends Connector {
|
|||||||
int aliceCode = codes[0], bobCode = codes[1];
|
int aliceCode = codes[0], bobCode = codes[1];
|
||||||
group.keyAgreementSucceeded(aliceCode, bobCode);
|
group.keyAgreementSucceeded(aliceCode, bobCode);
|
||||||
// Exchange confirmation results
|
// Exchange confirmation results
|
||||||
|
boolean localMatched, remoteMatched;
|
||||||
try {
|
try {
|
||||||
sendConfirmation(w);
|
localMatched = group.waitForLocalConfirmationResult();
|
||||||
if(receiveConfirmation(r)) group.remoteConfirmationSucceeded();
|
sendConfirmation(w, localMatched);
|
||||||
else group.remoteConfirmationFailed();
|
remoteMatched = receiveConfirmation(r);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
tryToClose(conn, true);
|
|
||||||
group.remoteConfirmationFailed();
|
group.remoteConfirmationFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
return;
|
return;
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
if(LOG.isLoggable(WARNING))
|
if(LOG.isLoggable(WARNING))
|
||||||
LOG.warning("Interrupted while waiting for confirmation");
|
LOG.warning("Interrupted while waiting for confirmation");
|
||||||
tryToClose(conn, true);
|
|
||||||
group.remoteConfirmationFailed();
|
group.remoteConfirmationFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(remoteMatched) group.remoteConfirmationSucceeded();
|
||||||
|
else group.remoteConfirmationFailed();
|
||||||
|
if(!(localMatched && remoteMatched)) {
|
||||||
|
tryToClose(conn, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// The timestamp is taken after exhanging confirmation results
|
// The timestamp is taken after exhanging confirmation results
|
||||||
long localTimestamp = clock.currentTimeMillis();
|
long localTimestamp = clock.currentTimeMillis();
|
||||||
// Confirmation succeeded - upgrade to a secure connection
|
// Confirmation succeeded - upgrade to a secure connection
|
||||||
@@ -152,13 +159,13 @@ class AliceConnector extends Connector {
|
|||||||
remoteProps = receiveTransportProperties(r);
|
remoteProps = receiveTransportProperties(r);
|
||||||
} catch(GeneralSecurityException e) {
|
} catch(GeneralSecurityException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
tryToClose(conn, true);
|
|
||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
return;
|
return;
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
tryToClose(conn, true);
|
|
||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The epoch is the minimum of the peers' timestamps
|
// The epoch is the minimum of the peers' timestamps
|
||||||
|
|||||||
@@ -106,23 +106,30 @@ class BobConnector extends Connector {
|
|||||||
int aliceCode = codes[0], bobCode = codes[1];
|
int aliceCode = codes[0], bobCode = codes[1];
|
||||||
group.keyAgreementSucceeded(bobCode, aliceCode);
|
group.keyAgreementSucceeded(bobCode, aliceCode);
|
||||||
// Exchange confirmation results
|
// Exchange confirmation results
|
||||||
|
boolean localMatched, remoteMatched;
|
||||||
try {
|
try {
|
||||||
if(receiveConfirmation(r)) group.remoteConfirmationSucceeded();
|
remoteMatched = receiveConfirmation(r);
|
||||||
else group.remoteConfirmationFailed();
|
localMatched = group.waitForLocalConfirmationResult();
|
||||||
sendConfirmation(w);
|
sendConfirmation(w, localMatched);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
tryToClose(conn, true);
|
|
||||||
group.remoteConfirmationFailed();
|
group.remoteConfirmationFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
return;
|
return;
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
if(LOG.isLoggable(WARNING))
|
if(LOG.isLoggable(WARNING))
|
||||||
LOG.warning("Interrupted while waiting for confirmation");
|
LOG.warning("Interrupted while waiting for confirmation");
|
||||||
tryToClose(conn, true);
|
|
||||||
group.remoteConfirmationFailed();
|
group.remoteConfirmationFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(remoteMatched) group.remoteConfirmationSucceeded();
|
||||||
|
else group.remoteConfirmationFailed();
|
||||||
|
if(!(localMatched && remoteMatched)) {
|
||||||
|
tryToClose(conn, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// The timestamp is taken after exhanging confirmation results
|
// The timestamp is taken after exhanging confirmation results
|
||||||
long localTimestamp = clock.currentTimeMillis();
|
long localTimestamp = clock.currentTimeMillis();
|
||||||
// Confirmation succeeded - upgrade to a secure connection
|
// Confirmation succeeded - upgrade to a secure connection
|
||||||
@@ -152,13 +159,13 @@ class BobConnector extends Connector {
|
|||||||
sendTransportProperties(w);
|
sendTransportProperties(w);
|
||||||
} catch(GeneralSecurityException e) {
|
} catch(GeneralSecurityException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
tryToClose(conn, true);
|
|
||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
return;
|
return;
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
tryToClose(conn, true);
|
|
||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The epoch is the minimum of the peers' timestamps
|
// The epoch is the minimum of the peers' timestamps
|
||||||
|
|||||||
@@ -175,21 +175,23 @@ abstract class Connector extends Thread {
|
|||||||
throw new GeneralSecurityException();
|
throw new GeneralSecurityException();
|
||||||
}
|
}
|
||||||
// Derive the master secret
|
// Derive the master secret
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info(pluginName + " deriving master secret");
|
||||||
return crypto.deriveMasterSecret(key, keyPair, alice);
|
return crypto.deriveMasterSecret(key, keyPair, alice);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendConfirmation(Writer w) throws IOException,
|
protected void sendConfirmation(Writer w, boolean matched)
|
||||||
InterruptedException {
|
throws IOException {
|
||||||
boolean matched = group.waitForLocalConfirmationResult();
|
|
||||||
w.writeBoolean(matched);
|
w.writeBoolean(matched);
|
||||||
w.flush();
|
w.flush();
|
||||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent confirmation");
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info(pluginName + " sent confirmation: " + matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean receiveConfirmation(Reader r) throws IOException {
|
protected boolean receiveConfirmation(Reader r) throws IOException {
|
||||||
boolean matched = r.readBoolean();
|
boolean matched = r.readBoolean();
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
LOG.info(pluginName + " received confirmation");
|
LOG.info(pluginName + " received confirmation: " + matched);
|
||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,15 +197,15 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
public void localConfirmationFailed() {
|
public void localConfirmationFailed() {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
localCompared = true;
|
localCompared = true;
|
||||||
|
localMatched = false;
|
||||||
}
|
}
|
||||||
localConfirmationLatch.countDown();
|
localConfirmationLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getAndSetConnected() {
|
boolean getAndSetConnected() {
|
||||||
boolean redundant = connected.getAndSet(true);
|
boolean redundant = connected.getAndSet(true);
|
||||||
if(!redundant) {
|
if(!redundant)
|
||||||
for(InvitationListener l : listeners) l.connectionSucceeded();
|
for(InvitationListener l : listeners) l.connectionSucceeded();
|
||||||
}
|
|
||||||
return redundant;
|
return redundant;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +222,13 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
for(InvitationListener l : listeners) l.keyAgreementFailed();
|
for(InvitationListener l : listeners) l.keyAgreementFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean waitForLocalConfirmationResult() throws InterruptedException {
|
||||||
|
localConfirmationLatch.await(CONFIRMATION_TIMEOUT, MILLISECONDS);
|
||||||
|
synchronized(this) {
|
||||||
|
return localMatched;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void remoteConfirmationSucceeded() {
|
void remoteConfirmationSucceeded() {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
remoteCompared = true;
|
remoteCompared = true;
|
||||||
@@ -233,17 +240,11 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
|||||||
void remoteConfirmationFailed() {
|
void remoteConfirmationFailed() {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
remoteCompared = true;
|
remoteCompared = true;
|
||||||
|
remoteMatched = false;
|
||||||
}
|
}
|
||||||
for(InvitationListener l : listeners) l.remoteConfirmationFailed();
|
for(InvitationListener l : listeners) l.remoteConfirmationFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean waitForLocalConfirmationResult() throws InterruptedException {
|
|
||||||
localConfirmationLatch.await(CONFIRMATION_TIMEOUT, MILLISECONDS);
|
|
||||||
synchronized(this) {
|
|
||||||
return localMatched;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pseudonymExchangeSucceeded(Author remoteAuthor) {
|
void pseudonymExchangeSucceeded(Author remoteAuthor) {
|
||||||
String name = remoteAuthor.getName();
|
String name = remoteAuthor.getName();
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
|
|||||||
Reference in New Issue
Block a user