Skip to content

Commit

Permalink
Merge pull request #974 from alvasw/move_fingerprint_reads_to_dir_auth
Browse files Browse the repository at this point in the history
Tor: Move fingerprint reads to DirectoryAuthority
  • Loading branch information
alvasw authored Jul 7, 2023
2 parents 6b19427 + 2dc0e76 commit 9ae6f15
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

import bisq.tor.local_network.da.DirectoryAuthority;
import bisq.tor.local_network.da.keygen.process.DirectoryAuthorityKeyGenerator;
import bisq.tor.local_network.da.keygen.process.DirectoryIdentityKeyGenProcess;
import bisq.tor.local_network.da.keygen.RelayKeyGenProcess;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

Expand All @@ -37,19 +35,16 @@ public void generateKeys(@TempDir Path dataDir) throws IOException, InterruptedE
assertThat(keysPath.toFile().mkdirs())
.isTrue();

var torDAKeyGenProcess = new DirectoryIdentityKeyGenProcess(keysPath, "127.0.0.1:8080");

var directoryAuthority = DirectoryAuthority.builder()
.nickname("Nick")
.dataDir(dataDir)
.controlPort(1)
.orPort(2)
.dirPort(3)
.build();
RelayKeyGenProcess relayKeyGenProcess = new RelayKeyGenProcess(directoryAuthority);

var directoryAuthorityKeyGenerator = new DirectoryAuthorityKeyGenerator(torDAKeyGenProcess, relayKeyGenProcess);
directoryAuthorityKeyGenerator.generate("my_passphrase");
var directoryAuthorityKeyGenerator = new DirectoryAuthorityKeyGenerator();
directoryAuthorityKeyGenerator.generate(directoryAuthority, "my_passphrase");

File dataDirFile = dataDir.toFile();
assertThat(new File(dataDirFile, "fingerprint"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@

package bisq.tor.local_network.da;

import bisq.tor.local_network.KeyFingerprintReader;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.io.File;
import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

@Getter
public class DirectoryAuthority {
Expand All @@ -36,9 +40,11 @@ public class DirectoryAuthority {

private final String exitPolicy = "ExitPolicy accept *:*";

@Setter
private final Path keysPath;

@Getter(AccessLevel.NONE)
private Optional<String> identityKeyFingerprint = Optional.empty();
@Setter
@Getter(AccessLevel.NONE)
private Optional<String> relayKeyFingerprint = Optional.empty();

@Builder
Expand All @@ -48,9 +54,37 @@ public DirectoryAuthority(String nickname, Path dataDir, int controlPort, int or
this.controlPort = controlPort;
this.orPort = orPort;
this.dirPort = dirPort;
this.keysPath = dataDir.resolve("keys");
}

public Path getTorrcPath() {
return dataDir.resolve("torrc");
}

public Optional<String> getIdentityKeyFingerprint() {
if (identityKeyFingerprint.isPresent()) {
return identityKeyFingerprint;
}

File certificateFile = new File(keysPath.toFile(), "authority_certificate");
identityKeyFingerprint = readFingerprint(certificateFile, "fingerprint ");
return identityKeyFingerprint;
}

public Optional<String> getRelayKeyFingerprint() {
if (relayKeyFingerprint.isPresent()) {
return relayKeyFingerprint;
}

File fingerprintFile = new File(dataDir.toFile(), "fingerprint");
relayKeyFingerprint = readFingerprint(fingerprintFile, "Unnamed ");
return relayKeyFingerprint;
}

private Optional<String> readFingerprint(File fingerprintFile, String linePrefix) {
Predicate<String> lineMatcher = s -> s.startsWith(linePrefix);
UnaryOperator<String> dataExtractor = s -> s.split(" ")[1].strip();
var keyFingerprintReader = new KeyFingerprintReader(fingerprintFile, lineMatcher, dataExtractor);
return keyFingerprintReader.read();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
package bisq.tor.local_network.da;

import bisq.tor.local_network.da.keygen.process.DirectoryAuthorityKeyGenerator;
import bisq.tor.local_network.da.keygen.process.DirectoryIdentityKeyGenProcess;
import bisq.tor.local_network.da.keygen.RelayKeyGenProcess;
import lombok.Getter;

import java.io.File;
Expand All @@ -44,19 +42,8 @@ public void createDirectoryAuthority(DirectoryAuthority directoryAuthority,
throw new IllegalStateException("Couldn't create keys folder in data directory for directory authority.");
}

var relayKeyGenProcess = new RelayKeyGenProcess(directoryAuthority);
String firstDirectoryAuthorityAddress = "127.0.0.1:" + directoryAuthority.getDirPort();
var torDAKeyGenProcess = new DirectoryIdentityKeyGenProcess(keysPath, firstDirectoryAuthorityAddress);

var directoryAuthorityKeyGenerator = new DirectoryAuthorityKeyGenerator(torDAKeyGenProcess, relayKeyGenProcess);
directoryAuthorityKeyGenerator.generate(passphrase);

directoryAuthority.setIdentityKeyFingerprint(
directoryAuthorityKeyGenerator.getIdentityKeyFingerprint()
);
directoryAuthority.setRelayKeyFingerprint(
directoryAuthorityKeyGenerator.getRelayKeyFingerprint()
);
var directoryAuthorityKeyGenerator = new DirectoryAuthorityKeyGenerator();
directoryAuthorityKeyGenerator.generate(directoryAuthority, passphrase);

allDirectoryAuthorities.add(directoryAuthority);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@

package bisq.tor.local_network.da.keygen;

import bisq.tor.local_network.KeyFingerprintReader;
import bisq.tor.local_network.da.DirectoryAuthority;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

public class RelayKeyGenProcess {
private final DirectoryAuthority directoryAuthority;
Expand All @@ -33,7 +29,7 @@ public RelayKeyGenProcess(DirectoryAuthority directoryAuthority) {
this.directoryAuthority = directoryAuthority;
}

public String generateKeys(String identityKeyFingerprint) throws IOException, InterruptedException {
public void generateKeys(String identityKeyFingerprint) throws IOException, InterruptedException {
var processBuilder = new ProcessBuilder(
"tor", "--list-fingerprint",
"--DataDirectory", directoryAuthority.getDataDir().toAbsolutePath().toString(),
Expand All @@ -52,18 +48,5 @@ public String generateKeys(String identityKeyFingerprint) throws IOException, In

Process process = processBuilder.start();
process.waitFor(45, TimeUnit.SECONDS);

return readKeyFingerprint();
}

private String readKeyFingerprint() {
File dataDirFile = directoryAuthority.getDataDir().toFile();
File fingerprintFile = new File(dataDirFile, "fingerprint");

Predicate<String> lineMatcher = s -> s.startsWith("Unnamed ");
UnaryOperator<String> dataExtractor = s -> s.split(" ")[1].strip();

var keyFingerprintReader = new KeyFingerprintReader(fingerprintFile, lineMatcher, dataExtractor);
return keyFingerprintReader.read().orElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,24 @@

package bisq.tor.local_network.da.keygen.process;

import bisq.tor.local_network.da.DirectoryAuthority;
import bisq.tor.local_network.da.keygen.RelayKeyGenProcess;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Optional;

@Slf4j
public class DirectoryAuthorityKeyGenerator {
private final DirectoryIdentityKeyGenProcess identityKeyGenProcess;
private final RelayKeyGenProcess relayKeyGenProcess;
public void generate(DirectoryAuthority directoryAuthority, String passphrase) throws IOException, InterruptedException {
var identityKeyGenProcess = new DirectoryIdentityKeyGenProcess(
directoryAuthority.getKeysPath(),
"127.0.0.1:" + directoryAuthority.getDirPort()
);
identityKeyGenProcess.generateKeys(passphrase);

@Getter
private Optional<String> identityKeyFingerprint = Optional.empty();
@Getter
private Optional<String> relayKeyFingerprint = Optional.empty();
String identityKeyFingerprint = directoryAuthority.getIdentityKeyFingerprint().orElseThrow();

public DirectoryAuthorityKeyGenerator(DirectoryIdentityKeyGenProcess identityKeyGenProcess,
RelayKeyGenProcess relayKeyGenProcess) {
this.identityKeyGenProcess = identityKeyGenProcess;
this.relayKeyGenProcess = relayKeyGenProcess;
}

public void generate(String passphrase) throws IOException, InterruptedException {
String identityKeyFingerprint = identityKeyGenProcess.generateKeys(passphrase);
this.identityKeyFingerprint = Optional.of(identityKeyFingerprint);

String relayKeyFingerprint = relayKeyGenProcess.generateKeys(identityKeyFingerprint);
this.relayKeyFingerprint = Optional.of(relayKeyFingerprint);
var relayKeyGenProcess = new RelayKeyGenProcess(directoryAuthority);
relayKeyGenProcess.generateKeys(identityKeyFingerprint);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,14 @@
package bisq.tor.local_network.da.keygen.process;

import bisq.tor.local_network.InputStreamWaiter;
import bisq.tor.local_network.KeyFingerprintReader;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

@Slf4j
public class DirectoryIdentityKeyGenProcess {
Expand All @@ -44,7 +40,7 @@ public DirectoryIdentityKeyGenProcess(Path torKeyDirPath, String directoryAddres
this.directoryAddress = directoryAddress;
}

public String generateKeys(String passphrase) throws IOException, InterruptedException {
public void generateKeys(String passphrase) throws IOException, InterruptedException {
Process process = createAndStartKeygenProcess();
InputStream inputStream = process.getInputStream();
OutputStream outputStream = process.getOutputStream();
Expand All @@ -57,12 +53,7 @@ public String generateKeys(String passphrase) throws IOException, InterruptedExc
inputStreamWaiter.waitForString(PEM_VERIFY_PASSPHRASE_PROMPT);
enterPassphrase(outputStream, passphrase);

return getKeyFingerprint(process);
}

public String getKeyFingerprint(Process process) throws InterruptedException {
process.waitFor(1, TimeUnit.MINUTES);
return readKeyFingerprint();
}

private Process createAndStartKeygenProcess() throws IOException {
Expand All @@ -78,14 +69,4 @@ private void enterPassphrase(OutputStream outputStream, String passphrase) throw
outputStream.write(passphraseWithNewLine.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
}

private String readKeyFingerprint() {
File certificateFile = new File(torKeyDirPath.toFile(), "authority_certificate");

Predicate<String> lineMatcher = s -> s.startsWith("fingerprint ");
UnaryOperator<String> dataExtractor = s -> s.split(" ")[1].strip();

var keyFingerprintReader = new KeyFingerprintReader(certificateFile, lineMatcher, dataExtractor);
return keyFingerprintReader.read().orElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,38 +29,54 @@
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

public class DirectoryAuthorityTorrcGeneratorTests {
@Test
void basicTest(@TempDir Path tempDir) throws IOException {
Path daAPath = tempDir.resolve("DA_A");
assertThat(daAPath.toFile().mkdir()).isTrue();

DirectoryAuthority firstDirAuth = DirectoryAuthority.builder()
.nickname("A")
.dataDir(daAPath)
DirectoryAuthority firstDirAuth = spy(
DirectoryAuthority.builder()
.nickname("A")
.dataDir(daAPath)

.controlPort(1)
.orPort(2)
.dirPort(3)
.controlPort(1)
.orPort(2)
.dirPort(3)

.build();
.build()
);

firstDirAuth.setIdentityKeyFingerprint(Optional.of("AAAA_fp"));
firstDirAuth.setRelayKeyFingerprint(Optional.of("AAAA_v3"));
doReturn(Optional.of("AAAA_fp"))
.when(firstDirAuth)
.getIdentityKeyFingerprint();

DirectoryAuthority secondDirAuth = DirectoryAuthority.builder()
.nickname("B")
.dataDir(tempDir.resolve("DA_B"))
doReturn(Optional.of("AAAA_v3"))
.when(firstDirAuth)
.getRelayKeyFingerprint();

.controlPort(1)
.orPort(2)
.dirPort(3)
DirectoryAuthority secondDirAuth = spy(
DirectoryAuthority.builder()
.nickname("B")
.dataDir(tempDir.resolve("DA_B"))

.build();
.controlPort(1)
.orPort(2)
.dirPort(3)

secondDirAuth.setIdentityKeyFingerprint(Optional.of("BBBB_fp"));
secondDirAuth.setRelayKeyFingerprint(Optional.of("BBBB_v3"));
.build()
);

doReturn(Optional.of("BBBB_fp"))
.when(secondDirAuth)
.getIdentityKeyFingerprint();

doReturn(Optional.of("BBBB_v3"))
.when(secondDirAuth)
.getRelayKeyFingerprint();

var torDaTorrcGenerator = new DirectoryAuthorityTorrcGenerator(firstDirAuth);
var allDirAuthorities = Set.of(firstDirAuth, secondDirAuth);
Expand Down
Loading

0 comments on commit 9ae6f15

Please sign in to comment.