Compare commits

...

21 Commits

Author SHA1 Message Date
Torsten Grote
fa79a31911 Define common library version centrally in top-level build.gradle file
This should make it easier to upgrade libraries in the future and provide
an overview over which versions we are using as well as keep them
consistent throughout the project.
2017-12-01 16:32:02 -02:00
akwizgran
8171dd8bc9 Merge branch 'more-lambdas' into 'master'
Replace a few runnables with lambdas

See merge request !638
2017-12-01 17:42:58 +00:00
Torsten Grote
4b88f0d9f1 Merge branch 'package-name-briar-android' into 'master'
Change package name, bump expiry date

See merge request !637
2017-12-01 16:36:47 +00:00
akwizgran
116419f505 Don't show expiry warning for release builds. 2017-12-01 16:18:47 +00:00
akwizgran
87b2624aa8 Set IS_BETA_BUILD to false. 2017-12-01 16:16:37 +00:00
akwizgran
71fe6f3148 Bump expiry date to 31 December 2018. 2017-12-01 16:11:06 +00:00
akwizgran
21df6cb809 Change package name, version number for release branch. 2017-12-01 15:59:04 +00:00
akwizgran
1f0c385a5c Merge branch '1124-notification-channel-crash' into 'master'
Use NotificationChannel for foreground service to avoid crash on Android 8.1

Closes #1124

See merge request !634
2017-12-01 15:53:05 +00:00
Torsten Grote
986ea05fb2 Use NotificationChannel for foreground service to avoid crash on Android 8.1
This also seems to address #1075 at least on an emulator
2017-12-01 13:44:51 -02:00
akwizgran
030b52261d Replace a few runnables with lambdas. 2017-12-01 14:01:32 +00:00
akwizgran
a50e13c2e3 Merge branch 'transport-property-manager-cleanup' into 'master'
Simplify management of old transport property updates

See merge request !629
2017-11-30 17:46:15 +00:00
akwizgran
c8326103b4 Merge branch 'git-rev-parse-workaround' 2017-11-30 17:39:33 +00:00
Torsten Grote
ddea031cbf Merge branch '1110-signature-labels' into 'master'
Don't use ClientId.toString() for signature labels

Closes #1110

See merge request !631
2017-11-30 17:03:07 +00:00
akwizgran
f0d8532f71 Specify 7 characters for Git revision. 2017-11-30 16:55:41 +00:00
akwizgran
4883d157dc Simplify management of old transport property updates. 2017-11-30 16:43:33 +00:00
akwizgran
a1bec1e927 Merge branch 'ed25519' into 'master'
Add support for Ed25519 signatures

See merge request !627
2017-11-30 16:22:04 +00:00
akwizgran
37d4d79c64 Don't rethrow SignatureException as RuntimeException. 2017-11-29 17:29:32 +00:00
akwizgran
05bc3f6a71 Don't use ClientId.toString() for signature labels. 2017-11-29 16:57:00 +00:00
akwizgran
8b3960781a Fix a typo. 2017-11-23 17:34:40 +00:00
akwizgran
f3de4f53c5 Add ProGuard rule to keep EdDSA classes. 2017-11-23 16:18:30 +00:00
akwizgran
166fc2948c Add support for Ed25519 signatures. 2017-11-23 16:17:41 +00:00
33 changed files with 497 additions and 283 deletions

View File

@@ -12,8 +12,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 1612 versionCode 1700
versionName "0.16.12" versionName "0.17.0"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
} }
@@ -27,7 +27,7 @@ dependencies {
implementation project(path: ':bramble-core', configuration: 'default') implementation project(path: ':bramble-core', configuration: 'default')
implementation fileTree(dir: 'libs', include: '*.jar') implementation fileTree(dir: 'libs', include: '*.jar')
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2' annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
compileOnly 'javax.annotation:jsr250-api:1.0' compileOnly 'javax.annotation:jsr250-api:1.0'
} }
@@ -43,6 +43,7 @@ dependencyVerification {
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728', 'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f', 'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb', 'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128-runtime.jar:e357a0f1d573c2f702a273992b1b6cb661734f66311854efb3778a888515c5b5', 'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128-runtime.jar:e357a0f1d573c2f702a273992b1b6cb661734f66311854efb3778a888515c5b5',
'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128.jar:47b4bec6df11a1118da3953da8b9fa1e7079d6fec857faa1a3cf912e53a6fd4e', 'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128.jar:47b4bec6df11a1118da3953da8b9fa1e7079d6fec857faa1a3cf912e53a6fd4e',
@@ -54,8 +55,6 @@ dependencyVerification {
} }
ext.torBinaryDir = 'src/main/res/raw' ext.torBinaryDir = 'src/main/res/raw'
ext.torVersion = '0.2.9.12'
ext.geoipVersion = '2017-09-06'
ext.torDownloadUrl = 'https://briarproject.org/build/' ext.torDownloadUrl = 'https://briarproject.org/build/'
def torBinaries = [ def torBinaries = [

View File

@@ -8,6 +8,8 @@
-dontwarn dagger.** -dontwarn dagger.**
-dontnote dagger.** -dontnote dagger.**
-keep class net.i2p.crypto.eddsa.** { *; }
-dontwarn sun.misc.Unsafe -dontwarn sun.misc.Unsafe
-dontnote com.google.common.** -dontnote com.google.common.**

View File

@@ -5,15 +5,15 @@ targetCompatibility = 1.8
apply plugin: 'witness' apply plugin: 'witness'
dependencies { dependencies {
implementation "com.google.dagger:dagger:2.0.2" implementation "com.google.dagger:dagger:$daggerVersion"
implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation 'com.google.code.findbugs:jsr305:3.0.2'
testImplementation 'junit:junit:4.12' testImplementation "junit:junit:$junitVersion"
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:$jmockVersion"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:$jmockVersion"
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:$jmockVersion"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
} }
dependencyVerification { dependencyVerification {

View File

@@ -20,6 +20,10 @@ public interface CryptoComponent {
KeyParser getSignatureKeyParser(); KeyParser getSignatureKeyParser();
KeyPair generateEdKeyPair();
KeyParser getEdKeyParser();
KeyParser getMessageKeyParser(); KeyParser getMessageKeyParser();
/** /**
@@ -61,7 +65,6 @@ public interface CryptoComponent {
* @param ourKeyPair our ephemeral keypair * @param ourKeyPair our ephemeral keypair
* @param alice true if ourKeyPair belongs to Alice * @param alice true if ourKeyPair belongs to Alice
* @return the shared secret * @return the shared secret
* @throws GeneralSecurityException
*/ */
SecretKey deriveSharedSecret(byte[] theirPublicKey, KeyPair ourKeyPair, SecretKey deriveSharedSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
boolean alice) throws GeneralSecurityException; boolean alice) throws GeneralSecurityException;
@@ -106,7 +109,6 @@ public interface CryptoComponent {
* @param ourKeyPair our ephemeral keypair * @param ourKeyPair our ephemeral keypair
* @param alice true if ourKeyPair belongs to Alice * @param alice true if ourKeyPair belongs to Alice
* @return the shared secret * @return the shared secret
* @throws GeneralSecurityException
*/ */
SecretKey deriveMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair, SecretKey deriveMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
boolean alice) throws GeneralSecurityException; boolean alice) throws GeneralSecurityException;
@@ -130,7 +132,7 @@ public interface CryptoComponent {
long streamNumber); long streamNumber);
/** /**
* Signs the given byte[] with the given PrivateKey. * Signs the given byte[] with the given ECDSA private key.
* *
* @param label A label specific to this signature * @param label A label specific to this signature
* to ensure that the signature cannot be repurposed * to ensure that the signature cannot be repurposed
@@ -139,8 +141,17 @@ public interface CryptoComponent {
throws GeneralSecurityException; throws GeneralSecurityException;
/** /**
* Verifies that the given signature is valid for the signedData * Signs the given byte[] with the given Ed25519 private key.
* and the given publicKey. *
* @param label A label specific to this signature
* to ensure that the signature cannot be repurposed
*/
byte[] signEd(String label, byte[] toSign, byte[] privateKey)
throws GeneralSecurityException;
/**
* Verifies that the given signature is valid for the signed data
* and the given ECDSA public key.
* *
* @param label A label that was specific to this signature * @param label A label that was specific to this signature
* to ensure that the signature cannot be repurposed * to ensure that the signature cannot be repurposed
@@ -149,6 +160,17 @@ public interface CryptoComponent {
boolean verify(String label, byte[] signedData, byte[] publicKey, boolean verify(String label, byte[] signedData, byte[] publicKey,
byte[] signature) throws GeneralSecurityException; byte[] signature) throws GeneralSecurityException;
/**
* Verifies that the given signature is valid for the signed data
* and the given Ed25519 public key.
*
* @param label A label that was specific to this signature
* to ensure that the signature cannot be repurposed
* @return true if the signature was valid, false otherwise.
*/
boolean verifyEd(String label, byte[] signedData, byte[] publicKey,
byte[] signature) throws GeneralSecurityException;
/** /**
* Returns the hash of the given inputs. The inputs are unambiguously * Returns the hash of the given inputs. The inputs are unambiguously
* combined by prefixing each input with its length. * combined by prefixing each input with its length.

View File

@@ -36,4 +36,8 @@ public class ClientId implements Comparable<ClientId> {
return id.hashCode(); return id.hashCode();
} }
@Override
public String toString() {
return id;
}
} }

View File

@@ -11,18 +11,19 @@ dependencies {
implementation 'com.madgag.spongycastle:core:1.58.0.0' implementation 'com.madgag.spongycastle:core:1.58.0.0'
implementation 'com.h2database:h2:1.4.192' // This is the last version that supports Java 1.6 implementation 'com.h2database:h2:1.4.192' // This is the last version that supports Java 1.6
implementation 'org.bitlet:weupnp:0.1.4' implementation 'org.bitlet:weupnp:0.1.4'
implementation 'net.i2p.crypto:eddsa:0.2.0'
apt 'com.google.dagger:dagger-compiler:2.0.2' apt "com.google.dagger:dagger-compiler:$daggerVersion"
testImplementation project(path: ':bramble-api', configuration: 'testOutput') testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation 'junit:junit:4.12' testImplementation "junit:junit:$junitVersion"
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:$jmockVersion"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:$jmockVersion"
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:$jmockVersion"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
testApt 'com.google.dagger:dagger-compiler:2.0.2' testApt "com.google.dagger:dagger-compiler:$daggerVersion"
} }
dependencyVerification { dependencyVerification {
@@ -37,6 +38,7 @@ dependencyVerification {
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728', 'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a', 'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d', 'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8', 'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8', 'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',

View File

@@ -1,5 +1,9 @@
package org.briarproject.bramble.crypto; package org.briarproject.bramble.crypto;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.KeyPairGenerator;
import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.KeyParser; import org.briarproject.bramble.api.crypto.KeyParser;
@@ -56,6 +60,7 @@ class CryptoComponentImpl implements CryptoComponent {
private static final int AGREEMENT_KEY_PAIR_BITS = 256; private static final int AGREEMENT_KEY_PAIR_BITS = 256;
private static final int SIGNATURE_KEY_PAIR_BITS = 256; private static final int SIGNATURE_KEY_PAIR_BITS = 256;
private static final int ED_KEY_PAIR_BITS = 256;
private static final int STORAGE_IV_BYTES = 24; // 196 bits private static final int STORAGE_IV_BYTES = 24; // 196 bits
private static final int PBKDF_SALT_BYTES = 32; // 256 bits private static final int PBKDF_SALT_BYTES = 32; // 256 bits
private static final int PBKDF_TARGET_MILLIS = 500; private static final int PBKDF_TARGET_MILLIS = 500;
@@ -99,6 +104,8 @@ class CryptoComponentImpl implements CryptoComponent {
private final ECKeyPairGenerator signatureKeyPairGenerator; private final ECKeyPairGenerator signatureKeyPairGenerator;
private final KeyParser agreementKeyParser, signatureKeyParser; private final KeyParser agreementKeyParser, signatureKeyParser;
private final MessageEncrypter messageEncrypter; private final MessageEncrypter messageEncrypter;
private final KeyPairGenerator edKeyPairGenerator;
private final KeyParser edKeyParser;
@Inject @Inject
CryptoComponentImpl(SecureRandomProvider secureRandomProvider) { CryptoComponentImpl(SecureRandomProvider secureRandomProvider) {
@@ -132,6 +139,9 @@ class CryptoComponentImpl implements CryptoComponent {
signatureKeyParser = new Sec1KeyParser(PARAMETERS, signatureKeyParser = new Sec1KeyParser(PARAMETERS,
SIGNATURE_KEY_PAIR_BITS); SIGNATURE_KEY_PAIR_BITS);
messageEncrypter = new MessageEncrypter(secureRandom); messageEncrypter = new MessageEncrypter(secureRandom);
edKeyPairGenerator = new KeyPairGenerator();
edKeyPairGenerator.initialize(ED_KEY_PAIR_BITS, secureRandom);
edKeyParser = new EdKeyParser();
} }
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html // Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
@@ -190,6 +200,21 @@ class CryptoComponentImpl implements CryptoComponent {
return secret; return secret;
} }
@Override
public KeyPair generateEdKeyPair() {
java.security.KeyPair keyPair = edKeyPairGenerator.generateKeyPair();
EdDSAPublicKey edPublicKey = (EdDSAPublicKey) keyPair.getPublic();
PublicKey publicKey = new EdPublicKey(edPublicKey.getAbyte());
EdDSAPrivateKey edPrivateKey = (EdDSAPrivateKey) keyPair.getPrivate();
PrivateKey privateKey = new EdPrivateKey(edPrivateKey.getSeed());
return new KeyPair(publicKey, privateKey);
}
@Override
public KeyParser getEdKeyParser() {
return edKeyParser;
}
@Override @Override
public KeyPair generateAgreementKeyPair() { public KeyPair generateAgreementKeyPair() {
AsymmetricCipherKeyPair keyPair = AsymmetricCipherKeyPair keyPair =
@@ -416,19 +441,41 @@ class CryptoComponentImpl implements CryptoComponent {
@Override @Override
public byte[] sign(String label, byte[] toSign, byte[] privateKey) public byte[] sign(String label, byte[] toSign, byte[] privateKey)
throws GeneralSecurityException { throws GeneralSecurityException {
Signature signature = new SignatureImpl(secureRandom); return sign(new SignatureImpl(secureRandom), signatureKeyParser, label,
KeyParser keyParser = getSignatureKeyParser(); toSign, privateKey);
}
@Override
public byte[] signEd(String label, byte[] toSign, byte[] privateKey)
throws GeneralSecurityException {
return sign(new EdSignature(), edKeyParser, label, toSign, privateKey);
}
private byte[] sign(Signature sig, KeyParser keyParser, String label,
byte[] toSign, byte[] privateKey) throws GeneralSecurityException {
PrivateKey key = keyParser.parsePrivateKey(privateKey); PrivateKey key = keyParser.parsePrivateKey(privateKey);
signature.initSign(key); sig.initSign(key);
updateSignature(signature, label, toSign); updateSignature(sig, label, toSign);
return signature.sign(); return sig.sign();
} }
@Override @Override
public boolean verify(String label, byte[] signedData, byte[] publicKey, public boolean verify(String label, byte[] signedData, byte[] publicKey,
byte[] signature) throws GeneralSecurityException { byte[] signature) throws GeneralSecurityException {
Signature sig = new SignatureImpl(secureRandom); return verify(new SignatureImpl(secureRandom), signatureKeyParser,
KeyParser keyParser = getSignatureKeyParser(); label, signedData, publicKey, signature);
}
@Override
public boolean verifyEd(String label, byte[] signedData, byte[] publicKey,
byte[] signature) throws GeneralSecurityException {
return verify(new EdSignature(), edKeyParser, label, signedData,
publicKey, signature);
}
private boolean verify(Signature sig, KeyParser keyParser, String label,
byte[] signedData, byte[] publicKey, byte[] signature)
throws GeneralSecurityException {
PublicKey key = keyParser.parsePublicKey(publicKey); PublicKey key = keyParser.parsePublicKey(publicKey);
sig.initVerify(key); sig.initVerify(key);
updateSignature(sig, label, signedData); updateSignature(sig, label, signedData);
@@ -436,7 +483,7 @@ class CryptoComponentImpl implements CryptoComponent {
} }
private void updateSignature(Signature signature, String label, private void updateSignature(Signature signature, String label,
byte[] toSign) { byte[] toSign) throws GeneralSecurityException {
byte[] labelBytes = StringUtils.toUtf8(label); byte[] labelBytes = StringUtils.toUtf8(label);
byte[] length = new byte[INT_32_BYTES]; byte[] length = new byte[INT_32_BYTES];
ByteUtils.writeUint32(labelBytes.length, length, 0); ByteUtils.writeUint32(labelBytes.length, length, 0);

View File

@@ -0,0 +1,26 @@
package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.KeyParser;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.security.GeneralSecurityException;
@NotNullByDefault
class EdKeyParser implements KeyParser {
@Override
public PublicKey parsePublicKey(byte[] encodedKey)
throws GeneralSecurityException {
if (encodedKey.length != 32) throw new GeneralSecurityException();
return new EdPublicKey(encodedKey);
}
@Override
public PrivateKey parsePrivateKey(byte[] encodedKey)
throws GeneralSecurityException {
if (encodedKey.length != 32) throw new GeneralSecurityException();
return new EdPrivateKey(encodedKey);
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
class EdPrivateKey extends Bytes implements PrivateKey {
EdPrivateKey(byte[] bytes) {
super(bytes);
}
@Override
public byte[] getEncoded() {
return getBytes();
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
class EdPublicKey extends Bytes implements PublicKey {
EdPublicKey(byte[] bytes) {
super(bytes);
}
@Override
public byte[] getEncoded() {
return getBytes();
}
}

View File

@@ -0,0 +1,83 @@
package org.briarproject.bramble.crypto;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.EdDSASecurityProvider;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import static net.i2p.crypto.eddsa.EdDSAEngine.SIGNATURE_ALGORITHM;
@NotNullByDefault
class EdSignature implements Signature {
private static final Provider PROVIDER = new EdDSASecurityProvider();
private static final EdDSANamedCurveSpec CURVE_SPEC =
EdDSANamedCurveTable.getByName("Ed25519");
private final java.security.Signature signature;
EdSignature() {
try {
signature = java.security.Signature
.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}
@Override
public void initSign(PrivateKey k) throws GeneralSecurityException {
if (!(k instanceof EdPrivateKey))
throw new IllegalArgumentException();
EdDSAPrivateKey privateKey = new EdDSAPrivateKey(
new EdDSAPrivateKeySpec(k.getEncoded(), CURVE_SPEC));
signature.initSign(privateKey);
}
@Override
public void initVerify(PublicKey k) throws GeneralSecurityException {
if (!(k instanceof EdPublicKey))
throw new IllegalArgumentException();
EdDSAPublicKey publicKey = new EdDSAPublicKey(
new EdDSAPublicKeySpec(k.getEncoded(), CURVE_SPEC));
signature.initVerify(publicKey);
}
@Override
public void update(byte b) throws GeneralSecurityException {
signature.update(b);
}
@Override
public void update(byte[] b) throws GeneralSecurityException {
signature.update(b);
}
@Override
public void update(byte[] b, int off, int len)
throws GeneralSecurityException {
signature.update(b, off, len);
}
@Override
public byte[] sign() throws GeneralSecurityException {
return signature.sign();
}
@Override
public boolean verify(byte[] sig) throws GeneralSecurityException {
return signature.verify(sig);
}
}

View File

@@ -22,25 +22,25 @@ interface Signature {
/** /**
* @see {@link java.security.Signature#update(byte)} * @see {@link java.security.Signature#update(byte)}
*/ */
void update(byte b); void update(byte b) throws GeneralSecurityException;
/** /**
* @see {@link java.security.Signature#update(byte[])} * @see {@link java.security.Signature#update(byte[])}
*/ */
void update(byte[] b); void update(byte[] b) throws GeneralSecurityException;
/** /**
* @see {@link java.security.Signature#update(byte[], int, int)} * @see {@link java.security.Signature#update(byte[], int, int)}
*/ */
void update(byte[] b, int off, int len); void update(byte[] b, int off, int len) throws GeneralSecurityException;
/** /**
* @see {@link java.security.Signature#sign()} * @see {@link java.security.Signature#sign()}
*/ */
byte[] sign(); byte[] sign() throws GeneralSecurityException;
/** /**
* @see {@link java.security.Signature#verify(byte[])} * @see {@link java.security.Signature#verify(byte[])}
*/ */
boolean verify(byte[] signature); boolean verify(byte[] signature) throws GeneralSecurityException;
} }

View File

@@ -129,8 +129,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
public Map<TransportId, TransportProperties> getLocalProperties() public Map<TransportId, TransportProperties> getLocalProperties()
throws DbException { throws DbException {
Map<TransportId, TransportProperties> local; Map<TransportId, TransportProperties> local;
// TODO: Transaction can be read-only when code is simplified Transaction txn = db.startTransaction(true);
Transaction txn = db.startTransaction(false);
try { try {
local = getLocalProperties(txn); local = getLocalProperties(txn);
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -165,8 +164,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
throws DbException { throws DbException {
try { try {
TransportProperties p = null; TransportProperties p = null;
// TODO: Transaction can be read-only when code is simplified Transaction txn = db.startTransaction(true);
Transaction txn = db.startTransaction(false);
try { try {
// Find the latest local update // Find the latest local update
LatestUpdate latest = findLatest(txn, localGroup.getId(), t, LatestUpdate latest = findLatest(txn, localGroup.getId(), t,
@@ -192,8 +190,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
public Map<ContactId, TransportProperties> getRemoteProperties( public Map<ContactId, TransportProperties> getRemoteProperties(
TransportId t) throws DbException { TransportId t) throws DbException {
Map<ContactId, TransportProperties> remote = new HashMap<>(); Map<ContactId, TransportProperties> remote = new HashMap<>();
// TODO: Transaction can be read-only when code is simplified Transaction txn = db.startTransaction(true);
Transaction txn = db.startTransaction(false);
try { try {
for (Contact c : db.getContacts(txn)) for (Contact c : db.getContacts(txn))
remote.put(c.getId(), getRemoteProperties(txn, c, t)); remote.put(c.getId(), getRemoteProperties(txn, c, t));
@@ -227,8 +224,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
public TransportProperties getRemoteProperties(ContactId c, TransportId t) public TransportProperties getRemoteProperties(ContactId c, TransportId t)
throws DbException { throws DbException {
TransportProperties p; TransportProperties p;
// TODO: Transaction can be read-only when code is simplified Transaction txn = db.startTransaction(true);
Transaction txn = db.startTransaction(false);
try { try {
p = getRemoteProperties(txn, db.getContact(txn, c), t); p = getRemoteProperties(txn, db.getContact(txn, c), t);
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -318,7 +314,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
private Map<TransportId, LatestUpdate> findLatestLocal(Transaction txn) private Map<TransportId, LatestUpdate> findLatestLocal(Transaction txn)
throws DbException, FormatException { throws DbException, FormatException {
// TODO: This can be simplified before 1.0
Map<TransportId, LatestUpdate> latestUpdates = new HashMap<>(); Map<TransportId, LatestUpdate> latestUpdates = new HashMap<>();
Map<MessageId, BdfDictionary> metadata = clientHelper Map<MessageId, BdfDictionary> metadata = clientHelper
.getMessageMetadataAsDictionary(txn, localGroup.getId()); .getMessageMetadataAsDictionary(txn, localGroup.getId());
@@ -326,17 +321,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
BdfDictionary meta = e.getValue(); BdfDictionary meta = e.getValue();
TransportId t = new TransportId(meta.getString("transportId")); TransportId t = new TransportId(meta.getString("transportId"));
long version = meta.getLong("version"); long version = meta.getLong("version");
LatestUpdate latest = latestUpdates.get(t); latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
if (latest == null) {
latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
} else if (version > latest.version) {
// This update is newer - delete the previous one
db.removeMessage(txn, latest.messageId);
latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
} else {
// We've already found a newer update - delete this one
db.removeMessage(txn, e.getKey());
}
} }
return latestUpdates; return latestUpdates;
} }
@@ -344,38 +329,16 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Nullable @Nullable
private LatestUpdate findLatest(Transaction txn, GroupId g, TransportId t, private LatestUpdate findLatest(Transaction txn, GroupId g, TransportId t,
boolean local) throws DbException, FormatException { boolean local) throws DbException, FormatException {
// TODO: This can be simplified before 1.0
LatestUpdate latest = null;
Map<MessageId, BdfDictionary> metadata = Map<MessageId, BdfDictionary> metadata =
clientHelper.getMessageMetadataAsDictionary(txn, g); clientHelper.getMessageMetadataAsDictionary(txn, g);
for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) { for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) {
BdfDictionary meta = e.getValue(); BdfDictionary meta = e.getValue();
if (meta.getString("transportId").equals(t.getString()) if (meta.getString("transportId").equals(t.getString())
&& meta.getBoolean("local") == local) { && meta.getBoolean("local") == local) {
long version = meta.getLong("version"); return new LatestUpdate(e.getKey(), meta.getLong("version"));
if (latest == null) {
latest = new LatestUpdate(e.getKey(), version);
} else if (version > latest.version) {
// This update is newer - delete the previous one
if (local) {
db.removeMessage(txn, latest.messageId);
} else {
db.deleteMessage(txn, latest.messageId);
db.deleteMessageMetadata(txn, latest.messageId);
}
latest = new LatestUpdate(e.getKey(), version);
} else {
// We've already found a newer update - delete this one
if (local) {
db.removeMessage(txn, e.getKey());
} else {
db.deleteMessage(txn, e.getKey());
db.deleteMessageMetadata(txn, e.getKey());
}
}
} }
} }
return latest; return null;
} }
private TransportProperties parseProperties(BdfList message) private TransportProperties parseProperties(BdfList message)

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.KeyPair;
import java.security.GeneralSecurityException;
public class EcdsaSignatureTest extends SignatureTest {
@Override
protected KeyPair generateKeyPair() {
return crypto.generateSignatureKeyPair();
}
@Override
protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
throws GeneralSecurityException {
return crypto.sign(label, toSign, privateKey);
}
@Override
protected boolean verify(String label, byte[] signedData, byte[] publicKey,
byte[] signature) throws GeneralSecurityException {
return crypto.verify(label, signedData, publicKey, signature);
}
}

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.KeyPair;
import java.security.GeneralSecurityException;
public class EdSignatureTest extends SignatureTest {
@Override
protected KeyPair generateKeyPair() {
return crypto.generateEdKeyPair();
}
@Override
protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
throws GeneralSecurityException {
return crypto.signEd(label, toSign, privateKey);
}
@Override
protected boolean verify(String label, byte[] signedData, byte[] publicKey,
byte[] signature) throws GeneralSecurityException {
return crypto.verifyEd(label, signedData, publicKey, signature);
}
}

View File

@@ -8,23 +8,32 @@ import org.briarproject.bramble.test.TestUtils;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import org.junit.Test; import org.junit.Test;
import java.security.GeneralSecurityException;
import java.util.Arrays; import java.util.Arrays;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class SignatureTest extends BrambleTestCase { public abstract class SignatureTest extends BrambleTestCase {
private final CryptoComponent crypto; protected final CryptoComponent crypto;
private final byte[] publicKey, privateKey; private final byte[] publicKey, privateKey;
private final String label = StringUtils.getRandomString(42); private final String label = StringUtils.getRandomString(42);
private final byte[] inputBytes = TestUtils.getRandomBytes(123); private final byte[] inputBytes = TestUtils.getRandomBytes(123);
public SignatureTest() { protected abstract KeyPair generateKeyPair();
protected abstract byte[] sign(String label, byte[] toSign,
byte[] privateKey) throws GeneralSecurityException;
protected abstract boolean verify(String label, byte[] signedData,
byte[] publicKey, byte[] signature) throws GeneralSecurityException;
SignatureTest() {
crypto = new CryptoComponentImpl(new TestSecureRandomProvider()); crypto = new CryptoComponentImpl(new TestSecureRandomProvider());
KeyPair k = crypto.generateSignatureKeyPair(); KeyPair k = generateKeyPair();
publicKey = k.getPublic().getEncoded(); publicKey = k.getPublic().getEncoded();
privateKey = k.getPrivate().getEncoded(); privateKey = k.getPrivate().getEncoded();
} }
@@ -33,19 +42,19 @@ public class SignatureTest extends BrambleTestCase {
public void testIdenticalKeysAndInputsProduceIdenticalSignatures() public void testIdenticalKeysAndInputsProduceIdenticalSignatures()
throws Exception { throws Exception {
// Calculate the Signature twice - the results should be identical // Calculate the Signature twice - the results should be identical
byte[] sig1 = crypto.sign(label, inputBytes, privateKey); byte[] sig1 = sign(label, inputBytes, privateKey);
byte[] sig2 = crypto.sign(label, inputBytes, privateKey); byte[] sig2 = sign(label, inputBytes, privateKey);
assertArrayEquals(sig1, sig2); assertArrayEquals(sig1, sig2);
} }
@Test @Test
public void testDifferentKeysProduceDifferentSignatures() throws Exception { public void testDifferentKeysProduceDifferentSignatures() throws Exception {
// Generate second private key // Generate second private key
KeyPair k2 = crypto.generateSignatureKeyPair(); KeyPair k2 = generateKeyPair();
byte[] privateKey2 = k2.getPrivate().getEncoded(); byte[] privateKey2 = k2.getPrivate().getEncoded();
// Calculate the signature with each key // Calculate the signature with each key
byte[] sig1 = crypto.sign(label, inputBytes, privateKey); byte[] sig1 = sign(label, inputBytes, privateKey);
byte[] sig2 = crypto.sign(label, inputBytes, privateKey2); byte[] sig2 = sign(label, inputBytes, privateKey2);
assertFalse(Arrays.equals(sig1, sig2)); assertFalse(Arrays.equals(sig1, sig2));
} }
@@ -56,8 +65,8 @@ public class SignatureTest extends BrambleTestCase {
byte[] inputBytes2 = TestUtils.getRandomBytes(123); byte[] inputBytes2 = TestUtils.getRandomBytes(123);
// Calculate the signature with different inputs // Calculate the signature with different inputs
// the results should be different // the results should be different
byte[] sig1 = crypto.sign(label, inputBytes, privateKey); byte[] sig1 = sign(label, inputBytes, privateKey);
byte[] sig2 = crypto.sign(label, inputBytes2, privateKey); byte[] sig2 = sign(label, inputBytes2, privateKey);
assertFalse(Arrays.equals(sig1, sig2)); assertFalse(Arrays.equals(sig1, sig2));
} }
@@ -68,25 +77,25 @@ public class SignatureTest extends BrambleTestCase {
String label2 = StringUtils.getRandomString(42); String label2 = StringUtils.getRandomString(42);
// Calculate the signature with different inputs // Calculate the signature with different inputs
// the results should be different // the results should be different
byte[] sig1 = crypto.sign(label, inputBytes, privateKey); byte[] sig1 = sign(label, inputBytes, privateKey);
byte[] sig2 = crypto.sign(label2, inputBytes, privateKey); byte[] sig2 = sign(label2, inputBytes, privateKey);
assertFalse(Arrays.equals(sig1, sig2)); assertFalse(Arrays.equals(sig1, sig2));
} }
@Test @Test
public void testSignatureVerification() throws Exception { public void testSignatureVerification() throws Exception {
byte[] sig = crypto.sign(label, inputBytes, privateKey); byte[] sig = sign(label, inputBytes, privateKey);
assertTrue(crypto.verify(label, inputBytes, publicKey, sig)); assertTrue(verify(label, inputBytes, publicKey, sig));
} }
@Test @Test
public void testDifferentKeyFailsVerification() throws Exception { public void testDifferentKeyFailsVerification() throws Exception {
// Generate second private key // Generate second private key
KeyPair k2 = crypto.generateSignatureKeyPair(); KeyPair k2 = generateKeyPair();
byte[] privateKey2 = k2.getPrivate().getEncoded(); byte[] privateKey2 = k2.getPrivate().getEncoded();
// calculate the signature with different key, should fail to verify // calculate the signature with different key, should fail to verify
byte[] sig = crypto.sign(label, inputBytes, privateKey2); byte[] sig = sign(label, inputBytes, privateKey2);
assertFalse(crypto.verify(label, inputBytes, publicKey, sig)); assertFalse(verify(label, inputBytes, publicKey, sig));
} }
@Test @Test
@@ -94,8 +103,8 @@ public class SignatureTest extends BrambleTestCase {
// Generate a second input // Generate a second input
byte[] inputBytes2 = TestUtils.getRandomBytes(123); byte[] inputBytes2 = TestUtils.getRandomBytes(123);
// calculate the signature with different input, should fail to verify // calculate the signature with different input, should fail to verify
byte[] sig = crypto.sign(label, inputBytes, privateKey); byte[] sig = sign(label, inputBytes, privateKey);
assertFalse(crypto.verify(label, inputBytes2, publicKey, sig)); assertFalse(verify(label, inputBytes2, publicKey, sig));
} }
@Test @Test
@@ -103,8 +112,8 @@ public class SignatureTest extends BrambleTestCase {
// Generate a second label // Generate a second label
String label2 = StringUtils.getRandomString(42); String label2 = StringUtils.getRandomString(42);
// calculate the signature with different label, should fail to verify // calculate the signature with different label, should fail to verify
byte[] sig = crypto.sign(label, inputBytes, privateKey); byte[] sig = sign(label, inputBytes, privateKey);
assertFalse(crypto.verify(label2, inputBytes, publicKey, sig)); assertFalse(verify(label2, inputBytes, publicKey, sig));
} }
} }

View File

@@ -150,17 +150,14 @@ public class LanTcpPluginTest extends BrambleTestCase {
int port = ss.getLocalPort(); int port = ss.getLocalPort();
CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1);
AtomicBoolean error = new AtomicBoolean(false); AtomicBoolean error = new AtomicBoolean(false);
new Thread() { new Thread(() -> {
@Override try {
public void run() { ss.accept();
try { latch.countDown();
ss.accept(); } catch (IOException e) {
latch.countDown(); error.set(true);
} catch (IOException e) {
error.set(true);
}
} }
}.start(); }).start();
// Tell the plugin about the port // Tell the plugin about the port
TransportProperties p = new TransportProperties(); TransportProperties p = new TransportProperties();
p.put("ipPorts", addrString + ":" + port); p.put("ipPorts", addrString + ":" + port);
@@ -243,17 +240,14 @@ public class LanTcpPluginTest extends BrambleTestCase {
ss.bind(new InetSocketAddress(addrString, 0), 10); ss.bind(new InetSocketAddress(addrString, 0), 10);
CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1);
AtomicBoolean error = new AtomicBoolean(false); AtomicBoolean error = new AtomicBoolean(false);
new Thread() { new Thread(() -> {
@Override try {
public void run() { ss.accept();
try { latch.countDown();
ss.accept(); } catch (IOException e) {
latch.countDown(); error.set(true);
} catch (IOException e) {
error.set(true);
}
} }
}.start(); }).start();
// Tell the plugin about the port // Tell the plugin about the port
BdfList descriptor = new BdfList(); BdfList descriptor = new BdfList();
descriptor.add(TRANSPORT_ID_LAN); descriptor.add(TRANSPORT_ID_LAN);

View File

@@ -215,6 +215,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
long timestamp = 123456789; long timestamp = 123456789;
Message message = getMessage(contactGroupId, timestamp); Message message = getMessage(contactGroupId, timestamp);
Metadata meta = new Metadata(); Metadata meta = new Metadata();
// Version 4 is being delivered
BdfDictionary metaDictionary = BdfDictionary.of( BdfDictionary metaDictionary = BdfDictionary.of(
new BdfEntry("transportId", "foo"), new BdfEntry("transportId", "foo"),
new BdfEntry("version", 4), new BdfEntry("version", 4),
@@ -222,19 +223,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
); );
Map<MessageId, BdfDictionary> messageMetadata = Map<MessageId, BdfDictionary> messageMetadata =
new LinkedHashMap<>(); new LinkedHashMap<>();
// Old remote updates for the same transport should be deleted // An older remote update for the same transport should be deleted
MessageId fooVersion2 = new MessageId(getRandomId());
messageMetadata.put(fooVersion2, BdfDictionary.of(
new BdfEntry("transportId", "foo"),
new BdfEntry("version", 2),
new BdfEntry("local", false)
));
MessageId fooVersion1 = new MessageId(getRandomId());
messageMetadata.put(fooVersion1, BdfDictionary.of(
new BdfEntry("transportId", "foo"),
new BdfEntry("version", 1),
new BdfEntry("local", false)
));
MessageId fooVersion3 = new MessageId(getRandomId()); MessageId fooVersion3 = new MessageId(getRandomId());
messageMetadata.put(fooVersion3, BdfDictionary.of( messageMetadata.put(fooVersion3, BdfDictionary.of(
new BdfEntry("transportId", "foo"), new BdfEntry("transportId", "foo"),
@@ -248,11 +237,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroupId); contactGroupId);
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
// Versions 1-3 should be deleted // The previous update (version 3) should be deleted
oneOf(db).deleteMessage(txn, fooVersion1);
oneOf(db).deleteMessageMetadata(txn, fooVersion1);
oneOf(db).deleteMessage(txn, fooVersion2);
oneOf(db).deleteMessageMetadata(txn, fooVersion2);
oneOf(db).deleteMessage(txn, fooVersion3); oneOf(db).deleteMessage(txn, fooVersion3);
oneOf(db).deleteMessageMetadata(txn, fooVersion3); oneOf(db).deleteMessageMetadata(txn, fooVersion3);
}}); }});
@@ -268,6 +253,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
long timestamp = 123456789; long timestamp = 123456789;
Message message = getMessage(contactGroupId, timestamp); Message message = getMessage(contactGroupId, timestamp);
Metadata meta = new Metadata(); Metadata meta = new Metadata();
// Version 3 is being delivered
BdfDictionary metaDictionary = BdfDictionary.of( BdfDictionary metaDictionary = BdfDictionary.of(
new BdfEntry("transportId", "foo"), new BdfEntry("transportId", "foo"),
new BdfEntry("version", 3), new BdfEntry("version", 3),
@@ -275,19 +261,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
); );
Map<MessageId, BdfDictionary> messageMetadata = Map<MessageId, BdfDictionary> messageMetadata =
new LinkedHashMap<>(); new LinkedHashMap<>();
// Old remote updates for the same transport should be deleted
MessageId fooVersion2 = new MessageId(getRandomId());
messageMetadata.put(fooVersion2, BdfDictionary.of(
new BdfEntry("transportId", "foo"),
new BdfEntry("version", 2),
new BdfEntry("local", false)
));
MessageId fooVersion1 = new MessageId(getRandomId());
messageMetadata.put(fooVersion1, BdfDictionary.of(
new BdfEntry("transportId", "foo"),
new BdfEntry("version", 1),
new BdfEntry("local", false)
));
// A newer remote update for the same transport should not be deleted // A newer remote update for the same transport should not be deleted
MessageId fooVersion4 = new MessageId(getRandomId()); MessageId fooVersion4 = new MessageId(getRandomId());
messageMetadata.put(fooVersion4, BdfDictionary.of( messageMetadata.put(fooVersion4, BdfDictionary.of(
@@ -302,11 +275,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroupId); contactGroupId);
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
// Versions 1 and 2 should be deleted, version 4 should not
oneOf(db).deleteMessage(txn, fooVersion1);
oneOf(db).deleteMessageMetadata(txn, fooVersion1);
oneOf(db).deleteMessage(txn, fooVersion2);
oneOf(db).deleteMessageMetadata(txn, fooVersion2);
// The update being delivered (version 3) should be deleted // The update being delivered (version 3) should be deleted
oneOf(db).deleteMessage(txn, message.getId()); oneOf(db).deleteMessage(txn, message.getId());
oneOf(db).deleteMessageMetadata(txn, message.getId()); oneOf(db).deleteMessageMetadata(txn, message.getId());
@@ -343,7 +311,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testReturnsLatestLocalProperties() throws Exception { public void testReturnsLatestLocalProperties() throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, true);
expectGetLocalProperties(txn); expectGetLocalProperties(txn);
@@ -357,7 +325,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testReturnsEmptyPropertiesIfNoLocalPropertiesAreFound() public void testReturnsEmptyPropertiesIfNoLocalPropertiesAreFound()
throws Exception { throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, true);
Map<MessageId, BdfDictionary> messageMetadata = Map<MessageId, BdfDictionary> messageMetadata =
new LinkedHashMap<>(); new LinkedHashMap<>();
// A local update for another transport should be ignored // A local update for another transport should be ignored
@@ -369,7 +337,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
)); ));
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).startTransaction(false); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
@@ -384,7 +352,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testReturnsLocalProperties() throws Exception { public void testReturnsLocalProperties() throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, true);
Map<MessageId, BdfDictionary> messageMetadata = Map<MessageId, BdfDictionary> messageMetadata =
new LinkedHashMap<>(); new LinkedHashMap<>();
// A local update for another transport should be ignored // A local update for another transport should be ignored
@@ -404,7 +372,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict); BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).startTransaction(false); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
@@ -423,7 +391,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testReturnsRemotePropertiesOrEmptyProperties() public void testReturnsRemotePropertiesOrEmptyProperties()
throws Exception { throws Exception {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, true);
Contact contact1 = getContact(false); Contact contact1 = getContact(false);
Contact contact2 = getContact(true); Contact contact2 = getContact(true);
Contact contact3 = getContact(true); Contact contact3 = getContact(true);
@@ -457,7 +425,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict); BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).startTransaction(false); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(contacts)); will(returnValue(contacts));
@@ -638,28 +606,14 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
return new Message(messageId, g, timestamp, raw); return new Message(messageId, g, timestamp, raw);
} }
private void expectGetLocalProperties(Transaction txn) private void expectGetLocalProperties(Transaction txn) throws Exception {
throws Exception { Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
Map<MessageId, BdfDictionary> messageMetadata = // The latest update for transport "foo" should be returned
new LinkedHashMap<>();
// The only update for transport "foo" should be returned
MessageId fooVersion999 = new MessageId(getRandomId()); MessageId fooVersion999 = new MessageId(getRandomId());
messageMetadata.put(fooVersion999, BdfDictionary.of( messageMetadata.put(fooVersion999, BdfDictionary.of(
new BdfEntry("transportId", "foo"), new BdfEntry("transportId", "foo"),
new BdfEntry("version", 999) new BdfEntry("version", 999)
)); ));
// An old update for transport "bar" should be deleted
MessageId barVersion2 = new MessageId(getRandomId());
messageMetadata.put(barVersion2, BdfDictionary.of(
new BdfEntry("transportId", "bar"),
new BdfEntry("version", 2)
));
// An even older update for transport "bar" should be deleted
MessageId barVersion1 = new MessageId(getRandomId());
messageMetadata.put(barVersion1, BdfDictionary.of(
new BdfEntry("transportId", "bar"),
new BdfEntry("version", 1)
));
// The latest update for transport "bar" should be returned // The latest update for transport "bar" should be returned
MessageId barVersion3 = new MessageId(getRandomId()); MessageId barVersion3 = new MessageId(getRandomId());
messageMetadata.put(barVersion3, BdfDictionary.of( messageMetadata.put(barVersion3, BdfDictionary.of(
@@ -674,8 +628,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
localGroup.getId()); localGroup.getId());
will(returnValue(messageMetadata)); will(returnValue(messageMetadata));
oneOf(db).removeMessage(txn, barVersion1);
oneOf(db).removeMessage(txn, barVersion2);
// Retrieve and parse the latest local properties // Retrieve and parse the latest local properties
oneOf(clientHelper).getMessageAsList(txn, fooVersion999); oneOf(clientHelper).getMessageAsList(txn, fooVersion999);
will(returnValue(fooUpdate)); will(returnValue(fooUpdate));

View File

@@ -12,16 +12,16 @@ dependencies {
implementation 'net.java.dev.jna:jna:4.4.0' implementation 'net.java.dev.jna:jna:4.4.0'
implementation 'net.java.dev.jna:jna-platform:4.4.0' implementation 'net.java.dev.jna:jna-platform:4.4.0'
apt 'com.google.dagger:dagger-compiler:2.0.2' apt "com.google.dagger:dagger-compiler:$daggerVersion"
testImplementation project(path: ':bramble-api', configuration: 'testOutput') testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation project(path: ':bramble-core', configuration: 'testOutput') testImplementation project(path: ':bramble-core', configuration: 'testOutput')
testImplementation 'junit:junit:4.12' testImplementation "junit:junit:$junitVersion"
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:$jmockVersion"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:$jmockVersion"
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:$jmockVersion"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
} }
dependencyVerification { dependencyVerification {
@@ -36,6 +36,7 @@ dependencyVerification {
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728', 'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a', 'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
'net.java.dev.jna:jna-platform:4.4.0:jna-platform-4.4.0.jar:e9dda9e884fc107eb6367710540789a12dfa8ad28be9326b22ca6e352e325499', 'net.java.dev.jna:jna-platform:4.4.0:jna-platform-4.4.0.jar:e9dda9e884fc107eb6367710540789a12dfa8ad28be9326b22ca6e352e325499',
'net.java.dev.jna:jna:4.4.0:jna-4.4.0.jar:c4dadeeecaa90c8847902082aee5eb107fcf59c5d0e63a17fcaf273c0e2d2bd1', 'net.java.dev.jna:jna:4.4.0:jna-4.4.0.jar:c4dadeeecaa90c8847902082aee5eb107fcf59c5d0e63a17fcaf273c0e2d2bd1',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d', 'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',

View File

@@ -6,7 +6,6 @@ dependencies {
implementation project(path: ':bramble-core', configuration: 'default') implementation project(path: ':bramble-core', configuration: 'default')
implementation project(path: ':bramble-android', configuration: 'default') implementation project(path: ':bramble-android', configuration: 'default')
def supportVersion = '27.0.1'
implementation "com.android.support:support-v4:$supportVersion" implementation "com.android.support:support-v4:$supportVersion"
implementation("com.android.support:appcompat-v7:$supportVersion") { implementation("com.android.support:appcompat-v7:$supportVersion") {
exclude module: 'support-v4' exclude module: 'support-v4'
@@ -34,7 +33,7 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:3.8.0' implementation 'com.github.bumptech.glide:glide:3.8.0'
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.1.0' implementation 'uk.co.samuelwall:material-tap-target-prompt:2.1.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2' annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
compileOnly 'javax.annotation:jsr250-api:1.0' compileOnly 'javax.annotation:jsr250-api:1.0'
@@ -43,12 +42,12 @@ dependencies {
testImplementation 'org.robolectric:robolectric:3.5.1' testImplementation 'org.robolectric:robolectric:3.5.1'
testImplementation 'org.robolectric:shadows-support-v4:3.0' testImplementation 'org.robolectric:shadows-support-v4:3.0'
testImplementation 'org.mockito:mockito-core:2.8.9' testImplementation 'org.mockito:mockito-core:2.8.9'
testImplementation 'junit:junit:4.12' testImplementation "junit:junit:$junitVersion"
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:$jmockVersion"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:$jmockVersion"
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:$jmockVersion"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
} }
dependencyVerification { dependencyVerification {
@@ -108,6 +107,7 @@ dependencyVerification {
'nekohtml:xercesMinimal:1.9.6.2:xercesMinimal-1.9.6.2.jar:95b8b357d19f63797dd7d67622fd3f18374d64acbc6584faba1c7759a31e8438', 'nekohtml:xercesMinimal:1.9.6.2:xercesMinimal-1.9.6.2.jar:95b8b357d19f63797dd7d67622fd3f18374d64acbc6584faba1c7759a31e8438',
'net.bytebuddy:byte-buddy-agent:1.6.14:byte-buddy-agent-1.6.14.jar:c141a2d6809c3eeff4a43d25992826abccebdd4b793af3e7a5f346e88ae73a33', 'net.bytebuddy:byte-buddy-agent:1.6.14:byte-buddy-agent-1.6.14.jar:c141a2d6809c3eeff4a43d25992826abccebdd4b793af3e7a5f346e88ae73a33',
'net.bytebuddy:byte-buddy:1.6.14:byte-buddy-1.6.14.jar:917758b3c651e278a15a029ba1d42dbf802d8b0e1fe2aa4b81c5750c64f461c1', 'net.bytebuddy:byte-buddy:1.6.14:byte-buddy-1.6.14.jar:917758b3c651e278a15a029ba1d42dbf802d8b0e1fe2aa4b81c5750c64f461c1',
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d', 'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8', 'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
'org.apache.maven.wagon:wagon-file:1.0-beta-6:wagon-file-1.0-beta-6.jar:7298feeb36ff14dd933c38e62585fb9973fea32fb3c4bc5379428cb1aac5dd3c', 'org.apache.maven.wagon:wagon-file:1.0-beta-6:wagon-file-1.0-beta-6.jar:7298feeb36ff14dd933c38e62585fb9973fea32fb3c4bc5379428cb1aac5dd3c',
@@ -169,7 +169,7 @@ def getGitHash = { ->
def stdout = new ByteArrayOutputStream() def stdout = new ByteArrayOutputStream()
try { try {
exec { exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD' commandLine 'git', 'rev-parse', '--short=7', 'HEAD'
standardOutput = stdout standardOutput = stdout
} }
return stdout.toString().trim() return stdout.toString().trim()
@@ -185,18 +185,18 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 1612 versionCode 1700
versionName "0.16.12" versionName "0.17.0"
applicationId "org.briarproject.briar.beta" applicationId "org.briarproject.briar.android"
resValue "string", "app_package", "org.briarproject.briar.beta" resValue "string", "app_package", "org.briarproject.briar.android"
resValue "string", "app_name", "Briar Beta" resValue "string", "app_name", "Briar"
buildConfigField "String", "GitHash", "\"${getGitHash()}\"" buildConfigField "String", "GitHash", "\"${getGitHash()}\""
} }
buildTypes { buildTypes {
debug { debug {
applicationIdSuffix ".debug" applicationIdSuffix ".debug"
resValue "string", "app_package", "org.briarproject.briar.beta.debug" resValue "string", "app_package", "org.briarproject.briar.android.debug"
resValue "string", "app_name", "Briar Debug" resValue "string", "app_name", "Briar Debug"
shrinkResources false shrinkResources false
minifyEnabled true minifyEnabled true

View File

@@ -6,8 +6,8 @@ package org.briarproject.briar.android;
*/ */
public interface BriarApplication { public interface BriarApplication {
// This build expires on 31 December 2017 // This build expires on 31 December 2018
long EXPIRY_DATE = 1514761200 * 1000L; long EXPIRY_DATE = 1546214400 * 1000L;
AndroidComponent getApplicationComponent(); AndroidComponent getApplicationComponent();

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.android; package org.briarproject.briar.android;
import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
@@ -73,8 +74,20 @@ public class BriarService extends Service {
stopSelf(); stopSelf();
return; return;
} }
// Create mandatory notification channel
String channelId = "foregroundService";
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel(channelId,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_NONE);
channel.setLockscreenVisibility(VISIBILITY_SECRET);
NotificationManager nm =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.createNotificationChannel(channel);
}
// Show an ongoing notification that the service is running // Show an ongoing notification that the service is running
NotificationCompat.Builder b = new NotificationCompat.Builder(this); NotificationCompat.Builder b =
new NotificationCompat.Builder(this, channelId);
b.setSmallIcon(R.drawable.notification_ongoing); b.setSmallIcon(R.drawable.notification_ongoing);
b.setColor(ContextCompat.getColor(this, R.color.briar_primary)); b.setColor(ContextCompat.getColor(this, R.color.briar_primary));
b.setContentTitle(getText(R.string.ongoing_notification_title)); b.setContentTitle(getText(R.string.ongoing_notification_title));
@@ -91,24 +104,21 @@ public class BriarService extends Service {
b.setPriority(PRIORITY_MIN); b.setPriority(PRIORITY_MIN);
startForeground(ONGOING_NOTIFICATION_ID, b.build()); startForeground(ONGOING_NOTIFICATION_ID, b.build());
// Start the services in a background thread // Start the services in a background thread
new Thread() { new Thread(() -> {
@Override String nickname = databaseConfig.getLocalAuthorName();
public void run() { StartResult result = lifecycleManager.startServices(nickname);
String nickname = databaseConfig.getLocalAuthorName(); if (result == SUCCESS) {
StartResult result = lifecycleManager.startServices(nickname); started = true;
if (result == SUCCESS) { } else if (result == ALREADY_RUNNING) {
started = true; LOG.info("Already running");
} else if (result == ALREADY_RUNNING) { stopSelf();
LOG.info("Already running"); } else {
stopSelf(); if (LOG.isLoggable(WARNING))
} else { LOG.warning("Startup failed: " + result);
if (LOG.isLoggable(WARNING)) showStartupFailureNotification(result);
LOG.warning("Startup failed: " + result); stopSelf();
showStartupFailureNotification(result);
stopSelf();
}
} }
}.start(); }).start();
} }
private void showStartupFailureNotification(StartResult result) { private void showStartupFailureNotification(StartResult result) {
@@ -155,12 +165,9 @@ public class BriarService extends Service {
LOG.info("Destroyed"); LOG.info("Destroyed");
stopForeground(true); stopForeground(true);
// Stop the services in a background thread // Stop the services in a background thread
new Thread() { new Thread(() -> {
@Override if (started) lifecycleManager.stopServices();
public void run() { }).start();
if (started) lifecycleManager.stopServices();
}
}.start();
} }
@Override @Override

View File

@@ -18,7 +18,7 @@ public interface TestingConstants {
* Whether this is a beta build. This should be set to false for final * Whether this is a beta build. This should be set to false for final
* release builds. * release builds.
*/ */
boolean IS_BETA_BUILD = true; boolean IS_BETA_BUILD = false;
/** /**
* Default log level. Disable logging for final release builds. * Default log level. Disable logging for final release builds.

View File

@@ -123,25 +123,22 @@ public class BriarControllerImpl implements BriarController {
@Override @Override
public void signOut(ResultHandler<Void> eventHandler) { public void signOut(ResultHandler<Void> eventHandler) {
new Thread() { new Thread(() -> {
@Override try {
public void run() { // Wait for the service to finish starting up
try { IBinder binder = serviceConnection.waitForBinder();
// Wait for the service to finish starting up BriarService service =
IBinder binder = serviceConnection.waitForBinder(); ((BriarService.BriarBinder) binder).getService();
BriarService service = service.waitForStartup();
((BriarService.BriarBinder) binder).getService(); // Shut down the service and wait for it to shut down
service.waitForStartup(); LOG.info("Shutting down service");
// Shut down the service and wait for it to shut down service.shutdown();
LOG.info("Shutting down service"); service.waitForShutdown();
service.shutdown(); } catch (InterruptedException e) {
service.waitForShutdown(); LOG.warning("Interrupted while waiting for service");
} catch (InterruptedException e) {
LOG.warning("Interrupted while waiting for service");
}
eventHandler.onResult(null);
} }
}.start(); eventHandler.onResult(null);
}).start();
} }
private void unbindService() { private void unbindService() {

View File

@@ -29,6 +29,8 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.briar.android.BriarApplication.EXPIRY_DATE; import static org.briarproject.briar.android.BriarApplication.EXPIRY_DATE;
import static org.briarproject.briar.android.TestingConstants.IS_BETA_BUILD;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
import static org.briarproject.briar.android.controller.BriarControllerImpl.DOZE_ASK_AGAIN; import static org.briarproject.briar.android.controller.BriarControllerImpl.DOZE_ASK_AGAIN;
import static org.briarproject.briar.android.navdrawer.NavDrawerController.ExpiryWarning.NO; import static org.briarproject.briar.android.navdrawer.NavDrawerController.ExpiryWarning.NO;
import static org.briarproject.briar.android.navdrawer.NavDrawerController.ExpiryWarning.SHOW; import static org.briarproject.briar.android.navdrawer.NavDrawerController.ExpiryWarning.SHOW;
@@ -106,6 +108,10 @@ public class NavDrawerControllerImpl extends DbControllerImpl
@Override @Override
public void showExpiryWarning(ResultHandler<ExpiryWarning> handler) { public void showExpiryWarning(ResultHandler<ExpiryWarning> handler) {
if (!IS_DEBUG_BUILD && !IS_BETA_BUILD) {
handler.onResult(NO);
return;
}
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
Settings settings = Settings settings =

View File

@@ -34,10 +34,10 @@
<string name="startup_failed_db_error">For some reason, your Briar database is corrupted beyond repair. Your account, your data and all your contacts are lost. Unfortunately, you need to reinstall Briar and set up a new account.</string> <string name="startup_failed_db_error">For some reason, your Briar database is corrupted beyond repair. Your account, your data and all your contacts are lost. Unfortunately, you need to reinstall Briar and set up a new account.</string>
<string name="startup_failed_service_error">Briar was unable to start a required plugin. Reinstalling Briar usually solves this problem. However, please note that you will then lose your account and all data associated with it since Briar is not using central servers to store your data on.</string> <string name="startup_failed_service_error">Briar was unable to start a required plugin. Reinstalling Briar usually solves this problem. However, please note that you will then lose your account and all data associated with it since Briar is not using central servers to store your data on.</string>
<plurals name="expiry_warning"> <plurals name="expiry_warning">
<item quantity="one">This is a beta version of Briar. Your account will expire in %d day and cannot be renewed.</item> <item quantity="one">This is a test version of Briar. Your account will expire in %d day and cannot be renewed.</item>
<item quantity="other">This is a beta version of Briar. Your account will expire in %d days and cannot be renewed.</item> <item quantity="other">This is a test version of Briar. Your account will expire in %d days and cannot be renewed.</item>
</plurals> </plurals>
<string name="expiry_update">The beta expiry date has been extended. Your account will now expire in %d days.</string> <string name="expiry_update">The testing expiry date has been extended. Your account will now expire in %d days.</string>
<string name="expiry_date_reached">This software has expired.\nThank you for testing!</string> <string name="expiry_date_reached">This software has expired.\nThank you for testing!</string>
<!-- Navigation Drawer --> <!-- Navigation Drawer -->

View File

@@ -17,8 +17,8 @@ import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
@NotNullByDefault @NotNullByDefault
public interface BlogPostFactory { public interface BlogPostFactory {
String SIGNING_LABEL_POST = CLIENT_ID + "/POST"; String SIGNING_LABEL_POST = CLIENT_ID.getString() + "/POST";
String SIGNING_LABEL_COMMENT = CLIENT_ID + "/COMMENT"; String SIGNING_LABEL_COMMENT = CLIENT_ID.getString() + "/COMMENT";
BlogPost createBlogPost(GroupId groupId, long timestamp, BlogPost createBlogPost(GroupId groupId, long timestamp,
@Nullable MessageId parent, LocalAuthor author, String body) @Nullable MessageId parent, LocalAuthor author, String body)

View File

@@ -16,7 +16,7 @@ import static org.briarproject.briar.api.forum.ForumManager.CLIENT_ID;
@NotNullByDefault @NotNullByDefault
public interface ForumPostFactory { public interface ForumPostFactory {
String SIGNING_LABEL_POST = CLIENT_ID + "/POST"; String SIGNING_LABEL_POST = CLIENT_ID.getString() + "/POST";
@CryptoExecutor @CryptoExecutor
ForumPost createPost(GroupId groupId, long timestamp, ForumPost createPost(GroupId groupId, long timestamp,

View File

@@ -13,8 +13,8 @@ import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT
@NotNullByDefault @NotNullByDefault
public interface GroupMessageFactory { public interface GroupMessageFactory {
String SIGNING_LABEL_JOIN = CLIENT_ID + "/JOIN"; String SIGNING_LABEL_JOIN = CLIENT_ID.getString() + "/JOIN";
String SIGNING_LABEL_POST = CLIENT_ID + "/POST"; String SIGNING_LABEL_POST = CLIENT_ID.getString() + "/POST";
/** /**
* Creates a join announcement message for the creator of a group. * Creates a join announcement message for the creator of a group.

View File

@@ -12,7 +12,7 @@ import static org.briarproject.briar.api.privategroup.invitation.GroupInvitation
@NotNullByDefault @NotNullByDefault
public interface GroupInvitationFactory { public interface GroupInvitationFactory {
String SIGNING_LABEL_INVITE = CLIENT_ID + "/INVITE"; String SIGNING_LABEL_INVITE = CLIENT_ID.getString() + "/INVITE";
/** /**
* Returns a signature to include when inviting a member to join a private * Returns a signature to include when inviting a member to join a private

View File

@@ -13,20 +13,20 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.8.0' implementation 'com.squareup.okhttp3:okhttp:3.8.0'
implementation 'org.jsoup:jsoup:1.10.3' implementation 'org.jsoup:jsoup:1.10.3'
apt 'com.google.dagger:dagger-compiler:2.0.2' apt "com.google.dagger:dagger-compiler:$daggerVersion"
testImplementation project(path: ':bramble-core', configuration: 'default') testImplementation project(path: ':bramble-core', configuration: 'default')
testImplementation project(path: ':bramble-core', configuration: 'testOutput') testImplementation project(path: ':bramble-core', configuration: 'testOutput')
testImplementation project(path: ':bramble-api', configuration: 'testOutput') testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation 'net.jodah:concurrentunit:0.4.2' testImplementation 'net.jodah:concurrentunit:0.4.2'
testImplementation 'junit:junit:4.12' testImplementation "junit:junit:$junitVersion"
testImplementation "org.jmock:jmock:2.8.2" testImplementation "org.jmock:jmock:$jmockVersion"
testImplementation "org.jmock:jmock-junit4:2.8.2" testImplementation "org.jmock:jmock-junit4:$jmockVersion"
testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.jmock:jmock-legacy:$jmockVersion"
testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
testImplementation "org.hamcrest:hamcrest-core:1.3" testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
testApt 'com.google.dagger:dagger-compiler:2.0.2' testApt "com.google.dagger:dagger-compiler:$daggerVersion"
} }
dependencyVerification { dependencyVerification {
@@ -45,6 +45,7 @@ dependencyVerification {
'com.squareup.okio:okio:1.13.0:okio-1.13.0.jar:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850', 'com.squareup.okio:okio:1.13.0:okio-1.13.0.jar:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a', 'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
'net.jodah:concurrentunit:0.4.2:concurrentunit-0.4.2.jar:5583078e1acf91734939e985bc9e7ee947b0e93a8eef679da6bb07bbeb47ced3', 'net.jodah:concurrentunit:0.4.2:concurrentunit-0.4.2.jar:5583078e1acf91734939e985bc9e7ee947b0e93a8eef679da6bb07bbeb47ced3',
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d', 'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8', 'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',

View File

@@ -98,7 +98,8 @@ class IntroduceeManager {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(IntroduceeManager.class.getName()); Logger.getLogger(IntroduceeManager.class.getName());
static final String SIGNING_LABEL_RESPONSE = CLIENT_ID + "/RESPONSE"; static final String SIGNING_LABEL_RESPONSE =
CLIENT_ID.getString() + "/RESPONSE";
private final MessageSender messageSender; private final MessageSender messageSender;
private final DatabaseComponent db; private final DatabaseComponent db;

View File

@@ -21,22 +21,34 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'net.ltgt.gradle:gradle-apt-plugin:0.9' classpath 'net.ltgt.gradle:gradle-apt-plugin:0.9'
classpath 'de.undercouch:gradle-download-task:3.2.0' classpath 'de.undercouch:gradle-download-task:3.3.0'
classpath files('libs/gradle-witness.jar') classpath files('libs/gradle-witness.jar')
} }
} }
// If a Java 6 JRE is available, check we're not using any Java 7 or 8 APIs
ext.useJava6StandardLibrary = { task -> ext {
def home = System.env.JAVA_6_HOME; // Define common library version centrally
if (home != null && !home.isEmpty()) { daggerVersion = '2.0.2'
println "Setting Java 6 bootstrap classpath for ${task.name}" supportVersion = '27.0.1'
task.dependsOn createJavaLangInvokeJar junitVersion = '4.12'
task.options.bootstrapClasspath = files( jmockVersion = '2.8.2'
"${project.rootDir}/build/invoke.jar", hamcrestVersion = '1.3'
"${home}/jre/lib/rt.jar", torVersion = '0.2.9.12'
"${home}/jre/lib/jsse.jar" geoipVersion = '2017-09-06'
)
// If a Java 6 JRE is available, check we're not using any Java 7 or 8 APIs
useJava6StandardLibrary = { task ->
def home = System.env.JAVA_6_HOME;
if (home != null && !home.isEmpty()) {
println "Setting Java 6 bootstrap classpath for ${task.name}"
task.dependsOn createJavaLangInvokeJar
task.options.bootstrapClasspath = files(
"${project.rootDir}/build/invoke.jar",
"${home}/jre/lib/rt.jar",
"${home}/jre/lib/jsse.jar"
)
}
} }
} }