mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
Encrypt and save crash reports, send them the next time TorPlugin start
Will currently fail at runtime; requires a public key and a server onion.
This commit is contained in:
@@ -17,6 +17,7 @@ import org.briarproject.messaging.MessagingModule;
|
||||
import org.briarproject.plugins.PluginsModule;
|
||||
import org.briarproject.properties.PropertiesModule;
|
||||
import org.briarproject.reliability.ReliabilityModule;
|
||||
import org.briarproject.reporting.ReportingModule;
|
||||
import org.briarproject.settings.SettingsModule;
|
||||
import org.briarproject.sync.SyncModule;
|
||||
import org.briarproject.system.SystemModule;
|
||||
@@ -42,6 +43,7 @@ import dagger.Module;
|
||||
PluginsModule.class,
|
||||
PropertiesModule.class,
|
||||
ReliabilityModule.class,
|
||||
ReportingModule.class,
|
||||
SettingsModule.class,
|
||||
SyncModule.class,
|
||||
SystemModule.class,
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.briarproject.util.ByteUtils;
|
||||
import org.briarproject.util.StringUtils;
|
||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.spongycastle.crypto.CipherParameters;
|
||||
import org.spongycastle.crypto.CryptoException;
|
||||
import org.spongycastle.crypto.Digest;
|
||||
import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||
@@ -28,6 +29,7 @@ import org.spongycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
@@ -438,6 +440,18 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public String encryptToKey(byte[] publicKey, byte[] plaintext) {
|
||||
MessageEncrypter encrypter = new MessageEncrypter(secureRandom);
|
||||
try {
|
||||
byte[] ciphertext = encrypter.encrypt(publicKey, plaintext);
|
||||
return AsciiArmour.wrap(ciphertext, 70);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (CryptoException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Key derivation function based on a pseudo-random function - see
|
||||
// NIST SP 800-108, section 5.1
|
||||
private byte[] macKdf(SecretKey key, byte[]... inputs) {
|
||||
|
||||
@@ -70,6 +70,14 @@ public class MessageEncrypter {
|
||||
return generator.generateKeyPair();
|
||||
}
|
||||
|
||||
byte[] encrypt(byte[] keyBytes, byte[] plaintext)
|
||||
throws IOException, CryptoException {
|
||||
InputStream in = new ByteArrayInputStream(keyBytes);
|
||||
ECPublicKeyParameters publicKey =
|
||||
(ECPublicKeyParameters) parser.readKey(in);
|
||||
return encrypt(publicKey, plaintext);
|
||||
}
|
||||
|
||||
byte[] encrypt(ECPublicKeyParameters pubKey, byte[] plaintext)
|
||||
throws CryptoException {
|
||||
IESEngine engine = getEngine();
|
||||
@@ -159,10 +167,7 @@ public class MessageEncrypter {
|
||||
}
|
||||
// Encrypt a decrypted message
|
||||
InputStream in = new FileInputStream(args[1]);
|
||||
byte[] b = StringUtils.fromHexString(readFully(in).trim());
|
||||
in = new ByteArrayInputStream(b);
|
||||
ECPublicKeyParameters publicKey =
|
||||
(ECPublicKeyParameters) encrypter.parser.readKey(in);
|
||||
byte[] publicKey = StringUtils.fromHexString(readFully(in).trim());
|
||||
String message = readFully(System.in);
|
||||
byte[] plaintext = message.getBytes(Charset.forName("UTF-8"));
|
||||
byte[] ciphertext = encrypter.encrypt(publicKey, plaintext);
|
||||
|
||||
124
briar-core/src/org/briarproject/reporting/DevReporterImpl.java
Normal file
124
briar-core/src/org/briarproject/reporting/DevReporterImpl.java
Normal file
@@ -0,0 +1,124 @@
|
||||
package org.briarproject.reporting;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import net.sourceforge.jsocks.socks.Socks5Proxy;
|
||||
import net.sourceforge.jsocks.socks.SocksException;
|
||||
import net.sourceforge.jsocks.socks.SocksSocket;
|
||||
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.reporting.DevConfig;
|
||||
import org.briarproject.api.reporting.DevReporter;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
class DevReporterImpl implements DevReporter {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(DevReporterImpl.class.getName());
|
||||
|
||||
private static final int TIMEOUT = 30 * 1000; // 30 seconds
|
||||
private static final String PREFIX = "briar-";
|
||||
private static final String REPORT_EXT = ".report";
|
||||
private static final String CRLF = "\r\n";
|
||||
|
||||
private CryptoComponent crypto;
|
||||
private DevConfig devConfig;
|
||||
|
||||
public DevReporterImpl(CryptoComponent crypto, DevConfig devConfig) {
|
||||
this.crypto = crypto;
|
||||
this.devConfig = devConfig;
|
||||
}
|
||||
|
||||
private Socket connectToDevelopers(int socksPort, int devPort)
|
||||
throws UnknownHostException, SocksException, SocketException {
|
||||
Socks5Proxy proxy = new Socks5Proxy("127.0.0.1", socksPort);
|
||||
proxy.resolveAddrLocally(false);
|
||||
Socket s =
|
||||
new SocksSocket(proxy, devConfig.getDevOnionAddress(), devPort);
|
||||
s.setSoTimeout(TIMEOUT);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encryptCrashReportToFile(File crashReportDir,
|
||||
String crashReport) throws FileNotFoundException {
|
||||
String encryptedReport =
|
||||
crypto.encryptToKey(devConfig.getDevPublicKey(),
|
||||
StringUtils.toUtf8(crashReport));
|
||||
|
||||
String filename = PREFIX + new Date().getTime() + REPORT_EXT;
|
||||
File report = new File(crashReportDir, filename);
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
writer = new PrintWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(report)));
|
||||
writer.append(encryptedReport);
|
||||
writer.flush();
|
||||
} finally {
|
||||
if (writer != null)
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCrashReports(File crashReportDir, int socksPort) {
|
||||
File[] reports = crashReportDir.listFiles();
|
||||
if (reports == null || reports.length == 0)
|
||||
return; // No crash reports to send
|
||||
|
||||
LOG.info("Connecting to developers' Hidden Service");
|
||||
Socket s;
|
||||
try {
|
||||
s = connectToDevelopers(socksPort,
|
||||
devConfig.getDevReportPort());
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, "Tor SOCKS proxy failed", e);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("Sending crash reports to developers");
|
||||
OutputStream output;
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
output = s.getOutputStream();
|
||||
writer = new PrintWriter(
|
||||
new OutputStreamWriter(output, "UTF-8"), true);
|
||||
for (File f : reports) {
|
||||
List<String> encryptedReport = Files.readLines(f,
|
||||
Charset.forName("UTF-8"));
|
||||
writer.append(f.getName()).append(CRLF);
|
||||
for (String line : encryptedReport) {
|
||||
writer.append(line).append(CRLF);
|
||||
}
|
||||
writer.append(CRLF);
|
||||
f.delete();
|
||||
}
|
||||
writer.flush();
|
||||
LOG.info("Crash reports sent");
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, "Connection to developers failed", e);
|
||||
} finally {
|
||||
if (writer != null)
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.reporting;
|
||||
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.reporting.DevConfig;
|
||||
import org.briarproject.api.reporting.DevReporter;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class ReportingModule {
|
||||
|
||||
@Provides
|
||||
DevReporter provideDevReportTask(CryptoComponent crypto,
|
||||
DevConfig devConfig) {
|
||||
return new DevReporterImpl(crypto, devConfig);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user