diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 3fddc9284..c587a4166 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -101,6 +101,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0-rc03' + implementation 'org.magmacollective.darkcrystal:dark-crystal-secret-sharing-wrapper:1.0.0' implementation 'info.guardianproject.panic:panic:1.0' implementation 'info.guardianproject.trustedintents:trustedintents:0.2' diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/DarkCrystalImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/DarkCrystalImpl.java new file mode 100644 index 000000000..af7041bd6 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/DarkCrystalImpl.java @@ -0,0 +1,46 @@ +package org.briarproject.briar.android.socialbackup; +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.briar.api.socialbackup.Shard; +import org.briarproject.briar.api.socialbackup.DarkCrystal; +import org.magmacollective.darkcrystal.secretsharingwrapper.SecretSharingWrapper; + +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import static org.briarproject.briar.socialbackup.SocialBackupConstants.SECRET_ID_BYTES; + +public class DarkCrystalImpl implements DarkCrystal { + + @Override + public List createShards(SecretKey secret, int numShards, + int threshold) { + Random random = new Random(); + byte[] secretId = new byte[SECRET_ID_BYTES]; + random.nextBytes(secretId); + List shardsBytes = SecretSharingWrapper.share(secret.getBytes(), numShards, threshold); + List shards = new ArrayList<>(numShards); + for (byte[] shardBytes : shardsBytes) { + shards.add(new Shard(secretId, shardBytes)); + } + return shards; + } + + @Override + public SecretKey combineShards(List shards) throws + GeneralSecurityException { + // Check each shard has the same secret Id + byte[] secretId = shards.get(0).getSecretId(); + for (Shard shard : shards) { + if (!Arrays.equals(shard.getSecretId(), secretId)) throw new GeneralSecurityException(); + } + List shardsBytes = new ArrayList<>(shards.size()); + for (Shard shard : shards) { + shardsBytes.add(shard.getShard()); + } + byte[] secretBytes = SecretSharingWrapper.combine(shardsBytes); + return new SecretKey(secretBytes); + } +} diff --git a/briar-android/witness.gradle b/briar-android/witness.gradle index 668b51e64..853f63b7f 100644 --- a/briar-android/witness.gradle +++ b/briar-android/witness.gradle @@ -110,28 +110,32 @@ dependencyVerification { 'com.google.auto:auto-common:0.8:auto-common-0.8.jar:97db1709f57b91b32edacb596ef4641872f227b7d99ad90e467f0d77f5ba134a', 'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7', 'com.google.code.gson:gson:2.8.5:gson-2.8.5.jar:233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81', + 'com.google.code.gson:gson:2.8.6:gson-2.8.6.jar:c8fb4839054d280b3033f800d1f5a97de2f028eb8ba2eb458ad287e536f3f25f', 'com.google.dagger:dagger-compiler:2.24:dagger-compiler-2.24.jar:3c5afb955fb188da485cb2c048eff37dce0e1530b9780a0f2f7187d16d1ccc1f', 'com.google.dagger:dagger-producers:2.24:dagger-producers-2.24.jar:f10f45b95191954d5d6b043fca9e62fb621d21bf70634b8f8476c7988b504c3a', 'com.google.dagger:dagger-spi:2.24:dagger-spi-2.24.jar:c038445d14dbcb4054e61bf49e05009edf26fce4fdc7ec1a9db544784f68e718', 'com.google.dagger:dagger:2.24:dagger-2.24.jar:550a6e46a6dfcdf1d764887b6090cea94f783327e50e5c73754f18facfc70b64', 'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a', 'com.google.errorprone:error_prone_annotations:2.3.2:error_prone_annotations-2.3.2.jar:357cd6cfb067c969226c442451502aee13800a24e950fdfde77bcdb4565a668d', + 'com.google.errorprone:error_prone_annotations:2.3.4:error_prone_annotations-2.3.4.jar:baf7d6ea97ce606c53e11b6854ba5f2ce7ef5c24dddf0afa18d1260bd25b002c', 'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30', 'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e', 'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26', - 'com.google.guava:guava:27.0.1-jre:guava-27.0.1-jre.jar:e1c814fd04492a27c38e0317eabeaa1b3e950ec8010239e400fe90ad6c9107b4', 'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7', + 'com.google.guava:guava:28.1-android:guava-28.1-android.jar:e112ce92c0f0733965eede73d94589c59a72128b06b08bba5ebe2f9ea672ef60', 'com.google.guava:guava:28.1-jre:guava-28.1-jre.jar:30beb8b8527bd07c6e747e77f1a92122c2f29d57ce347461a4a55eb26e382da4', 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99', 'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6', 'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b', 'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd', - 'com.google.protobuf:protobuf-java:2.6.1:protobuf-java-2.6.1.jar:55aa554843983f431df5616112cf688d38aa17c132357afd1c109435bfdac4e6', + 'com.google.protobuf:protobuf-java-util:3.11.4:protobuf-java-util-3.11.4.jar:29aacfff1cc455102627d4cfe6f319e4864ea7ce1a4e9d03b4c7bb01fc8255b0', 'com.google.protobuf:protobuf-java:3.10.0:protobuf-java-3.10.0.jar:161d7d61a8cb3970891c299578702fd079646e032329d6c2cabf998d191437c9', + 'com.google.protobuf:protobuf-java:3.11.4:protobuf-java-3.11.4.jar:42e98f58f53d1a49fd734c2dd193880f2dfec3436a2993a00d06b8800a22a3f2', 'com.google.zxing:core:3.3.3:core-3.3.3.jar:5820f81e943e4bce0329306621e2d6255d2930b0a6ce934c5c23c0d6d3f20599', 'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439', 'com.ibm.icu:icu4j:53.1:icu4j-53.1.jar:e37a4467bac5cdeb02c5c4b8e5063d2f4e67b69e3c7df6d6b610f13185572bab', 'com.jraska:falcon:2.1.1:falcon-2.1.1.aar:827f06556b7fa599f29a48a5277df39ca3dce5080d4ea6f9ea1f9c7b6b78bb7a', + 'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728', 'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90', 'com.squareup:javawriter:2.1.1:javawriter-2.1.1.jar:f699823d0081f69cbb676c1845ea222e0ada79bc88a53e5d22d8bd02d328f57e', 'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0', @@ -156,6 +160,8 @@ dependencyVerification { 'nekohtml:xercesMinimal:1.9.6.2:xercesMinimal-1.9.6.2.jar:95b8b357d19f63797dd7d67622fd3f18374d64acbc6584faba1c7759a31e8438', 'net.bytebuddy:byte-buddy-agent:1.9.10:byte-buddy-agent-1.9.10.jar:8ed739d29132103250d307d2e8e3c95f07588ef0543ab11d2881d00768a5e182', 'net.bytebuddy:byte-buddy:1.9.10:byte-buddy-1.9.10.jar:2936debc4d7b6c534848d361412e2d0f8bd06f7f27a6f4e728a20e97648d2bf3', + 'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140', + 'net.java.dev.jna:jna:5.5.0:jna-5.5.0.aar:12ef4a3c2ea685c9c816caa6a77ae8f17bb7727d8460f249925409acda270101', 'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd', 'net.sf.jopt-simple:jopt-simple:4.9:jopt-simple-4.9.jar:26c5856e954b5f864db76f13b86919b59c6eecf9fd930b96baa8884626baf2f5', 'net.sf.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2', @@ -184,6 +190,7 @@ dependencyVerification { 'org.bouncycastle:bcprov-jdk15on:1.52:bcprov-jdk15on-1.52.jar:0dc4d181e4d347893c2ddbd2e6cd5d7287fc651c03648fa64b2341c7366b1773', 'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349', 'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d', + 'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a', 'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a', 'org.checkerframework:checker-qual:2.8.1:checker-qual-2.8.1.jar:9103499008bcecd4e948da29b17864abb64304e15706444ae209d17ebe0575df', 'org.codehaus.groovy:groovy-all:2.4.15:groovy-all-2.4.15.jar:51d6c4e71782e85674239189499854359d380fb75e1a703756e3aaa5b98a5af0', @@ -213,6 +220,9 @@ dependencyVerification { 'org.jmock:jmock-testjar:2.8.2:jmock-testjar-2.8.2.jar:8900860f72c474e027cf97fe78dcbf154a1aa7fc62b6845c5fb4e4f3c7bc8760', 'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16', 'org.jvnet.staxex:stax-ex:1.8:stax-ex-1.8.jar:95b05d9590af4154c6513b9c5dc1fb2e55b539972ba0a9ef28e9a0c01d83ad77', + 'org.magmacollective.darkcrystal:dark-crystal-key-backup-crypto:1.0.0:dark-crystal-key-backup-crypto-1.0.0.jar:7c808f30314f7bc0c715b53415b07bd7e9a6bbcc55e5f672a296e5298d335f78', + 'org.magmacollective.darkcrystal:dark-crystal-secret-sharing-wrapper:1.0.0:dark-crystal-secret-sharing-wrapper-1.0.0.aar:c31c51628a34f37ff7f61b6fe08536b4f9419f14ecb6aa9c1330c3ccbc44f637', + 'org.magmacollective.darkcrystal:shamir-secret-sharing-jna:1.0.0:shamir-secret-sharing-jna-1.0.0.aar:cdccfaf74dc1fcf30799a45d034c406315ce8507a8f4382eee118a66fb229ced', 'org.mockito:mockito-core:3.1.0:mockito-core-3.1.0.jar:89b09e518e04f5c35f5ccf7abe45e72f594070a53d95cc2579001bd392c5afa6', 'org.objenesis:objenesis:2.6:objenesis-2.6.jar:5e168368fbc250af3c79aa5fef0c3467a2d64e5a7bd74005f25d8399aeb0708d', 'org.ow2.asm:asm-analysis:7.0:asm-analysis-7.0.jar:e981f8f650c4d900bb033650b18e122fa6b161eadd5f88978d08751f72ee8474', @@ -231,6 +241,7 @@ dependencyVerification { 'org.robolectric:shadows-framework:4.3.1:shadows-framework-4.3.1.jar:9c69db134cdd79be751856a148020fd9b32b086bb491846eedc0a1106fcadd5e', 'org.robolectric:utils-reflector:4.3.1:utils-reflector-4.3.1.jar:9d7bf2557947d44d6f3ed76ec5231e8b72e33eb61c65ac9e149ad307b0eb936c', 'org.robolectric:utils:4.3.1:utils-4.3.1.jar:6f9e406cd667019a5450e473c4e2d372bff9c9ab6ef55aafcbc9843109cb1519', + 'org.whispersystems:curve25519-java:0.5.0:curve25519-java-0.5.0.jar:0aadd43cf01d11e9b58f867b3c4f25c3194e8b0623d1953d32dfbfbee009e38d', 'tools.fastlane:screengrab:2.0.0:screengrab-2.0.0.aar:15ac15eb7c371db05e721be8d466567c2b7274b767d91478e781b6d89ee5d3d0', 'uk.co.samuelwall:material-tap-target-prompt:3.0.0:material-tap-target-prompt-3.0.0.aar:e4d3c472b2d378e39a6535b7788e6c790fc9dde2d7659974e006ed8c7260911d', ] diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystal.java b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/DarkCrystal.java similarity index 79% rename from briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystal.java rename to briar-api/src/main/java/org/briarproject/briar/api/socialbackup/DarkCrystal.java index da991acbe..19390e98f 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystal.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/DarkCrystal.java @@ -1,13 +1,13 @@ -package org.briarproject.briar.socialbackup; +package org.briarproject.briar.api.socialbackup; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.api.socialbackup.Shard; import java.security.GeneralSecurityException; import java.util.List; @NotNullByDefault +public interface DarkCrystal { List createShards(SecretKey secret, int shards, int threshold); diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystalStub.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystalStub.java index 6671b14ff..80b339f79 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystalStub.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/DarkCrystalStub.java @@ -2,6 +2,7 @@ package org.briarproject.briar.socialbackup; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.briar.api.socialbackup.DarkCrystal; import org.briarproject.briar.api.socialbackup.Shard; import java.security.GeneralSecurityException; diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupConstants.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupConstants.java index 924609a72..4de42b420 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupConstants.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupConstants.java @@ -1,6 +1,6 @@ package org.briarproject.briar.socialbackup; -interface SocialBackupConstants { +public interface SocialBackupConstants { // Group metadata keys String GROUP_KEY_CONTACT_ID = "contactId"; diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java index f864d9427..c0a187603 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java @@ -39,6 +39,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook; import org.briarproject.briar.api.socialbackup.BackupExistsException; import org.briarproject.briar.api.socialbackup.BackupMetadata; +import org.briarproject.briar.api.socialbackup.DarkCrystal; import org.briarproject.briar.api.socialbackup.Shard; import org.briarproject.briar.api.socialbackup.SocialBackupManager; diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java index 4e568b4af..c2fb34c54 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java @@ -7,6 +7,7 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.sync.validation.ValidationManager; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.versioning.ClientVersioningManager; +import org.briarproject.briar.api.socialbackup.DarkCrystal; import org.briarproject.briar.api.socialbackup.SocialBackupManager; import javax.inject.Inject; diff --git a/build.gradle b/build.gradle index 75ffd3401..241efb19f 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,7 @@ allprojects { jcenter() mavenLocal() google() + maven { url 'https://mvn.darkcrystal.pw' } maven { url "https://jitpack.io" } } afterEvaluate {