Compare commits

...

14 Commits

Author SHA1 Message Date
ameba23
d564fc8713 Add logging on replacing outgoing transport keys 2021-10-04 13:55:03 +02:00
ameba23
41443db817 Bug with checking contactId, improve logging 2021-09-30 15:54:32 +02:00
ameba23
274722d695 Log keys in hex on handshake 2021-09-29 10:15:41 +02:00
ameba23
275c7d261f Fix bug when finding handshake mode keys 2021-09-28 14:45:01 +02:00
ameba23
667f8db4f0 Log keys in hex when failing to recognise tags 2021-09-28 12:47:44 +02:00
ameba23
8398ecdeae Merge branch 'social-backup-poc' into social-backup-handshake-after-recover
* social-backup-poc:
  Rm test which was not present in this branch before cherry pick
  Resolve conflict on cherry pick commit to use ByteBuddyClassImposteriser
  Tell animal sniffer gradle plugin to ignore java.util.Objects
  Improve lost password and setup password dialog for social backup
  When creating social backup, only allow selecting contacts when there are at least 2 contacts in contact list
  Disable help recover account option by default
2021-09-28 08:15:28 +02:00
ameba23
8437aa1b10 If current keys are not in handshake mode, look for handshake mode keys 2021-08-27 10:04:50 +02:00
ameba23
9cf00efa9c Comment out additional logging when restoring account 2021-08-27 10:00:27 +02:00
ameba23
2a45fd3c91 Use new method to get stream context in handshake mode on incoming duplex sync connection 2021-08-27 09:58:08 +02:00
ameba23
f1f16f8474 Additional logging for outgoing duplex sync connection 2021-08-27 09:56:05 +02:00
ameba23
873675d68f Additional logging when reading tag 2021-08-27 09:55:28 +02:00
ameba23
1ffa8ee024 Add a method to get stream context in handshake mode 2021-08-27 09:54:50 +02:00
ameba23
a425a33209 Add a method to get stream context in handshake mode 2021-08-27 09:54:24 +02:00
ameba23
5adbf18851 Add and retrieve Onion private key to/from Tor transport propeties 2021-08-27 09:52:04 +02:00
9 changed files with 110 additions and 9 deletions

View File

@@ -116,4 +116,8 @@ public interface KeyManager {
@Nullable @Nullable
StreamContext getStreamContext(TransportId t, byte[] tag) StreamContext getStreamContext(TransportId t, byte[] tag)
throws DbException; throws DbException;
@Nullable
StreamContext getStreamContextInHandshakeMode(ContactId c, TransportId t)
throws DbException;
} }

View File

@@ -47,7 +47,9 @@ abstract class Connection {
TransportId transportId) { TransportId transportId) {
StreamContext ctx; StreamContext ctx;
try { try {
LOG.info("Reading tag...");
byte[] tag = readTag(reader.getInputStream()); byte[] tag = readTag(reader.getInputStream());
LOG.info("Read tag!");
return keyManager.getStreamContext(transportId, tag); return keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) { } catch (IOException | DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);

View File

@@ -130,13 +130,17 @@ class IncomingDuplexSyncConnection extends DuplexSyncConnection
private boolean performHandshake(StreamContext ctxIn, ContactId contactId) { private boolean performHandshake(StreamContext ctxIn, ContactId contactId) {
LOG.info("Performing handshake (Incoming)"); LOG.info("Performing handshake (Incoming)");
// Allocate the outgoing stream context // Allocate the outgoing stream context
StreamContext ctxOut = StreamContext ctxOut;
allocateStreamContext(contactId, transportId);
if (ctxOut == null) { try {
ctxOut = keyManager.getStreamContextInHandshakeMode(contactId, transportId);
} catch (DbException e) {
logException(LOG, WARNING, e);
LOG.warning("Could not allocate stream context"); LOG.warning("Could not allocate stream context");
onReadError(true); onReadError(true);
return false; return false;
} }
try { try {
InputStream in = streamReaderFactory.createStreamReader( InputStream in = streamReaderFactory.createStreamReader(
reader.getInputStream(), ctxIn); reader.getInputStream(), ctxIn);
@@ -148,7 +152,7 @@ class IncomingDuplexSyncConnection extends DuplexSyncConnection
handshakeManager.handshake(contactId, in, out); handshakeManager.handshake(contactId, in, out);
keyManager.addRotationKeys(contactId, result.getMasterKey(), keyManager.addRotationKeys(contactId, result.getMasterKey(),
TIMESTAMP, result.isAlice(), true); TIMESTAMP, result.isAlice(), true);
LOG.info("Rotation keys added"); LOG.info("Rotation keys added - IncomingDuplexSyncConnection");
return true; return true;
} catch (IOException | DbException e) { } catch (IOException | DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);

View File

@@ -64,6 +64,7 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
LOG.info("Running OutgoingDuplexSyncConnection on transport " + LOG.info("Running OutgoingDuplexSyncConnection on transport " +
transportId.getString()); transportId.getString());
// Allocate a stream context // Allocate a stream context
StreamContext ctx = allocateStreamContext(contactId, transportId); StreamContext ctx = allocateStreamContext(contactId, transportId);
if (ctx == null) { if (ctx == null) {
LOG.warning("Could not allocate stream context"); LOG.warning("Could not allocate stream context");
@@ -71,6 +72,7 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
return; return;
} }
if (ctx.isHandshakeMode()) { if (ctx.isHandshakeMode()) {
LOG.info("OutgoingDuplexSyncConnection - context is in handshake mode, performing handshake");
if (!performHandshake(ctx)) { if (!performHandshake(ctx)) {
LOG.warning("Handshake failed"); LOG.warning("Handshake failed");
return; return;
@@ -155,7 +157,8 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
} }
private boolean performHandshake(StreamContext ctxOut) { private boolean performHandshake(StreamContext ctxOut) {
LOG.info("Performing handshake (Outgoing)"); LOG.info("Performing handshake (Outgoing) for transport " +
ctxOut.getTransportId().getString());
// Flush the output stream to send the outgoing stream header // Flush the output stream to send the outgoing stream header
StreamWriter out; StreamWriter out;
try { try {
@@ -177,7 +180,7 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
} }
// Check that the stream comes from the expected contact // Check that the stream comes from the expected contact
ContactId inContactId = ctxIn.getContactId(); ContactId inContactId = ctxIn.getContactId();
if (contactId == null) { if (inContactId == null) {
LOG.warning("Expected contact tag, got rendezvous tag"); LOG.warning("Expected contact tag, got rendezvous tag");
onReadError(); onReadError();
return false; return false;
@@ -196,7 +199,7 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
handshakeManager.handshake(contactId, in, out); handshakeManager.handshake(contactId, in, out);
keyManager.addRotationKeys(contactId, result.getMasterKey(), keyManager.addRotationKeys(contactId, result.getMasterKey(),
TIMESTAMP, result.isAlice(), true); TIMESTAMP, result.isAlice(), true);
LOG.info("Rotation keys added"); LOG.info("Rotation keys added - OutgoingDuplexSyncConnection");
return true; return true;
} catch (IOException | DbException e) { } catch (IOException | DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);

View File

@@ -470,6 +470,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (now - then >= V3_MIGRATION_PERIOD_MS) retireV2HiddenService(); if (now - then >= V3_MIGRATION_PERIOD_MS) retireV2HiddenService();
else publishV2HiddenService(port, privKey2); else publishV2HiddenService(port, privKey2);
} }
if (isNullOrEmpty(privKey3)) {
TransportProperties p = callback.getLocalProperties();
privKey3 = p.get(HS_PRIVATE_KEY_V3);
}
publishV3HiddenService(port, privKey3); publishV3HiddenService(port, privKey3);
} }
@@ -511,9 +515,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try { try {
// Use the control connection to set up the hidden service // Use the control connection to set up the hidden service
if (privKey == null) { if (privKey == null) {
LOG.info("Private key is null");
response = controlConnection.addOnion("NEW:ED25519-V3", response = controlConnection.addOnion("NEW:ED25519-V3",
portLines, null); portLines, null);
} else { } else {
LOG.info("Private key is not null");
response = controlConnection.addOnion(privKey, portLines); response = controlConnection.addOnion(privKey, portLines);
} }
} catch (IOException e) { } catch (IOException e) {
@@ -535,12 +541,15 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (privKey == null) { if (privKey == null) {
// Publish the hidden service's onion hostname in transport props // Publish the hidden service's onion hostname in transport props
TransportProperties p = new TransportProperties(); TransportProperties p = new TransportProperties();
String now = String.valueOf(clock.currentTimeMillis());
p.put(PROP_ONION_V3, onion3); p.put(PROP_ONION_V3, onion3);
p.put(HS_PRIVATE_KEY_V3, response.get(HS_PRIVKEY));
p.put(HS_V3_CREATED, now);
callback.mergeLocalProperties(p); callback.mergeLocalProperties(p);
// Save the hidden service's private key for next time // Save the hidden service's private key for next time
Settings s = new Settings(); Settings s = new Settings();
s.put(HS_PRIVATE_KEY_V3, response.get(HS_PRIVKEY)); s.put(HS_PRIVATE_KEY_V3, response.get(HS_PRIVKEY));
s.put(HS_V3_CREATED, String.valueOf(clock.currentTimeMillis())); s.put(HS_V3_CREATED, now);
callback.mergeSettings(s); callback.mergeSettings(s);
} }
} }

View File

@@ -128,6 +128,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
throws DbException, GeneralSecurityException { throws DbException, GeneralSecurityException {
SecretKey staticMasterKey = transportCrypto SecretKey staticMasterKey = transportCrypto
.deriveStaticMasterKey(theirPublicKey, ourKeyPair); .deriveStaticMasterKey(theirPublicKey, ourKeyPair);
LOG.info("Deriving root handshake key " + c.toString() + " " + ourKeyPair.getPublic().toString() + " them: " + theirPublicKey.toString());
SecretKey rootKey = SecretKey rootKey =
transportCrypto.deriveHandshakeRootKey(staticMasterKey, false); transportCrypto.deriveHandshakeRootKey(staticMasterKey, false);
boolean alice = transportCrypto.isAlice(theirPublicKey, ourKeyPair); boolean alice = transportCrypto.isAlice(theirPublicKey, ourKeyPair);
@@ -135,6 +136,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
for (Entry<TransportId, TransportKeyManager> e : managers.entrySet()) { for (Entry<TransportId, TransportKeyManager> e : managers.entrySet()) {
TransportId t = e.getKey(); TransportId t = e.getKey();
TransportKeyManager m = e.getValue(); TransportKeyManager m = e.getValue();
LOG.info("Adding handshake keys for transport " + t.getString());
ids.put(t, m.addHandshakeKeys(txn, c, rootKey, alice)); ids.put(t, m.addHandshakeKeys(txn, c, rootKey, alice));
} }
return ids; return ids;
@@ -205,6 +207,14 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
m.getStreamContext(txn, tag))); m.getStreamContext(txn, tag)));
} }
@Override
public StreamContext getStreamContextInHandshakeMode(ContactId c, TransportId t)
throws DbException {
return withManager(t, m ->
db.transactionWithNullableResult(false, txn ->
m.getStreamContextInHandshakeMode(txn, c)));
}
@Override @Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof ContactRemovedEvent) { if (e instanceof ContactRemovedEvent) {

View File

@@ -48,4 +48,7 @@ interface TransportKeyManager {
StreamContext getStreamContext(Transaction txn, byte[] tag) StreamContext getStreamContext(Transaction txn, byte[] tag)
throws DbException; throws DbException;
@Nullable
StreamContext getStreamContextInHandshakeMode(Transaction txn, ContactId c)
throws DbException;
} }

View File

@@ -19,6 +19,7 @@ import org.briarproject.bramble.api.transport.StreamContext;
import org.briarproject.bramble.api.transport.TransportKeySet; import org.briarproject.bramble.api.transport.TransportKeySet;
import org.briarproject.bramble.api.transport.TransportKeys; import org.briarproject.bramble.api.transport.TransportKeys;
import org.briarproject.bramble.transport.ReorderingWindow.Change; import org.briarproject.bramble.transport.ReorderingWindow.Change;
import org.briarproject.bramble.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -182,9 +183,12 @@ class TransportKeyManagerImpl implements TransportKeyManager {
if (old == null || (old.getKeys().isHandshakeMode() && if (old == null || (old.getKeys().isHandshakeMode() &&
!ks.getKeys().isHandshakeMode()) || !ks.getKeys().isHandshakeMode()) ||
old.getKeySetId().getInt() < ks.getKeySetId().getInt()) { old.getKeySetId().getInt() < ks.getKeySetId().getInt()) {
LOG.info("Replacing Outgoing keys!");
if (ks.getContactId() == null) if (ks.getContactId() == null)
pendingContactOutContexts.put(ks.getPendingContactId(), ks); pendingContactOutContexts.put(ks.getPendingContactId(), ks);
else contactOutContexts.put(ks.getContactId(), ks); else contactOutContexts.put(ks.getContactId(), ks);
} else {
LOG.info("Not replacing Outgoing keys!");
} }
} }
} }
@@ -372,6 +376,9 @@ class TransportKeyManagerImpl implements TransportKeyManager {
MutableTransportKeySet ks = getOutgoingKeySet(c, p); MutableTransportKeySet ks = getOutgoingKeySet(c, p);
if (ks == null) return null; if (ks == null) return null;
MutableTransportKeys keys = ks.getKeys(); MutableTransportKeys keys = ks.getKeys();
LOG.info("Using keys for outgoing connection - handshake mode: " +
keys.isHandshakeMode());
MutableOutgoingKeys outKeys = keys.getCurrentOutgoingKeys(); MutableOutgoingKeys outKeys = keys.getCurrentOutgoingKeys();
if (!outKeys.isActive()) throw new AssertionError(); if (!outKeys.isActive()) throw new AssertionError();
if (outKeys.getStreamCounter() > MAX_32_BIT_UNSIGNED) return null; if (outKeys.getStreamCounter() > MAX_32_BIT_UNSIGNED) return null;
@@ -395,7 +402,18 @@ class TransportKeyManagerImpl implements TransportKeyManager {
try { try {
// Look up the incoming keys for the tag // Look up the incoming keys for the tag
TagContext tagCtx = inContexts.remove(new Bytes(tag)); TagContext tagCtx = inContexts.remove(new Bytes(tag));
if (tagCtx == null) return null; if (tagCtx == null) {
LOG.info("Cannot find tag!");
for (MutableTransportKeySet t : keys.values()) {
LOG.info("Header key: " + StringUtils
.toHexString(t.getKeys().getCurrentIncomingKeys()
.getHeaderKey().getBytes()));
LOG.info("Tag key: " + StringUtils.toHexString(
t.getKeys().getCurrentIncomingKeys().getTagKey()
.getBytes()));
}
return null;
}
MutableIncomingKeys inKeys = tagCtx.inKeys; MutableIncomingKeys inKeys = tagCtx.inKeys;
// Create a stream context // Create a stream context
StreamContext ctx = new StreamContext(tagCtx.contactId, StreamContext ctx = new StreamContext(tagCtx.contactId,
@@ -443,6 +461,51 @@ class TransportKeyManagerImpl implements TransportKeyManager {
} }
} }
@Override
public StreamContext getStreamContextInHandshakeMode(Transaction txn,
ContactId c)
throws DbException {
lock.lock();
try {
MutableTransportKeySet ks = getOutgoingKeySet(c, null);
if (ks == null) return null;
MutableTransportKeys currentKeys = ks.getKeys();
LOG.info("Current keys handshake mode? " +
currentKeys.isHandshakeMode());
if (currentKeys.isHandshakeMode())
return getStreamContext(txn, c, null);
for (MutableTransportKeySet keySet : this.keys.values()) {
MutableTransportKeys keys = keySet.getKeys();
if (!keys.isHandshakeMode()) continue;
LOG.info("Found handshake mode keys");
MutableOutgoingKeys outKeys = keys.getCurrentOutgoingKeys();
// if (!outKeys.isActive()) throw new AssertionError();
if (outKeys.getStreamCounter() > MAX_32_BIT_UNSIGNED)
return null;
// Create a stream context
LOG.info("Creating handshake mode stream context");
StreamContext ctx = new StreamContext(c, null, transportId,
outKeys.getTagKey(), outKeys.getHeaderKey(),
outKeys.getStreamCounter(), keys.isHandshakeMode());
LOG.info("Tag key: " +
StringUtils.toHexString(outKeys.getTagKey().getBytes()));
LOG.info("Header key: " +
StringUtils.toHexString(outKeys.getHeaderKey().getBytes()));
// Increment the stream counter and write it back to the DB
outKeys.incrementStreamCounter();
db.incrementStreamCounter(txn, transportId,
keySet.getKeySetId());
LOG.info("Returning");
return ctx;
}
LOG.info("Cannot find handshake mode keys");
return null;
} finally {
lock.unlock();
}
}
@DatabaseExecutor @DatabaseExecutor
@Wakeful @Wakeful
private void updateKeys(Transaction txn) throws DbException { private void updateKeys(Transaction txn) throws DbException {

View File

@@ -201,6 +201,9 @@ public class RestoreAccountImpl implements RestoreAccount {
transportPropertyManager transportPropertyManager
.mergeLocalProperties(propertiesEntry.getKey(), .mergeLocalProperties(propertiesEntry.getKey(),
propertiesEntry.getValue()); propertiesEntry.getValue());
// for (Map.Entry<String, String> entry : propertiesEntry.getValue().entrySet()) {
// LOG.info(String.format("%s : %s", entry.getKey(), entry.getValue()));
// }
} }
} }