mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
493 Commits
social-bac
...
earthlingI
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
543eda68b2 | ||
|
|
5033febaed | ||
|
|
c13b40ec2e | ||
|
|
b74f635ba7 | ||
|
|
5a6c1cc0e9 | ||
|
|
a45669a750 | ||
|
|
5dd183ce47 | ||
|
|
32d121566e | ||
|
|
c76da20620 | ||
|
|
9b1d6d936e | ||
|
|
be9255029b | ||
|
|
f596811997 | ||
|
|
571ec2257e | ||
|
|
7fb2faba45 | ||
|
|
a390bf1c4f | ||
|
|
9d031fa796 | ||
|
|
d678043f8e | ||
|
|
b11147265d | ||
|
|
2fe052d77e | ||
|
|
8e91322869 | ||
|
|
1de5779e2c | ||
|
|
99b2c8af69 | ||
|
|
b1cc4fe006 | ||
|
|
d65afc519a | ||
|
|
32cbdff532 | ||
|
|
48292d2e47 | ||
|
|
89bd9ee653 | ||
|
|
61aa3a839d | ||
|
|
e38e9b943d | ||
|
|
4eb5c2ac10 | ||
|
|
ebaa3271dd | ||
|
|
adb6b4fba5 | ||
|
|
917a470559 | ||
|
|
a188e41134 | ||
|
|
b9ba813b23 | ||
|
|
b7d46b9340 | ||
|
|
60aaa4a7c1 | ||
|
|
d411b99030 | ||
|
|
acacb59114 | ||
|
|
2e07e79e4c | ||
|
|
e9dbceefe8 | ||
|
|
8cdb314170 | ||
|
|
39d3f47e19 | ||
|
|
522474ac15 | ||
|
|
ed6c4ba634 | ||
|
|
49562cbd79 | ||
|
|
6337b86266 | ||
|
|
93eadb88f3 | ||
|
|
46e391645c | ||
|
|
355c487ec9 | ||
|
|
d1c0f1b2f6 | ||
|
|
445ef0818c | ||
|
|
8af743db71 | ||
|
|
806fce8c34 | ||
|
|
f9494d71de | ||
|
|
df38187288 | ||
|
|
b8009c35f1 | ||
|
|
1306761f4a | ||
|
|
703ff9835d | ||
|
|
4abaeed32f | ||
|
|
9192ee32cf | ||
|
|
aecd204efe | ||
|
|
03cb1010e2 | ||
|
|
30063f5fbf | ||
|
|
0fb52a7f53 | ||
|
|
094024eb4f | ||
|
|
e39c99fd6c | ||
|
|
6cd70e0e7f | ||
|
|
d646635b1f | ||
|
|
a534ec2b50 | ||
|
|
a23de6172f | ||
|
|
ff2dd33435 | ||
|
|
d5d0a03638 | ||
|
|
344fff4a7a | ||
|
|
f9749fda80 | ||
|
|
aabba3a6c8 | ||
|
|
673f530c14 | ||
|
|
36a1478661 | ||
|
|
1c056160e1 | ||
|
|
ab6b83d4fa | ||
|
|
a6c33d300c | ||
|
|
28d87dd153 | ||
|
|
16b79e0482 | ||
|
|
3eee144c6c | ||
|
|
1b7007d4ef | ||
|
|
19a5c2f79f | ||
|
|
8c163d8f10 | ||
|
|
c3cd32b12c | ||
|
|
7c8aa5bc21 | ||
|
|
54b239f45e | ||
|
|
97bd977108 | ||
|
|
aaba9f2417 | ||
|
|
6a909b6c5c | ||
|
|
4ef92f1c39 | ||
|
|
8f392b4599 | ||
|
|
f556bc7249 | ||
|
|
e48886c95a | ||
|
|
e2879cd664 | ||
|
|
c3977e9276 | ||
|
|
b93803060e | ||
|
|
4498187721 | ||
|
|
8666fe45b1 | ||
|
|
cd12447c2e | ||
|
|
0a79cc882a | ||
|
|
7f80b5d660 | ||
|
|
92f58e9465 | ||
|
|
387f7f1545 | ||
|
|
65e0845376 | ||
|
|
97bb695373 | ||
|
|
d8230afae3 | ||
|
|
07afb955f7 | ||
|
|
a57d668fc9 | ||
|
|
765dbcc111 | ||
|
|
ccb4f88b89 | ||
|
|
eee9e1a488 | ||
|
|
f832f663c9 | ||
|
|
032f56ad67 | ||
|
|
3f2ac528c1 | ||
|
|
d174757ef0 | ||
|
|
f457a5e831 | ||
|
|
ab2fe58d2f | ||
|
|
fe1c384aeb | ||
|
|
4c327e9874 | ||
|
|
928b951c25 | ||
|
|
ecba2a51d8 | ||
|
|
9668f62c6a | ||
|
|
dc3ba3d8f0 | ||
|
|
3f6f970d36 | ||
|
|
768356d8e2 | ||
|
|
65110090de | ||
|
|
f5cab63052 | ||
|
|
399d8adb3b | ||
|
|
b40055686b | ||
|
|
2dcecb2a46 | ||
|
|
0cc118c849 | ||
|
|
b1148ebc83 | ||
|
|
802f64e309 | ||
|
|
80749fec09 | ||
|
|
1f1ea8f3ed | ||
|
|
796cbcaf4b | ||
|
|
4cf5242aa5 | ||
|
|
8921f10ffd | ||
|
|
b60c129acf | ||
|
|
852413b36a | ||
|
|
a39b367477 | ||
|
|
8be274dc4d | ||
|
|
9ac72296c7 | ||
|
|
1405f5954a | ||
|
|
f406de6b0c | ||
|
|
0df57c82cb | ||
|
|
4853bcd724 | ||
|
|
37e95d4ce6 | ||
|
|
23acd186f7 | ||
|
|
5e98bd0b53 | ||
|
|
d7238312b1 | ||
|
|
ec40da4353 | ||
|
|
204ad8913f | ||
|
|
c0f5023b63 | ||
|
|
b3c105bfa7 | ||
|
|
68acbe5c7d | ||
|
|
12245d960c | ||
|
|
f82c2517fb | ||
|
|
fa49da68a4 | ||
|
|
cffbfdf6f2 | ||
|
|
cd126279ac | ||
|
|
bedd6f9a6e | ||
|
|
10e0c8d876 | ||
|
|
dc2ad48a7f | ||
|
|
c010dd9401 | ||
|
|
270ef76057 | ||
|
|
9d47f27293 | ||
|
|
f0687a082a | ||
|
|
edebde2bf4 | ||
|
|
71ce74c633 | ||
|
|
2dd5239b9d | ||
|
|
f0145eb8e6 | ||
|
|
556ed8fe16 | ||
|
|
ed753fd354 | ||
|
|
4ecc5e4367 | ||
|
|
b4ae480d93 | ||
|
|
9a563e0cdd | ||
|
|
c5d6ee6782 | ||
|
|
f7fdf7745e | ||
|
|
a48b60a24a | ||
|
|
520f06020c | ||
|
|
f96b60c0d0 | ||
|
|
00f03f6587 | ||
|
|
c68bd699f1 | ||
|
|
e5f78cdc1e | ||
|
|
00407539d3 | ||
|
|
62014f4d01 | ||
|
|
e7dddda7e5 | ||
|
|
208ff6f3a5 | ||
|
|
4d31465191 | ||
|
|
cf987427e0 | ||
|
|
b11b959fd3 | ||
|
|
61f660ca1d | ||
|
|
6d44521016 | ||
|
|
7289f5ba8a | ||
|
|
b657c7f347 | ||
|
|
40865425c5 | ||
|
|
f7249f5e84 | ||
|
|
cc04fb05c2 | ||
|
|
58eb1d9e24 | ||
|
|
76b7e6fecf | ||
|
|
980940a7cf | ||
|
|
9a021daae8 | ||
|
|
cc9904a454 | ||
|
|
b0faab9395 | ||
|
|
f1198b47fd | ||
|
|
37f2ab555f | ||
|
|
61ca2a391b | ||
|
|
88537b9323 | ||
|
|
e6c004e8f6 | ||
|
|
dc7290dab7 | ||
|
|
9dff8bd64a | ||
|
|
35c2f60129 | ||
|
|
471a2372c8 | ||
|
|
fba028db03 | ||
|
|
c647c52638 | ||
|
|
cad5edcf86 | ||
|
|
38f70bb6be | ||
|
|
33bdc81b3e | ||
|
|
21fd7f5eed | ||
|
|
6354e91b55 | ||
|
|
8123c06348 | ||
|
|
663c648337 | ||
|
|
bee4e94987 | ||
|
|
c44bdc8762 | ||
|
|
423ecf71d8 | ||
|
|
73c7882cc0 | ||
|
|
552b9ef21a | ||
|
|
683af1ec3a | ||
|
|
77ed15311c | ||
|
|
3d72557618 | ||
|
|
e2a11d42f8 | ||
|
|
0f5ea6ae66 | ||
|
|
5b2c9b85f9 | ||
|
|
94921230d9 | ||
|
|
34788356e6 | ||
|
|
2f719d7f2c | ||
|
|
eb2e8d75f4 | ||
|
|
338d288290 | ||
|
|
03fe1a2d2c | ||
|
|
ade48c7bea | ||
|
|
4a8d89e2bb | ||
|
|
0fed1681ed | ||
|
|
93ad483066 | ||
|
|
d995e73996 | ||
|
|
1d271bab18 | ||
|
|
a9d2aa9366 | ||
|
|
2a48d43e5b | ||
|
|
0a4e23118a | ||
|
|
528a15962f | ||
|
|
0a0cc4e79c | ||
|
|
2b3ba42d70 | ||
|
|
9465331ece | ||
|
|
b0d86bef3e | ||
|
|
a28a2360f1 | ||
|
|
f7a957150e | ||
|
|
67bd065bc3 | ||
|
|
5a3a12767c | ||
|
|
2f86bc312c | ||
|
|
f0fcadfaf4 | ||
|
|
a9d88c849a | ||
|
|
7397efca80 | ||
|
|
17bd6f9a33 | ||
|
|
2d4e7a9fb0 | ||
|
|
0266da993d | ||
|
|
ea5280713f | ||
|
|
0b89d29c7d | ||
|
|
688bac77a8 | ||
|
|
c736bf7c06 | ||
|
|
539730f8ec | ||
|
|
a9c4669c75 | ||
|
|
4c11f93ee2 | ||
|
|
f8dba6fd7f | ||
|
|
419247074f | ||
|
|
2ddb7b5b64 | ||
|
|
c14b59661e | ||
|
|
d70d27e665 | ||
|
|
8991762b0c | ||
|
|
2fc6741c99 | ||
|
|
1075af73f2 | ||
|
|
8671229f76 | ||
|
|
0fb67583ff | ||
|
|
2fc0fd17a2 | ||
|
|
f185860213 | ||
|
|
8ffcdbfc21 | ||
|
|
6a38e2cca8 | ||
|
|
10d9d78ca8 | ||
|
|
03a68038e7 | ||
|
|
fabefcdf4b | ||
|
|
9e4d8ecddf | ||
|
|
1dffbfd8dc | ||
|
|
950db5a87a | ||
|
|
21348d5557 | ||
|
|
eb1a089437 | ||
|
|
17fc81ab7a | ||
|
|
1c54fd1101 | ||
|
|
263bce38cd | ||
|
|
a923c1151c | ||
|
|
0bf10a827f | ||
|
|
49850e4198 | ||
|
|
95b437b311 | ||
|
|
7006f765a6 | ||
|
|
ec3360400c | ||
|
|
5c41d09c52 | ||
|
|
a7590956fd | ||
|
|
a581960121 | ||
|
|
dc57a0b925 | ||
|
|
d6082162ab | ||
|
|
1801afdbb7 | ||
|
|
458add0c9c | ||
|
|
f2374eb141 | ||
|
|
5db5897793 | ||
|
|
f3d628afa7 | ||
|
|
4d3482e40e | ||
|
|
a8cff454ec | ||
|
|
f66cae4749 | ||
|
|
aded1daf92 | ||
|
|
aa1ba0d950 | ||
|
|
071010e438 | ||
|
|
f6d8e364d6 | ||
|
|
f1453ed4c4 | ||
|
|
3a2146cb03 | ||
|
|
24eb76de20 | ||
|
|
693478e0a5 | ||
|
|
bf6be5c5a7 | ||
|
|
a12a639cd3 | ||
|
|
ef37428714 | ||
|
|
644afe8995 | ||
|
|
c66c428124 | ||
|
|
db5b2ea9b6 | ||
|
|
d84603bce2 | ||
|
|
b128370299 | ||
|
|
240e619248 | ||
|
|
c89bde08db | ||
|
|
3ecd1c62b8 | ||
|
|
e3c5497283 | ||
|
|
4bd8ee8ccf | ||
|
|
43b437af92 | ||
|
|
56e0d62597 | ||
|
|
d10e5f025d | ||
|
|
b1a80691db | ||
|
|
049aa61e85 | ||
|
|
7026361234 | ||
|
|
5e30dc5bf4 | ||
|
|
024bfc8ec8 | ||
|
|
04e5e8e4d0 | ||
|
|
7c5d47733f | ||
|
|
b24f2a1818 | ||
|
|
ee6664ce9d | ||
|
|
ab434946b5 | ||
|
|
35e431eb99 | ||
|
|
aa8cddf509 | ||
|
|
c9ede0bfc1 | ||
|
|
6ec9a0f2b2 | ||
|
|
2f86112801 | ||
|
|
c032befe6f | ||
|
|
55eccde031 | ||
|
|
5716820439 | ||
|
|
17d433dd9b | ||
|
|
000812bf6d | ||
|
|
5e2187a877 | ||
|
|
e10b6334f5 | ||
|
|
baa0341727 | ||
|
|
814b2b2582 | ||
|
|
56705bde74 | ||
|
|
dceb38b777 | ||
|
|
9947a6aa1b | ||
|
|
7a3be374c8 | ||
|
|
4ea3ce0e3c | ||
|
|
923185b3f4 | ||
|
|
d91e6c6c1a | ||
|
|
1c93a79448 | ||
|
|
e12ad0cd79 | ||
|
|
8d6bd29b93 | ||
|
|
f941a73999 | ||
|
|
c3057141d8 | ||
|
|
49080cb64c | ||
|
|
27dbe23914 | ||
|
|
d7a2de5817 | ||
|
|
0328aa0630 | ||
|
|
b6cf302131 | ||
|
|
e2a894acd3 | ||
|
|
00ed6d9bb8 | ||
|
|
c9a9734368 | ||
|
|
efc56a8724 | ||
|
|
6e6923b108 | ||
|
|
f459beccdb | ||
|
|
751c5a3245 | ||
|
|
8488499da6 | ||
|
|
96a7e3c425 | ||
|
|
0dcf510466 | ||
|
|
0427b12d52 | ||
|
|
9256c66fcc | ||
|
|
706f4e1c4c | ||
|
|
96debcd616 | ||
|
|
07f20e1e0d | ||
|
|
fee2e503bd | ||
|
|
f9f260bbc1 | ||
|
|
61718192ee | ||
|
|
27893f9cdd | ||
|
|
9b0b80ef04 | ||
|
|
3e1c2df4b1 | ||
|
|
fa745410cc | ||
|
|
a427624e8d | ||
|
|
3798ca1e17 | ||
|
|
113120b3ab | ||
|
|
b10ca5b77f | ||
|
|
f10e3d756a | ||
|
|
9608b974ec | ||
|
|
3b6cc9c633 | ||
|
|
5305dd62d1 | ||
|
|
a066190c60 | ||
|
|
cdae8b35f5 | ||
|
|
6ee57315dd | ||
|
|
64f682146d | ||
|
|
36525fbe9d | ||
|
|
8f628f2d45 | ||
|
|
5e84e5b8b6 | ||
|
|
a64878bd00 | ||
|
|
c53fc5eaa3 | ||
|
|
212751c835 | ||
|
|
fe1c6acebb | ||
|
|
ce47bfe018 | ||
|
|
e99df2b69e | ||
|
|
db84d07c38 | ||
|
|
db610cfb4c | ||
|
|
8a768cf933 | ||
|
|
bebf3bbc39 | ||
|
|
8a3dd5472b | ||
|
|
f971533a5b | ||
|
|
a12166c13b | ||
|
|
51624a31e3 | ||
|
|
cdc632e1af | ||
|
|
31f87f647e | ||
|
|
dcd37f71d1 | ||
|
|
4ca286b28e | ||
|
|
62cca1335f | ||
|
|
11a18859fb | ||
|
|
1116a7e125 | ||
|
|
415b315292 | ||
|
|
9818ec2b66 | ||
|
|
95ef061a34 | ||
|
|
aaaf8aa66f | ||
|
|
29965e38d0 | ||
|
|
371d49a213 | ||
|
|
6ed95e145e | ||
|
|
8c025c1173 | ||
|
|
9ce541cc31 | ||
|
|
aa57a4c123 | ||
|
|
58d9deb3b8 | ||
|
|
f0685c4a43 | ||
|
|
484817db08 | ||
|
|
670bf15d31 | ||
|
|
6df1e0fd77 | ||
|
|
ec910cb80f | ||
|
|
372516646d | ||
|
|
72e721b0d3 | ||
|
|
6599093611 | ||
|
|
dceeecf1fe | ||
|
|
ace0b9a3d8 | ||
|
|
7c45c90de9 | ||
|
|
c2a4b5e26a | ||
|
|
feac0ad802 | ||
|
|
60478eba3f | ||
|
|
3639952612 | ||
|
|
c4a654b267 | ||
|
|
ecb31a4d32 | ||
|
|
76f201bb2f | ||
|
|
87799b743c | ||
|
|
b898a7c370 | ||
|
|
f3210e3af2 | ||
|
|
225fd6fd49 | ||
|
|
400d259a60 | ||
|
|
4074ac8578 | ||
|
|
b2e6dd4138 | ||
|
|
b608b42174 | ||
|
|
f603254153 | ||
|
|
c851dd228b | ||
|
|
e97478a21a | ||
|
|
726ebcea3f | ||
|
|
2f969775d8 | ||
|
|
d3b855318c | ||
|
|
95104d3383 | ||
|
|
6860a04e8b | ||
|
|
33c24f8655 | ||
|
|
1fa4b78474 | ||
|
|
b678de7529 | ||
|
|
ab1ed0ff5a | ||
|
|
ad20e5230a |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -18,6 +18,7 @@ local.properties
|
||||
|
||||
# Android Studio
|
||||
.idea/*
|
||||
!.idea/inspectionProfiles/
|
||||
!.idea/runConfigurations/
|
||||
!.idea/codeStyleSettings.xml
|
||||
!.idea/codeStyles
|
||||
|
||||
@@ -1,30 +1,79 @@
|
||||
image: briar/ci-image-android:latest
|
||||
|
||||
stages:
|
||||
- test
|
||||
- optional_tests
|
||||
- check_reproducibility
|
||||
- test
|
||||
- optional_tests
|
||||
- check_reproducibility
|
||||
|
||||
test:
|
||||
stage: test
|
||||
workflow:
|
||||
# when to create a CI pipeline
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
|
||||
when: never # avoids duplicate jobs for branch and MR
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
|
||||
.base-test:
|
||||
before_script:
|
||||
- set -e
|
||||
- export GRADLE_USER_HOME=$PWD/.gradle
|
||||
|
||||
cache:
|
||||
key: "$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- .gradle/wrapper
|
||||
- .gradle/caches
|
||||
|
||||
script:
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom check compileOfficialDebugAndroidTestSources compileScreenshotDebugAndroidTestSources
|
||||
|
||||
after_script:
|
||||
# these file change every time but should not be cached
|
||||
# these file change every time and should not be cached
|
||||
- rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
|
||||
- rm -fr $GRADLE_USER_HOME/caches/*/plugin-resolution/
|
||||
|
||||
test:
|
||||
extends: .base-test
|
||||
stage: test
|
||||
script:
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom compileOfficialDebugAndroidTestSources compileScreenshotDebugAndroidTestSources check
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
when: always
|
||||
- when: always
|
||||
|
||||
android test:
|
||||
extends: .base-test
|
||||
stage: optional_tests
|
||||
image: briar/ci-image-android-emulator:latest
|
||||
script:
|
||||
# start emulator first, so it can fail early
|
||||
- start-emulator.sh
|
||||
# run normal and screenshot tests together (exclude Large tests)
|
||||
- ./gradlew -Djava.security.egd=file:/dev/urandom connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.package=org.briarproject.briar.android -Pandroid.testInstrumentationRunnerArguments.notAnnotation=androidx.test.filters.LargeTest
|
||||
after_script:
|
||||
- adb pull /sdcard/Pictures/screenshots
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_PATH}_${CI_JOB_STAGE}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
|
||||
paths:
|
||||
- kernel.log
|
||||
- logcat.txt
|
||||
- briar-android/build/reports/androidTests/connected/flavors/*
|
||||
- screenshots
|
||||
expire_in: 3 days
|
||||
when: on_failure
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
when: on_success
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- briar-android/**/*
|
||||
when: manual
|
||||
allow_failure: true
|
||||
- if: '$CI_COMMIT_TAG == null'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
retry:
|
||||
max: 1
|
||||
tags:
|
||||
- kvm
|
||||
|
||||
test_reproducible:
|
||||
stage: check_reproducibility
|
||||
@@ -40,6 +89,7 @@ test_reproducible:
|
||||
- export GRADLE_USER_HOME=$PWD/.gradle
|
||||
|
||||
cache:
|
||||
key: "$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- .gradle/wrapper
|
||||
- .gradle/caches
|
||||
@@ -52,11 +102,15 @@ test_reproducible:
|
||||
- rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
|
||||
- rm -fr $GRADLE_USER_HOME/caches/*/plugin-resolution/
|
||||
|
||||
manual_tests:
|
||||
bridge test:
|
||||
extends: .optional_tests
|
||||
when: manual
|
||||
except:
|
||||
- tags
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
when: on_success
|
||||
allow_failure: true
|
||||
- if: '$CI_COMMIT_TAG == null'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
|
||||
pre_release_tests:
|
||||
extends: .optional_tests
|
||||
|
||||
35
.gitlab/issue_templates/bug_report.md
Normal file
35
.gitlab/issue_templates/bug_report.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Summary
|
||||
|
||||
(Briefly describe the bug encontered)
|
||||
|
||||
# Steps to reproduce
|
||||
|
||||
(Please list the steps you performed when you encountered the bug)
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
# How often does it happen?
|
||||
|
||||
(Every time, Sometimes, It happened only once)
|
||||
|
||||
# What did you expect to happen
|
||||
|
||||
(Describe the app behaviour that you expected to happen)
|
||||
|
||||
# What actually happened?
|
||||
|
||||
(Describe what actually happened)
|
||||
|
||||
* What version of Briar app do you have installed? [Please fill in]
|
||||
* Did you send the feedback from your device? [Yes/No]
|
||||
* Your device manufacturer: [Please fill in]
|
||||
* Your device model: [Please fill in]
|
||||
* Android version: [Please fill in]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
15
.gitlab/issue_templates/feature_request
Normal file
15
.gitlab/issue_templates/feature_request
Normal file
@@ -0,0 +1,15 @@
|
||||
# Are you requesting a new feature or an improvement to an existing feature?
|
||||
|
||||
# Brief description of the new or improved feature you would like to see in the Briar app
|
||||
|
||||
|
||||
# Please describe in detail what you would like to do in Briar app, for which a new or improved feature is required?
|
||||
|
||||
|
||||
* Does the absence of this feature prevent you from using the Briar app for certain activities? What are those activities?
|
||||
|
||||
* Would your use of Briar app increase with this new feature?
|
||||
|
||||
|
||||
|
||||
|
||||
9
.idea/codeStyles/Project.xml
generated
9
.idea/codeStyles/Project.xml
generated
@@ -31,6 +31,15 @@
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
|
||||
1
.idea/dictionaries/briar.xml
generated
1
.idea/dictionaries/briar.xml
generated
@@ -7,6 +7,7 @@
|
||||
<w>encrypter</w>
|
||||
<w>identicon</w>
|
||||
<w>introducee</w>
|
||||
<w>introducees</w>
|
||||
<w>introducer</w>
|
||||
<w>onboarding</w>
|
||||
</words>
|
||||
|
||||
14
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
14
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="MissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoreObjectMethods" value="true" />
|
||||
<option name="ignoreAnonymousClassMethods" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
|
||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="true" />
|
||||
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
51
.idea/runConfigurations/Instrumentation_Tests__destroys_DB_.xml
generated
Normal file
51
.idea/runConfigurations/Instrumentation_Tests__destroys_DB_.xml
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Instrumentation Tests (destroys DB)" type="AndroidTestRunConfigurationType" factoryName="Android Instrumented Tests">
|
||||
<module name="briar.briar-android" />
|
||||
<option name="TESTING_TYPE" value="1" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="CLASS_NAME" value="" />
|
||||
<option name="PACKAGE_NAME" value="org.briarproject.briar.android" />
|
||||
<option name="INSTRUMENTATION_RUNNER_CLASS" value="" />
|
||||
<option name="EXTRA_OPTIONS" value="-e notAnnotation androidx.test.filters.LargeTest" />
|
||||
<option name="INCLUDE_GRADLE_EXTRA_OPTIONS" value="true" />
|
||||
<option name="CLEAR_LOGCAT" value="false" />
|
||||
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
|
||||
<option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
|
||||
<option name="FORCE_STOP_RUNNING_APP" value="true" />
|
||||
<option name="TARGET_SELECTION_MODE" value="DEVICE_AND_SNAPSHOT_COMBO_BOX" />
|
||||
<option name="DEBUGGER_TYPE" value="Auto" />
|
||||
<Auto>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Auto>
|
||||
<Hybrid>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Hybrid>
|
||||
<Java />
|
||||
<Native>
|
||||
<option name="USE_JAVA_AWARE_DEBUGGER" value="false" />
|
||||
<option name="SHOW_STATIC_VARS" value="true" />
|
||||
<option name="WORKING_DIR" value="" />
|
||||
<option name="TARGET_LOGGING_CHANNELS" value="lldb process:gdb-remote packets" />
|
||||
<option name="SHOW_OPTIMIZED_WARNING" value="true" />
|
||||
</Native>
|
||||
<Profilers>
|
||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
||||
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Sample Java Methods" />
|
||||
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
|
||||
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
|
||||
</Profilers>
|
||||
<method v="2">
|
||||
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
29
README.md
29
README.md
@@ -1 +1,28 @@
|
||||
Briar is a messaging app designed for activists, journalists, and anyone else who needs a safe, easy and robust way to communicate. Unlike traditional messaging tools such as email, Twitter or Telegram, Briar doesn't rely on a central server - messages are synchronized directly between the users' devices. If the Internet's down, Briar can sync via Bluetooth or Wi-Fi, keeping the information flowing in a crisis. If the Internet's up, Briar can sync via the Tor network, protecting users and their relationships from surveillance.
|
||||
# Briar
|
||||
Briar is a messaging app designed for activists, journalists, and anyone else who needs a safe, easy and robust way to communicate.
|
||||
|
||||
Unlike traditional messaging tools such as email, Twitter or Telegram, Briar doesn't rely on a central server - messages are synchronized directly between the users' devices.
|
||||
|
||||
If the Internet's down, Briar can sync via Bluetooth or Wi-Fi, keeping information flowing in a crisis. If the Internet's up, Briar can sync via the Tor network, protecting users and their relationships from surveillance.
|
||||
|
||||
## Download Briar
|
||||
|
||||
[<img src="https://briarproject.org//img/fdroid_badge.png" width="240">](https://briarproject.org/fdroid)
|
||||
[<img src="https://briarproject.org/img/google_play_badge_web_generic.png" width="240">](https://play.google.com/store/apps/details?id=org.briarproject.briar.android)
|
||||
|
||||
You can also [download the APK file](https://briarproject.org/apk) directly from
|
||||
our site.
|
||||
|
||||
## Useful links
|
||||
[briarproject.org](https://briarproject.org/)
|
||||
|
||||
[Source code](https://code.briarproject.org/briar/briar/tree/master)
|
||||
|
||||
[Manual](https://briarproject.org/manual/)
|
||||
|
||||
[Wiki](https://code.briarproject.org/briar/briar/-/wikis/home)
|
||||
|
||||
## Donate
|
||||
|
||||
[](https://liberapay.com/Briar/donate) [](https://flattr.com/t/592836/)
|
||||
Bitcoin and BCH: 1NZCKkUCtJV2U2Y9hDb9uq8S7ksFCFGR6K
|
||||
|
||||
@@ -6,7 +6,7 @@ apply from: 'witness.gradle'
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion '30.0.2'
|
||||
buildToolsVersion '30.0.3'
|
||||
|
||||
packagingOptions {
|
||||
doNotStrip '**/*.so'
|
||||
@@ -14,9 +14,9 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
versionCode 10218
|
||||
versionName "1.2.18"
|
||||
targetSdkVersion 30
|
||||
versionCode 10306
|
||||
versionName "1.3.6"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -42,10 +42,10 @@ configurations {
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
tor 'org.briarproject:tor-android:0.3.5.13@zip'
|
||||
tor 'org.briarproject:tor-android:0.3.5.15'
|
||||
tor 'org.briarproject:obfs4proxy-android:0.0.12-dev-40245c4a@zip'
|
||||
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
|
||||
@@ -53,7 +53,7 @@ dependencies {
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-imposters:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-legacy:$jmock_version"
|
||||
}
|
||||
|
||||
def torBinariesDir = 'src/main/res/raw'
|
||||
|
||||
@@ -59,8 +59,8 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
class AndroidBluetoothPlugin
|
||||
extends BluetoothPlugin<BluetoothSocket, BluetoothServerSocket> {
|
||||
class AndroidBluetoothPlugin extends
|
||||
AbstractBluetoothPlugin<BluetoothSocket, BluetoothServerSocket> {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(AndroidBluetoothPlugin.class.getName());
|
||||
@@ -75,6 +75,7 @@ class AndroidBluetoothPlugin
|
||||
|
||||
// Non-null if the plugin started successfully
|
||||
private volatile BluetoothAdapter adapter = null;
|
||||
private volatile boolean stopDiscoverAndConnect;
|
||||
|
||||
AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
|
||||
BluetoothConnectionFactory<BluetoothSocket> connectionFactory,
|
||||
@@ -86,7 +87,7 @@ class AndroidBluetoothPlugin
|
||||
Clock clock,
|
||||
Backoff backoff,
|
||||
PluginCallback callback,
|
||||
int maxLatency,
|
||||
long maxLatency,
|
||||
int maxIdleTime) {
|
||||
super(connectionLimiter, connectionFactory, ioExecutor,
|
||||
wakefulIoExecutor, secureRandom, backoff, callback,
|
||||
@@ -187,22 +188,40 @@ class AndroidBluetoothPlugin
|
||||
@Nullable
|
||||
DuplexTransportConnection discoverAndConnect(String uuid) {
|
||||
if (adapter == null) return null;
|
||||
for (String address : discoverDevices()) {
|
||||
try {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Connecting to " + scrubMacAddress(address));
|
||||
return connectTo(address, uuid);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Could not connect to "
|
||||
+ scrubMacAddress(address));
|
||||
if (!discoverSemaphore.tryAcquire()) {
|
||||
LOG.info("Discover already running");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
stopDiscoverAndConnect = false;
|
||||
for (String address : discoverDevices()) {
|
||||
if (stopDiscoverAndConnect) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Connecting to " + scrubMacAddress(address));
|
||||
return connectTo(address, uuid);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Could not connect to "
|
||||
+ scrubMacAddress(address));
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
discoverSemaphore.release();
|
||||
}
|
||||
LOG.info("Could not connect to any devices");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopDiscoverAndConnect() {
|
||||
stopDiscoverAndConnect = true;
|
||||
adapter.cancelDiscovery();
|
||||
}
|
||||
|
||||
private Collection<String> discoverDevices() {
|
||||
List<String> addresses = new ArrayList<>();
|
||||
BlockingQueue<Intent> intents = new LinkedBlockingQueue<>();
|
||||
|
||||
@@ -47,7 +47,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
||||
private final BackoffFactory backoffFactory;
|
||||
|
||||
@Inject
|
||||
public AndroidBluetoothPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
AndroidBluetoothPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
@WakefulIoExecutor Executor wakefulIoExecutor,
|
||||
AndroidExecutor androidExecutor,
|
||||
AndroidWakeLockManager wakeLockManager,
|
||||
@@ -75,7 +75,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLatency() {
|
||||
public long getMaxLatency() {
|
||||
return MAX_LATENCY;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.briarproject.bramble.plugin.file;
|
||||
|
||||
import android.app.Application;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.PROP_URI;
|
||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class AndroidRemovableDrivePlugin extends RemovableDrivePlugin {
|
||||
|
||||
private final Application app;
|
||||
|
||||
AndroidRemovableDrivePlugin(Application app, PluginCallback callback,
|
||||
long maxLatency) {
|
||||
super(callback, maxLatency);
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
@Override
|
||||
InputStream openInputStream(TransportProperties p) throws IOException {
|
||||
String uri = p.get(PROP_URI);
|
||||
if (isNullOrEmpty(uri)) throw new IllegalArgumentException();
|
||||
return app.getContentResolver().openInputStream(Uri.parse(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
OutputStream openOutputStream(TransportProperties p) throws IOException {
|
||||
String uri = p.get(PROP_URI);
|
||||
if (isNullOrEmpty(uri)) throw new IllegalArgumentException();
|
||||
return app.getContentResolver().openOutputStream(Uri.parse(uri));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.briarproject.bramble.plugin.file;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin;
|
||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
import static org.briarproject.bramble.api.plugin.file.RemovableDriveConstants.ID;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class AndroidRemovableDrivePluginFactory implements
|
||||
SimplexPluginFactory {
|
||||
|
||||
private static final long MAX_LATENCY = DAYS.toMillis(28);
|
||||
|
||||
private final Application app;
|
||||
|
||||
@Inject
|
||||
AndroidRemovableDrivePluginFactory(Application app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportId getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxLatency() {
|
||||
return MAX_LATENCY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SimplexPlugin createPlugin(PluginCallback callback) {
|
||||
return new AndroidRemovableDrivePlugin(app, callback, MAX_LATENCY);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.net.SocketFactory;
|
||||
@@ -48,6 +49,7 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.NetworkUtils.getNetworkInterfaces;
|
||||
|
||||
@NotNullByDefault
|
||||
class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
@@ -55,6 +57,13 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
private static final Logger LOG =
|
||||
getLogger(AndroidLanTcpPlugin.class.getName());
|
||||
|
||||
/**
|
||||
* The interface name is used as a heuristic for deciding whether the
|
||||
* device is providing a wifi access point.
|
||||
*/
|
||||
private static final Pattern AP_INTERFACE_NAME =
|
||||
Pattern.compile("^(wlan|ap|p2p)[-0-9]");
|
||||
|
||||
private final Executor connectionStatusExecutor;
|
||||
private final ConnectivityManager connectivityManager;
|
||||
@Nullable
|
||||
@@ -67,7 +76,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
Application app,
|
||||
Backoff backoff,
|
||||
PluginCallback callback,
|
||||
int maxLatency,
|
||||
long maxLatency,
|
||||
int maxIdleTime,
|
||||
int connectionTimeout) {
|
||||
super(ioExecutor, wakefulIoExecutor, backoff, callback, maxLatency,
|
||||
@@ -130,17 +139,14 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
if (info != null && info.getIpAddress() != 0) {
|
||||
return new Pair<>(intToInetAddress(info.getIpAddress()), false);
|
||||
}
|
||||
List<InterfaceAddress> ifAddrs = getLocalInterfaceAddresses();
|
||||
// If we're providing a normal access point, return its address
|
||||
for (InterfaceAddress ifAddr : ifAddrs) {
|
||||
if (isAndroidWifiApAddress(ifAddr)) {
|
||||
return new Pair<>(ifAddr.getAddress(), true);
|
||||
}
|
||||
}
|
||||
// If we're providing a wifi direct access point, return its address
|
||||
for (InterfaceAddress ifAddr : ifAddrs) {
|
||||
if (isAndroidWifiDirectApAddress(ifAddr)) {
|
||||
return new Pair<>(ifAddr.getAddress(), true);
|
||||
// If we're providing an access point, return its address
|
||||
for (NetworkInterface iface : getNetworkInterfaces()) {
|
||||
if (AP_INTERFACE_NAME.matcher(iface.getName()).find()) {
|
||||
for (InterfaceAddress ifAddr : iface.getInterfaceAddresses()) {
|
||||
if (isPossibleWifiApInterface(ifAddr)) {
|
||||
return new Pair<>(ifAddr.getAddress(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Not connected to wifi
|
||||
@@ -148,33 +154,18 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given address belongs to a network provided by an
|
||||
* Android access point (including the access point's own address).
|
||||
* Returns true if the given address may belong to an interface providing
|
||||
* a wifi access point (including wifi direct legacy mode access points).
|
||||
* <p>
|
||||
* The access point's address is usually 192.168.43.1, but at least one
|
||||
* device (Honor 8A) may use other addresses in the range 192.168.43.0/24.
|
||||
* This method may return true for wifi client interfaces as well, but
|
||||
* we've already checked for a wifi client connection above.
|
||||
*/
|
||||
private boolean isAndroidWifiApAddress(InterfaceAddress ifAddr) {
|
||||
private boolean isPossibleWifiApInterface(InterfaceAddress ifAddr) {
|
||||
if (ifAddr.getNetworkPrefixLength() != 24) return false;
|
||||
byte[] ip = ifAddr.getAddress().getAddress();
|
||||
return ip.length == 4
|
||||
&& ip[0] == (byte) 192
|
||||
&& ip[1] == (byte) 168
|
||||
&& ip[2] == (byte) 43;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given address belongs to a network provided by an
|
||||
* Android wifi direct legacy mode access point (including the access
|
||||
* point's own address).
|
||||
*/
|
||||
private boolean isAndroidWifiDirectApAddress(InterfaceAddress ifAddr) {
|
||||
if (ifAddr.getNetworkPrefixLength() != 24) return false;
|
||||
byte[] ip = ifAddr.getAddress().getAddress();
|
||||
return ip.length == 4
|
||||
&& ip[0] == (byte) 192
|
||||
&& ip[1] == (byte) 168
|
||||
&& ip[2] == (byte) 49;
|
||||
&& ip[1] == (byte) 168;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,7 +37,7 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
||||
private final Application app;
|
||||
|
||||
@Inject
|
||||
public AndroidLanTcpPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
AndroidLanTcpPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
@WakefulIoExecutor Executor wakefulIoExecutor,
|
||||
EventBus eventBus,
|
||||
BackoffFactory backoffFactory,
|
||||
@@ -55,7 +55,7 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLatency() {
|
||||
public long getMaxLatency() {
|
||||
return MAX_LATENCY;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class AndroidTorPlugin extends TorPlugin {
|
||||
TorRendezvousCrypto torRendezvousCrypto,
|
||||
PluginCallback callback,
|
||||
String architecture,
|
||||
int maxLatency,
|
||||
long maxLatency,
|
||||
int maxIdleTime,
|
||||
File torDirectory) {
|
||||
super(ioExecutor, wakefulIoExecutor, networkManager, locationUtils,
|
||||
|
||||
@@ -58,7 +58,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
private final File torDirectory;
|
||||
|
||||
@Inject
|
||||
public AndroidTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
AndroidTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
@WakefulIoExecutor Executor wakefulIoExecutor,
|
||||
Application app,
|
||||
NetworkManager networkManager,
|
||||
@@ -94,7 +94,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLatency() {
|
||||
public long getMaxLatency() {
|
||||
return MAX_LATENCY;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,17 +10,20 @@ import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static java.lang.Runtime.getRuntime;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
|
||||
@@ -118,4 +121,17 @@ public class AndroidUtils {
|
||||
public static String[] getSupportedImageContentTypes() {
|
||||
return new String[] {"image/jpeg", "image/png", "image/gif"};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getSystemProperty(String propName) {
|
||||
try {
|
||||
Process p = getRuntime().exec("getprop " + propName);
|
||||
Scanner s = new Scanner(p.getInputStream());
|
||||
String line = s.nextLine();
|
||||
s.close();
|
||||
return line;
|
||||
} catch (SecurityException | IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.imposters.ByteBuddyClassImposteriser;
|
||||
import org.jmock.lib.legacy.ClassImposteriser;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -44,7 +44,7 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
|
||||
private AndroidAccountManager accountManager;
|
||||
|
||||
public AndroidAccountManagerTest() {
|
||||
context.setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
app = context.mock(Application.class);
|
||||
applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.dataDir = testDir.getAbsolutePath();
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||
'com.android.tools.analytics-library:protos:27.1.1:protos-27.1.1.jar:13f77e73762e58ab372d140b3a6be6903aea9775b62dd14fbc62d4cc7069c9a4',
|
||||
'com.android.tools.analytics-library:shared:27.1.1:shared-27.1.1.jar:82930a52001410e97d809930b670f4de3002286975f046b9de5f6b777b06d366',
|
||||
'com.android.tools.analytics-library:tracker:27.1.1:tracker-27.1.1.jar:31bc5a00be0055bac89c9b2f34751883e987cd89e3ac1783720645c164f591d9',
|
||||
'com.android.tools.analytics-library:protos:27.1.3:protos-27.1.3.jar:0d9e6cff60b318baac250b6f5bb076a8161103338bf2749cdf1db8a5a13a1f12',
|
||||
'com.android.tools.analytics-library:shared:27.1.3:shared-27.1.3.jar:10d2a51d8f89ff4ac849888e5a9c60b10e879c30d78545ec1da4d3df7bd56ae4',
|
||||
'com.android.tools.analytics-library:tracker:27.1.3:tracker-27.1.3.jar:589b355a2ba796cbc0a2b2295737de6661f078262e5f87cd6f540b8d011e5ebb',
|
||||
'com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524:aapt2-proto-4.1.0-alpha01-6193524.jar:17e75523e1e92dd4f222c7368ee41df9e964a508232f591e265d0c499baf9dca',
|
||||
'com.android.tools.build:apksig:4.1.1:apksig-4.1.1.jar:e0a69da9e5a03986d608b45bbf954ef0e6a0b3f58c1b8315bd169ec08b279e72',
|
||||
'com.android.tools.build:apkzlib:4.1.1:apkzlib-4.1.1.jar:ba4b5e419b6be0130eae7f8301c3a551ad3976f487d2e0c6852ebb175ac41127',
|
||||
'com.android.tools.build:builder-model:4.1.1:builder-model-4.1.1.jar:e95c99cc298ad67b8deb6ced99c51abc8f59afebedad044b1a10dde14646a4dd',
|
||||
'com.android.tools.build:builder-test-api:4.1.1:builder-test-api-4.1.1.jar:464f596ab261c051c3847406748e843770dea123f6fa5fee8a9390644e709b7a',
|
||||
'com.android.tools.build:builder:4.1.1:builder-4.1.1.jar:0f78d4759d2f7b57b95865522ec34596ba419b9982f3b25e3449213f9c98b80d',
|
||||
'com.android.tools.build:gradle-api:4.1.1:gradle-api-4.1.1.jar:d42e6b539e4c1353ad3546e75ec8ce11a017b97481023e8ea18577eefe374358',
|
||||
'com.android.tools.build:manifest-merger:27.1.1:manifest-merger-27.1.1.jar:7a45fa143687859bb2e5a961dcf6ee88094d3853de0cb543dc03dbcb0f4b554b',
|
||||
'com.android.tools.ddms:ddmlib:27.1.1:ddmlib-27.1.1.jar:da6e4bd834b6a85dae8019039849d8bd96933347dfbf460df74913ddade6e40a',
|
||||
'com.android.tools.external.com-intellij:intellij-core:27.1.1:intellij-core-27.1.1.jar:2591a7363c4443c59bf9f793730acafce9d6ec3076e2f46716edaf53a41b6fb6',
|
||||
'com.android.tools.external.com-intellij:kotlin-compiler:27.1.1:kotlin-compiler-27.1.1.jar:5054ae770ba788f110303c65abd6b1fa28eccf52dee1274510e201b2b81885c8',
|
||||
'com.android.tools.external.org-jetbrains:uast:27.1.1:uast-27.1.1.jar:54cd8f6886a9d2f5641659dd5c91f626629672cd48301f7f0bd6aad9bd448714',
|
||||
'com.android.tools.layoutlib:layoutlib-api:27.1.1:layoutlib-api-27.1.1.jar:8a9a22e3b309521ea83b724e5a89cfdac6076f52d675c0e17d77b05527bc0f8c',
|
||||
'com.android.tools.lint:lint-api:27.1.1:lint-api-27.1.1.jar:c1d8176094cb0478786070d40533efb578ebc53529a82f6ef5bee879bdca418b',
|
||||
'com.android.tools.lint:lint-checks:27.1.1:lint-checks-27.1.1.jar:3899c91e00bd059b40c31a9ca00cd0f8303191947608735ae1b657323693fb61',
|
||||
'com.android.tools.lint:lint-gradle-api:27.1.1:lint-gradle-api-27.1.1.jar:26aa89d38b9825cc73229daa82a68875801c8b8491f30497ce62aff1f206eb0d',
|
||||
'com.android.tools.lint:lint-gradle:27.1.1:lint-gradle-27.1.1.jar:f7355823ead869f4d28184ba28b7a0c693b507519a2d3705bb9848a0f35b3756',
|
||||
'com.android.tools.lint:lint-model:27.1.1:lint-model-27.1.1.jar:bc23c0c413bdfca59dac2cd56b870d8360d009e9ec0d365e71f774bcf127971d',
|
||||
'com.android.tools.lint:lint:27.1.1:lint-27.1.1.jar:2f6038a5398a42bd591883c3f5e5894f4ec52ca1c3683bf94fa8553c1700af81',
|
||||
'com.android.tools:annotations:27.1.1:annotations-27.1.1.jar:ff28c504d2acb9fd1a5ffbd97ae85cf59ee18c76927525aad250509bccf2cab1',
|
||||
'com.android.tools:common:27.1.1:common-27.1.1.jar:63d9a2a9ad6d278db319f3749b9f50bdf5457ef7020074a1bebe124e714b535c',
|
||||
'com.android.tools:dvlib:27.1.1:dvlib-27.1.1.jar:998a54201fc1cefee5f2399215e95c42b1f64f9e1d8f4452eb8255c68ba5440f',
|
||||
'com.android.tools:repository:27.1.1:repository-27.1.1.jar:d25b74ccabf4d876903efb375e9af6fb380d8ae0445bb74bbdcc225c1e37fa1d',
|
||||
'com.android.tools:sdk-common:27.1.1:sdk-common-27.1.1.jar:4473ae97d0ef7061ee1de61041d5aa97405ae08e44c09cf7bb278b42e4b97c7c',
|
||||
'com.android.tools:sdklib:27.1.1:sdklib-27.1.1.jar:08e6b83961ac9724b3c1e3d0eff971f13be6701292c77914b8794480f3391250',
|
||||
'com.android:signflinger:4.1.1:signflinger-4.1.1.jar:0c66825988873ec2d51057fa463f54a8f18fc7326ff4530b9da363b71e97ce60',
|
||||
'com.android:zipflinger:4.1.1:zipflinger-4.1.1.jar:0a8c3e52ac13dd031236f9fb5ba4408b1d5dcd12325a05440b36da09d8881446',
|
||||
'com.android.tools.build:apksig:4.1.3:apksig-4.1.3.jar:a851980c678ff7a6785388b9a9e8cc094788ce3c4a985ad2b19c2028fd3c631a',
|
||||
'com.android.tools.build:apkzlib:4.1.3:apkzlib-4.1.3.jar:475903065e7e83a8c1ba78d267c97a54dc5a04d768b535093850423d7b11f2c8',
|
||||
'com.android.tools.build:builder-model:4.1.3:builder-model-4.1.3.jar:2624a1436c3ab39dd91d3ecf9409a594b0f89ea5cab255f2e9ff11f5ee03d274',
|
||||
'com.android.tools.build:builder-test-api:4.1.3:builder-test-api-4.1.3.jar:3d2af66726b06b53b8d6d497efcee39ff9f77eb2f8d2cce38b31502383a40d2c',
|
||||
'com.android.tools.build:builder:4.1.3:builder-4.1.3.jar:a40426cd6d68f6a722ef4950058c075e4547025e8c2fd78e732ad89f15176f84',
|
||||
'com.android.tools.build:gradle-api:4.1.3:gradle-api-4.1.3.jar:11b1fb9de658bdcf9290b1c1517060d0c4d93f2b27975934989ca4ac890bc077',
|
||||
'com.android.tools.build:manifest-merger:27.1.3:manifest-merger-27.1.3.jar:ce8d4009b1f1584777a7ffa1da3b0551dc316bc8e08112e442c352af70f46f2d',
|
||||
'com.android.tools.ddms:ddmlib:27.1.3:ddmlib-27.1.3.jar:8f76e8236d2b9eebf26378746dad025c4c7c056a02e133dae4ddef47b283c710',
|
||||
'com.android.tools.external.com-intellij:intellij-core:27.1.3:intellij-core-27.1.3.jar:652814fa099b4746fb6f10e19718e476952e8b5bac24e17d914f90650ad21808',
|
||||
'com.android.tools.external.com-intellij:kotlin-compiler:27.1.3:kotlin-compiler-27.1.3.jar:8d7a78d5efd213c5e467e42bd205582aad73ffc77ee5dc18eb1361c9af72f125',
|
||||
'com.android.tools.external.org-jetbrains:uast:27.1.3:uast-27.1.3.jar:aea53944a1ac6a05f12297b55290e8cbecfe54c4166260cfba4405823bfe1c78',
|
||||
'com.android.tools.layoutlib:layoutlib-api:27.1.3:layoutlib-api-27.1.3.jar:23875ce0a8429f33a4e86cc358f658faa0ba9c576f5f05760e544b453d67d04b',
|
||||
'com.android.tools.lint:lint-api:27.1.3:lint-api-27.1.3.jar:97666be32bcadacd944416ea334a9575ef8f4ad0c8f333151491ff4a7df43e1c',
|
||||
'com.android.tools.lint:lint-checks:27.1.3:lint-checks-27.1.3.jar:b2d71ae84a31490fe9ff26c706163fe245b2aea98e3eb747214c1085df444708',
|
||||
'com.android.tools.lint:lint-gradle-api:27.1.3:lint-gradle-api-27.1.3.jar:e54131c287a2954e6ed78a3351e5e10e35a1da2f09ac443bf44b705c71b63a4d',
|
||||
'com.android.tools.lint:lint-gradle:27.1.3:lint-gradle-27.1.3.jar:6a79e48943649d63665db7b17dbaff7af93e94ab9b15072f1a4d90486294ee9f',
|
||||
'com.android.tools.lint:lint-model:27.1.3:lint-model-27.1.3.jar:acb9e792db7000e38e3c3ca21a9b14f2de6549d7a3fc92a97ffba3d06345e5bf',
|
||||
'com.android.tools.lint:lint:27.1.3:lint-27.1.3.jar:5a2e69d0901a3a476a5b2d5001de755868113145f5f6aa557750cfad5389a44b',
|
||||
'com.android.tools:annotations:27.1.3:annotations-27.1.3.jar:904dd771883496d5dfc86619ab2555968ea4e8a29d7a5f4f7cae6fbf5429f8f5',
|
||||
'com.android.tools:common:27.1.3:common-27.1.3.jar:17ab4728e3ea50f047dd5937f0faf35f2c5416962ed74891057087ddc328bf96',
|
||||
'com.android.tools:dvlib:27.1.3:dvlib-27.1.3.jar:cead1c0c356cbe43e6855b0330fe09ef4bec2c72e22bdb4c6e7cf7e6b1dfbc37',
|
||||
'com.android.tools:repository:27.1.3:repository-27.1.3.jar:99de1a178855b56b8cd91a56296f1e0a9399c445e6acc51f1d2927947cc472cb',
|
||||
'com.android.tools:sdk-common:27.1.3:sdk-common-27.1.3.jar:b591e2aa0f1be600795f5c9e2bf81cba9b052bee452fc86c3362b5dd9e427a14',
|
||||
'com.android.tools:sdklib:27.1.3:sdklib-27.1.3.jar:ad6c08a45fe2904d05656bdddf9f623fa5c1d16bbd7b8d6a270a0734136ae02e',
|
||||
'com.android:signflinger:4.1.3:signflinger-4.1.3.jar:f3103b55ccdc8dd9ee2517eb26af93b904d41303726594372d0df59d51156e5c',
|
||||
'com.android:zipflinger:4.1.3:zipflinger-4.1.3.jar:48569896c0497268308a8014c66eb0f2bace2b9e2fc9390f3012823fb86387d5',
|
||||
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
|
||||
'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.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.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e',
|
||||
'com.google.dagger:dagger-producers:2.33:dagger-producers-2.33.jar:5897f0b6eef799c2adfe3ccacc58c0fb374d58acb063c3ebe5366c38a8bce5c8',
|
||||
'com.google.dagger:dagger-spi:2.33:dagger-spi-2.33.jar:e2dcab2221b8afb9556ef0a1c83b0bd5f42552e254322a257330f754cdbbb9d4',
|
||||
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
|
||||
'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:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
@@ -51,7 +51,7 @@ dependencyVerification {
|
||||
'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
|
||||
'com.google.protobuf:protobuf-java:3.10.0:protobuf-java-3.10.0.jar:161d7d61a8cb3970891c299578702fd079646e032329d6c2cabf998d191437c9',
|
||||
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
|
||||
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
|
||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
|
||||
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
||||
'com.sun.istack:istack-commons-runtime:3.0.7:istack-commons-runtime-3.0.7.jar:6443e10ba2e259fb821d9b6becf10db5316285fc30c53cec9d7b19a3877e7fdf',
|
||||
@@ -63,7 +63,7 @@ dependencyVerification {
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'javax.xml.bind:jaxb-api:2.3.1:jaxb-api-2.3.1.jar:88b955a0df57880a26a74708bc34f74dcaf8ebf4e78843a28b50eae945732b06',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
|
||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
@@ -77,7 +77,7 @@ dependencyVerification {
|
||||
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
||||
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
||||
'org.briarproject:obfs4proxy-android:0.0.12-dev-40245c4a:obfs4proxy-android-0.0.12-dev-40245c4a.zip:8ab05a8f8391be2cb5ab2b665c281a06d9e3a756bd0f95a40a36ca927866ea82',
|
||||
'org.briarproject:tor-android:0.3.5.13:tor-android-0.3.5.13.zip:e0978db136731dae07774b722970cdae1e462fb5adc82845dd80a7e2d87f356c',
|
||||
'org.briarproject:tor-android:0.3.5.15:tor-android-0.3.5.15.jar:560c5070166300b396cb2f28d82d9f639ee1fb5479096a3cef67da56d39937ad',
|
||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||
'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',
|
||||
@@ -91,9 +91,12 @@ dependencyVerification {
|
||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||
'org.jetbrains.kotlin:kotlin-reflect:1.3.72:kotlin-reflect-1.3.72.jar:a188d9367de1c4ee9479db630985c0597b20709c83161b1430d24edb27e38c40',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72:kotlin-stdlib-common-1.3.72.jar:5e7d1552863e480c1628b1cc39ce230ef829f5b7230106215a05acda5172203a',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72:kotlin-stdlib-jdk7-1.3.72.jar:40566c0c08d414b9413ba556ff7f8a0b04b98b9f0f424d122dd2088510efccc4',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72:kotlin-stdlib-jdk8-1.3.72.jar:133da70cfc07b56094282eac5c59bccd59f167ee2ead22e5282876d8bc10bf95',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.3.72:kotlin-stdlib-1.3.72.jar:3856a7349ebacd6d1be6802b2fed9c4dc2c5a564ea92b6b945ac988243d4b16b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656',
|
||||
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5',
|
||||
'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7',
|
||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
|
||||
|
||||
@@ -7,12 +7,13 @@ apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
|
||||
dependencies {
|
||||
implementation "com.google.dagger:dagger:2.24"
|
||||
implementation "com.google.dagger:dagger:$dagger_version"
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-legacy:$jmock_version"
|
||||
|
||||
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.bramble.api;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface Consumer<T> {
|
||||
|
||||
void accept(T t);
|
||||
}
|
||||
@@ -9,4 +9,11 @@ public interface FeatureFlags {
|
||||
|
||||
boolean shouldEnableProfilePictures();
|
||||
|
||||
boolean shouldEnableDisappearingMessages();
|
||||
|
||||
boolean shouldEnableConnectViaBluetooth();
|
||||
|
||||
boolean shouldEnableTransferData();
|
||||
|
||||
boolean shouldEnableShareAppViaOfflineHotspot();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.api.account;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.DecryptionException;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.identity.Identity;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@@ -44,17 +43,6 @@ public interface AccountManager {
|
||||
*/
|
||||
boolean createAccount(String name, String password);
|
||||
|
||||
/**
|
||||
* Restores a given identity by registering it with the
|
||||
* {@link IdentityManager}. Creates a database key, encrypts it with the
|
||||
* given password and stores it on disk. {@link #accountExists()} will
|
||||
* return true after this method returns true.
|
||||
* @param identity
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
boolean restoreAccount(Identity identity, String password);
|
||||
|
||||
/**
|
||||
* Deletes all account state from disk. {@link #accountExists()} will
|
||||
* return false after this method returns.
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.bramble.api.cleanup;
|
||||
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* An interface for registering a hook with the {@link CleanupManager}
|
||||
* that will be called when a message's cleanup deadline is reached.
|
||||
*/
|
||||
@NotNullByDefault
|
||||
public interface CleanupHook {
|
||||
|
||||
/**
|
||||
* Called when the cleanup deadlines of one or more messages are reached.
|
||||
* <p>
|
||||
* The callee is not required to delete the messages, but the hook won't be
|
||||
* called again for these messages unless another cleanup timer is set (see
|
||||
* {@link DatabaseComponent#setCleanupTimerDuration(Transaction, MessageId, long)}
|
||||
* and {@link DatabaseComponent#startCleanupTimer(Transaction, MessageId)}).
|
||||
*/
|
||||
void deleteMessages(Transaction txn, GroupId g,
|
||||
Collection<MessageId> messageIds) throws DbException;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.bramble.api.cleanup;
|
||||
|
||||
import org.briarproject.bramble.api.cleanup.event.CleanupTimerStartedEvent;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
|
||||
/**
|
||||
* The CleanupManager is responsible for tracking the cleanup deadlines of
|
||||
* messages and passing them to their respective
|
||||
* {@link CleanupHook CleanupHooks} when the deadlines are reached.
|
||||
* <p>
|
||||
* The CleanupManager responds to
|
||||
* {@link CleanupTimerStartedEvent CleanupTimerStartedEvents} broadcast by the
|
||||
* {@link DatabaseComponent}.
|
||||
* <p>
|
||||
* See {@link DatabaseComponent#setCleanupTimerDuration(Transaction, MessageId, long)},
|
||||
* {@link DatabaseComponent#startCleanupTimer(Transaction, MessageId)},
|
||||
* {@link DatabaseComponent#stopCleanupTimer(Transaction, MessageId)}.
|
||||
*/
|
||||
@NotNullByDefault
|
||||
public interface CleanupManager {
|
||||
|
||||
/**
|
||||
* When scheduling a cleanup task we overshoot the deadline by this many
|
||||
* milliseconds to reduce the number of tasks that need to be scheduled
|
||||
* when messages have cleanup deadlines that are close together.
|
||||
*/
|
||||
long BATCH_DELAY_MS = 1000;
|
||||
|
||||
/**
|
||||
* Registers a hook to be called when messages are due for cleanup.
|
||||
* This method should be called before
|
||||
* {@link LifecycleManager#startServices(SecretKey)}.
|
||||
*/
|
||||
void registerCleanupHook(ClientId c, int majorVersion,
|
||||
CleanupHook hook);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.briarproject.bramble.api.cleanup.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when a message's cleanup timer is started.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class CleanupTimerStartedEvent extends Event {
|
||||
|
||||
private final MessageId messageId;
|
||||
private final long cleanupDeadline;
|
||||
|
||||
public CleanupTimerStartedEvent(MessageId messageId,
|
||||
long cleanupDeadline) {
|
||||
this.messageId = messageId;
|
||||
this.cleanupDeadline = cleanupDeadline;
|
||||
}
|
||||
|
||||
public MessageId getMessageId() {
|
||||
return messageId;
|
||||
}
|
||||
|
||||
public long getCleanupDeadline() {
|
||||
return cleanupDeadline;
|
||||
}
|
||||
}
|
||||
@@ -32,28 +32,31 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
|
||||
|
||||
/**
|
||||
* Called once for each incoming message that passes validation.
|
||||
* <p>
|
||||
* If an unexpected exception occurs while handling data that is assumed
|
||||
* to be valid (e.g. locally created metadata), it may be sensible to
|
||||
* rethrow the unexpected exception as a DbException so that delivery is
|
||||
* attempted again at next startup. This will allow delivery to succeed if
|
||||
* the unexpected exception was caused by a bug that has subsequently been
|
||||
* fixed.
|
||||
*
|
||||
* @param txn A read-write transaction
|
||||
* @return Whether or not this message should be shared
|
||||
* @throws DbException Should only be used for real database errors.
|
||||
* If this is thrown, delivery will be attempted again at next startup,
|
||||
* whereas if a FormatException is thrown, the message will be permanently
|
||||
* invalidated.
|
||||
* @throws FormatException Use this for any non-database error
|
||||
* that occurs while handling remotely created data.
|
||||
* This includes errors that occur while handling locally created data
|
||||
* in a context controlled by remotely created data
|
||||
* (for example, parsing the metadata of a dependency
|
||||
* of an incoming message).
|
||||
* Never rethrow DbException as FormatException!
|
||||
* @throws DbException if a database error occurs while delivering the
|
||||
* message. Delivery will be attempted again at next startup. Throwing
|
||||
* this exception has the same effect as returning
|
||||
* {@link DeliveryAction#DEFER}.
|
||||
* @throws FormatException if the message is invalid in the context of its
|
||||
* dependencies. The message and any dependents will be marked as invalid
|
||||
* and deleted along with their metadata. Throwing this exception has the
|
||||
* same effect as returning {@link DeliveryAction#REJECT}.
|
||||
*/
|
||||
protected abstract boolean incomingMessage(Transaction txn, Message m,
|
||||
BdfList body, BdfDictionary meta) throws DbException,
|
||||
FormatException;
|
||||
protected abstract DeliveryAction incomingMessage(Transaction txn,
|
||||
Message m, BdfList body, BdfDictionary meta)
|
||||
throws DbException, FormatException;
|
||||
|
||||
@Override
|
||||
public boolean incomingMessage(Transaction txn, Message m, Metadata meta)
|
||||
throws DbException, InvalidMessageException {
|
||||
public DeliveryAction incomingMessage(Transaction txn, Message m,
|
||||
Metadata meta) throws DbException, InvalidMessageException {
|
||||
try {
|
||||
BdfList body = clientHelper.toList(m);
|
||||
BdfDictionary metaDictionary = metadataParser.parse(meta);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.api.client;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
@@ -16,6 +17,7 @@ import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@NotNullByDefault
|
||||
@@ -50,9 +52,11 @@ public interface ClientHelper {
|
||||
BdfDictionary getGroupMetadataAsDictionary(Transaction txn, GroupId g)
|
||||
throws DbException, FormatException;
|
||||
|
||||
Collection<MessageId> getMessageIds(Transaction txn, GroupId g,
|
||||
BdfDictionary query) throws DbException, FormatException;
|
||||
|
||||
BdfDictionary getMessageMetadataAsDictionary(MessageId m)
|
||||
throws DbException,
|
||||
FormatException;
|
||||
throws DbException, FormatException;
|
||||
|
||||
BdfDictionary getMessageMetadataAsDictionary(Transaction txn, MessageId m)
|
||||
throws DbException, FormatException;
|
||||
@@ -119,4 +123,17 @@ public interface ClientHelper {
|
||||
Map<TransportId, TransportProperties> parseAndValidateTransportPropertiesMap(
|
||||
BdfDictionary properties) throws FormatException;
|
||||
|
||||
/**
|
||||
* Retrieves the contact ID from the group metadata of the given contact
|
||||
* group.
|
||||
*/
|
||||
ContactId getContactId(Transaction txn, GroupId contactGroupId)
|
||||
throws DbException, FormatException;
|
||||
|
||||
/**
|
||||
* Stores the given contact ID in the group metadata of the given contact
|
||||
* group.
|
||||
*/
|
||||
void setContactId(Transaction txn, GroupId contactGroupId, ContactId c)
|
||||
throws DbException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.bramble.api.client;
|
||||
|
||||
public interface ContactGroupConstants {
|
||||
|
||||
/**
|
||||
* Group metadata key for associating a contact ID with a contact group.
|
||||
*/
|
||||
String GROUP_KEY_CONTACT_ID = "contactId";
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.briarproject.bramble.api.contact;
|
||||
|
||||
/**
|
||||
* Record types for the contact exchange protocol.
|
||||
*/
|
||||
public interface ContactExchangeRecordTypes {
|
||||
|
||||
byte CONTACT_INFO = 0;
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.api.contact;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
@@ -49,10 +48,6 @@ public interface ContactManager {
|
||||
SecretKey rootKey, long timestamp, boolean alice, boolean verified,
|
||||
boolean active) throws DbException;
|
||||
|
||||
ContactId addContact(Transaction txn, Author remote, AuthorId local,
|
||||
PublicKey handshake, boolean verified)
|
||||
throws DbException, GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Stores a contact associated with the given local and remote pseudonyms,
|
||||
* replacing the given pending contact, derives and stores handshake mode
|
||||
@@ -210,19 +205,6 @@ public interface ContactManager {
|
||||
void setContactAlias(ContactId c, @Nullable String alias)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the contact's handshake public key
|
||||
*/
|
||||
void setHandshakePublicKey(Transaction txn, ContactId c,
|
||||
PublicKey handshakePublicKey) throws DbException,
|
||||
GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Sets the contact's handshake public key
|
||||
*/
|
||||
void setHandshakePublicKey(ContactId c, PublicKey handshakePublicKey)
|
||||
throws DbException, GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Returns true if a contact with this {@code remoteAuthorId} belongs to
|
||||
* the local pseudonym with this {@code localAuthorId}.
|
||||
|
||||
@@ -24,19 +24,6 @@ public interface HandshakeManager {
|
||||
HandshakeResult handshake(PendingContactId p, InputStream in,
|
||||
StreamWriter out) throws DbException, IOException;
|
||||
|
||||
/**
|
||||
* Handshakes with the given contact. Returns an ephemeral master key
|
||||
* authenticated with both parties' handshake key pairs and a flag
|
||||
* indicating whether the local peer is Alice or Bob.
|
||||
*
|
||||
* @param in An incoming stream for the handshake, which must be secured in
|
||||
* handshake mode
|
||||
* @param out An outgoing stream for the handshake, which must be secured
|
||||
* in handshake mode
|
||||
*/
|
||||
HandshakeResult handshake(ContactId c, InputStream in, StreamWriter out)
|
||||
throws DbException, IOException;
|
||||
|
||||
class HandshakeResult {
|
||||
|
||||
private final SecretKey masterKey;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.briarproject.bramble.api.contact.event;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when the alias for a contact changed.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class ContactAliasChangedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
@Nullable
|
||||
private final String alias;
|
||||
|
||||
public ContactAliasChangedEvent(ContactId contactId,
|
||||
@Nullable String alias) {
|
||||
this.contactId = contactId;
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,19 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
|
||||
/**
|
||||
* A secret key used for encryption and/or authentication.
|
||||
*/
|
||||
public class SecretKey {
|
||||
public class SecretKey extends Bytes {
|
||||
|
||||
/**
|
||||
* The length of a secret key in bytes.
|
||||
*/
|
||||
public static final int LENGTH = 32;
|
||||
|
||||
private final byte[] key;
|
||||
|
||||
public SecretKey(byte[] key) {
|
||||
super(key);
|
||||
if (key.length != LENGTH) throw new IllegalArgumentException();
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,18 @@ import javax.annotation.Nullable;
|
||||
@NotNullByDefault
|
||||
public interface DatabaseComponent extends TransactionManager {
|
||||
|
||||
/**
|
||||
* Return value for {@link #getNextCleanupDeadline(Transaction)} if
|
||||
* no messages are scheduled to be deleted.
|
||||
*/
|
||||
long NO_CLEANUP_DEADLINE = -1;
|
||||
|
||||
/**
|
||||
* Return value for {@link #startCleanupTimer(Transaction, MessageId)}
|
||||
* if the cleanup timer was not started.
|
||||
*/
|
||||
long TIMER_NOT_STARTED = -1;
|
||||
|
||||
/**
|
||||
* Opens the database and returns true if the database already existed.
|
||||
*
|
||||
@@ -89,7 +101,7 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
/**
|
||||
* Stores a transport.
|
||||
*/
|
||||
void addTransport(Transaction txn, TransportId t, int maxLatency)
|
||||
void addTransport(Transaction txn, TransportId t, long maxLatency)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
@@ -106,6 +118,18 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
KeySetId addTransportKeys(Transaction txn, PendingContactId p,
|
||||
TransportKeys k) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if there are any acks or messages to send to the given
|
||||
* contact over a transport with the given maximum latency.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*
|
||||
* @param eager True if messages that are not yet due for retransmission
|
||||
* should be included
|
||||
*/
|
||||
boolean containsAnythingToSend(Transaction txn, ContactId c,
|
||||
long maxLatency, boolean eager) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given contact for the given
|
||||
* local pseudonym.
|
||||
@@ -138,6 +162,16 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
boolean containsPendingContact(Transaction txn, PendingContactId p)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains keys for communicating with the
|
||||
* given contact over the given transport. Handshake mode and rotation mode
|
||||
* keys are included, whether activated or not.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
boolean containsTransportKeys(Transaction txn, ContactId c, TransportId t)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Deletes the message with the given ID. Unlike
|
||||
* {@link #removeMessage(Transaction, MessageId)}, the message ID,
|
||||
@@ -166,7 +200,19 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
*/
|
||||
@Nullable
|
||||
Collection<Message> generateBatch(Transaction txn, ContactId c,
|
||||
int maxLength, int maxLatency) throws DbException;
|
||||
int maxLength, long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a batch of messages for the given contact containing the
|
||||
* messages with the given IDs, for transmission over a transport with
|
||||
* the given maximum latency.
|
||||
* <p/>
|
||||
* If any of the given messages are not in the database or are not visible
|
||||
* to the contact, they are omitted from the batch without throwing an
|
||||
* exception.
|
||||
*/
|
||||
Collection<Message> generateBatch(Transaction txn, ContactId c,
|
||||
Collection<MessageId> ids, long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns an offer for the given contact for transmission over a
|
||||
@@ -175,7 +221,7 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
*/
|
||||
@Nullable
|
||||
Offer generateOffer(Transaction txn, ContactId c, int maxMessages,
|
||||
int maxLatency) throws DbException;
|
||||
long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a request for the given contact, or null if there are no
|
||||
@@ -194,7 +240,7 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
*/
|
||||
@Nullable
|
||||
Collection<Message> generateRequestedBatch(Transaction txn, ContactId c,
|
||||
int maxLength, int maxLatency) throws DbException;
|
||||
int maxLength, long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the contact with the given ID.
|
||||
@@ -288,6 +334,16 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
Collection<MessageId> getMessageIds(Transaction txn, GroupId g)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of any delivered messages in the given group with
|
||||
* metadata that matches all entries in the given query. If the query is
|
||||
* empty, the IDs of all delivered messages are returned.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Collection<MessageId> getMessageIds(Transaction txn, GroupId g,
|
||||
Metadata query) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of any messages that need to be validated.
|
||||
* <p/>
|
||||
@@ -314,6 +370,15 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
Collection<MessageId> getMessagesToShare(Transaction txn)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of any messages of any messages that are due for
|
||||
* deletion, along with their group IDs.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Map<GroupId, Collection<MessageId>> getMessagesToDelete(Transaction txn)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the metadata for all delivered messages in the given group.
|
||||
* <p/>
|
||||
@@ -395,6 +460,36 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
MessageStatus getMessageStatus(Transaction txn, ContactId c, MessageId m)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the IDs of all messages that are eligible to be sent to the
|
||||
* given contact, together with their raw lengths. This may include
|
||||
* messages that have already been sent and are not yet due for
|
||||
* retransmission.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Map<MessageId, Integer> getUnackedMessagesToSend(Transaction txn,
|
||||
ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the total length, including headers, of all messages that are
|
||||
* eligible to be sent to the given contact. This may include messages
|
||||
* that have already been sent and are not yet due for retransmission.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
long getUnackedMessageBytesToSend(Transaction txn, ContactId c)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the next time (in milliseconds since the Unix epoch) when a
|
||||
* message is due to be deleted, or {@link #NO_CLEANUP_DEADLINE}
|
||||
* if no messages are scheduled to be deleted.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
long getNextCleanupDeadline(Transaction txn) throws DbException;
|
||||
|
||||
/*
|
||||
* Returns the next time (in milliseconds since the Unix epoch) when a
|
||||
* message is due to be sent to the given contact. The returned value may
|
||||
@@ -443,6 +538,16 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
Collection<TransportKeySet> getTransportKeys(Transaction txn, TransportId t)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the contact IDs and transport IDs for which the DB contains
|
||||
* at least one set of transport keys. Handshake mode and rotation mode
|
||||
* keys are included, whether activated or not.
|
||||
* <p/>
|
||||
* Read-only.
|
||||
*/
|
||||
Map<ContactId, Collection<TransportId>> getTransportsWithKeys(
|
||||
Transaction txn) throws DbException;
|
||||
|
||||
/**
|
||||
* Increments the outgoing stream counter for the given transport keys.
|
||||
*/
|
||||
@@ -535,6 +640,13 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
void removeTransportKeys(Transaction txn, TransportId t, KeySetId k)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the cleanup timer duration for the given message. This does not
|
||||
* start the message's cleanup timer.
|
||||
*/
|
||||
void setCleanupTimerDuration(Transaction txn, MessageId m, long duration)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given contact as verified.
|
||||
*/
|
||||
@@ -546,11 +658,6 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
void setContactAlias(Transaction txn, ContactId c, @Nullable String alias)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the remote handshake public key for a given contact
|
||||
*/
|
||||
void setHandshakePublicKey(Transaction txn, ContactId c, PublicKey handshakePublicKey) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the given group's visibility to the given contact.
|
||||
*/
|
||||
@@ -562,6 +669,12 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
*/
|
||||
void setMessagePermanent(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as not shared. This method is only meant for
|
||||
* testing.
|
||||
*/
|
||||
void setMessageNotShared(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as shared.
|
||||
*/
|
||||
@@ -604,6 +717,22 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
void setTransportKeysActive(Transaction txn, TransportId t, KeySetId k)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Starts the cleanup timer for the given message, if a timer duration
|
||||
* has been set and the timer has not already been started.
|
||||
*
|
||||
* @return The cleanup deadline, or {@link #TIMER_NOT_STARTED} if no
|
||||
* timer duration has been set for this message or its timer has already
|
||||
* been started.
|
||||
*/
|
||||
long startCleanupTimer(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Stops the cleanup timer for the given message, if the timer has been
|
||||
* started.
|
||||
*/
|
||||
void stopCleanupTimer(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Stores the given transport keys, deleting any keys they have replaced.
|
||||
*/
|
||||
|
||||
@@ -57,6 +57,7 @@ public class Author implements Nameable {
|
||||
/**
|
||||
* Returns the author's name.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,6 @@ public interface IdentityManager {
|
||||
*/
|
||||
void registerIdentity(Identity i);
|
||||
|
||||
/**
|
||||
* Returns the cached local identity or loads it from the database.
|
||||
*/
|
||||
Identity getIdentity(Transaction txn) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the cached local identity or loads it from the database.
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.briarproject.bramble.api.keyagreement.event;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when a BQP protocol completes.
|
||||
* An event that is broadcast when a BQP protocol begins.
|
||||
*/
|
||||
public class KeyAgreementStartedEvent extends Event {
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.Wakeful;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -22,6 +23,7 @@ public interface LifecycleManager {
|
||||
*/
|
||||
enum StartResult {
|
||||
ALREADY_RUNNING,
|
||||
CLOCK_ERROR,
|
||||
DB_ERROR,
|
||||
DATA_TOO_OLD_ERROR,
|
||||
DATA_TOO_NEW_ERROR,
|
||||
@@ -65,6 +67,10 @@ public interface LifecycleManager {
|
||||
/**
|
||||
* Opens the {@link DatabaseComponent} using the given key and starts any
|
||||
* registered {@link Service Services}.
|
||||
*
|
||||
* @return {@link StartResult#CLOCK_ERROR} if the system clock is earlier
|
||||
* than {@link Clock#MIN_REASONABLE_TIME_MS} or later than
|
||||
* {@link Clock#MAX_REASONABLE_TIME_MS}.
|
||||
*/
|
||||
@Wakeful
|
||||
StartResult startServices(SecretKey dbKey);
|
||||
|
||||
@@ -61,7 +61,7 @@ public interface Plugin {
|
||||
/**
|
||||
* Returns the transport's maximum latency in milliseconds.
|
||||
*/
|
||||
int getMaxLatency();
|
||||
long getMaxLatency();
|
||||
|
||||
/**
|
||||
* Returns the transport's maximum idle time in milliseconds.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.bramble.api.plugin;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface PluginFactory<P extends Plugin> {
|
||||
|
||||
/**
|
||||
* Returns the plugin's transport identifier.
|
||||
*/
|
||||
TransportId getId();
|
||||
|
||||
/**
|
||||
* Returns the maximum latency of the transport in milliseconds.
|
||||
*/
|
||||
long getMaxLatency();
|
||||
|
||||
/**
|
||||
* Creates and returns a plugin, or null if no plugin can be created.
|
||||
*/
|
||||
@Nullable
|
||||
P createPlugin(PluginCallback callback);
|
||||
}
|
||||
@@ -15,13 +15,18 @@ public interface TransportConnectionWriter {
|
||||
/**
|
||||
* Returns the maximum latency of the transport in milliseconds.
|
||||
*/
|
||||
int getMaxLatency();
|
||||
long getMaxLatency();
|
||||
|
||||
/**
|
||||
* Returns the maximum idle time of the transport in milliseconds.
|
||||
*/
|
||||
int getMaxIdleTime();
|
||||
|
||||
/**
|
||||
* Returns true if the transport is lossy and cheap.
|
||||
*/
|
||||
boolean isLossyAndCheap();
|
||||
|
||||
/**
|
||||
* Returns an output stream for writing to the transport connection.
|
||||
*/
|
||||
|
||||
@@ -70,7 +70,7 @@ public abstract class AbstractDuplexTransportConnection
|
||||
private class Writer implements TransportConnectionWriter {
|
||||
|
||||
@Override
|
||||
public int getMaxLatency() {
|
||||
public long getMaxLatency() {
|
||||
return plugin.getMaxLatency();
|
||||
}
|
||||
|
||||
@@ -79,6 +79,11 @@ public abstract class AbstractDuplexTransportConnection
|
||||
return plugin.getMaxIdleTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLossyAndCheap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return AbstractDuplexTransportConnection.this.getOutputStream();
|
||||
|
||||
@@ -1,30 +1,11 @@
|
||||
package org.briarproject.bramble.api.plugin.duplex;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.briarproject.bramble.api.plugin.PluginFactory;
|
||||
|
||||
/**
|
||||
* Factory for creating a plugin for a duplex transport.
|
||||
*/
|
||||
@NotNullByDefault
|
||||
public interface DuplexPluginFactory {
|
||||
|
||||
/**
|
||||
* Returns the plugin's transport identifier.
|
||||
*/
|
||||
TransportId getId();
|
||||
|
||||
/**
|
||||
* Returns the maximum latency of the transport in milliseconds.
|
||||
*/
|
||||
int getMaxLatency();
|
||||
|
||||
/**
|
||||
* Creates and returns a plugin, or null if no plugin can be created.
|
||||
*/
|
||||
@Nullable
|
||||
DuplexPlugin createPlugin(PluginCallback callback);
|
||||
public interface DuplexPluginFactory extends PluginFactory<DuplexPlugin> {
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.bramble.api.plugin;
|
||||
package org.briarproject.bramble.api.plugin.file;
|
||||
|
||||
public interface FileConstants {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.briarproject.bramble.api.plugin.file;
|
||||
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
|
||||
public interface RemovableDriveConstants {
|
||||
|
||||
TransportId ID = new TransportId("org.briarproject.bramble.drive");
|
||||
|
||||
String PROP_PATH = "path";
|
||||
String PROP_URI = "uri";
|
||||
String PROP_SUPPORTED = "supported";
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.briarproject.bramble.api.plugin.file;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface RemovableDriveManager {
|
||||
|
||||
/**
|
||||
* Returns the currently running reader task, or null if no reader task
|
||||
* is running.
|
||||
*/
|
||||
@Nullable
|
||||
RemovableDriveTask getCurrentReaderTask();
|
||||
|
||||
/**
|
||||
* Returns the currently running writer task, or null if no writer task
|
||||
* is running.
|
||||
*/
|
||||
@Nullable
|
||||
RemovableDriveTask getCurrentWriterTask();
|
||||
|
||||
/**
|
||||
* Starts and returns a reader task, reading from a stream described by
|
||||
* the given transport properties. If a reader task is already running,
|
||||
* it will be returned and the argument will be ignored.
|
||||
*/
|
||||
RemovableDriveTask startReaderTask(TransportProperties p);
|
||||
|
||||
/**
|
||||
* Starts and returns a writer task for the given contact, writing to
|
||||
* a stream described by the given transport properties. If a writer task
|
||||
* is already running, it will be returned and the arguments will be
|
||||
* ignored.
|
||||
*/
|
||||
RemovableDriveTask startWriterTask(ContactId c, TransportProperties p);
|
||||
|
||||
/**
|
||||
* Returns true if the given contact has indicated support for the
|
||||
* removable drive transport.
|
||||
*/
|
||||
boolean isTransportSupportedByContact(ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if there is anything to send to the given contact.
|
||||
*/
|
||||
boolean isWriterTaskNeeded(ContactId c) throws DbException;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.briarproject.bramble.api.plugin.file;
|
||||
|
||||
import org.briarproject.bramble.api.Consumer;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface RemovableDriveTask extends Runnable {
|
||||
|
||||
/**
|
||||
* Returns the {@link TransportProperties} that were used for creating
|
||||
* this task.
|
||||
*/
|
||||
TransportProperties getTransportProperties();
|
||||
|
||||
/**
|
||||
* Adds an observer to the task. The observer will be notified on the
|
||||
* event thread of the current state of the task and any subsequent state
|
||||
* changes.
|
||||
*/
|
||||
void addObserver(Consumer<State> observer);
|
||||
|
||||
/**
|
||||
* Removes an observer from the task.
|
||||
*/
|
||||
void removeObserver(Consumer<State> observer);
|
||||
|
||||
class State {
|
||||
|
||||
private final long done, total;
|
||||
private final boolean finished, success;
|
||||
|
||||
public State(long done, long total, boolean finished, boolean success) {
|
||||
this.done = done;
|
||||
this.total = total;
|
||||
this.finished = finished;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total length in bytes of the messages read or written
|
||||
* so far, or zero if the total is unknown.
|
||||
*/
|
||||
public long getDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total length in bytes of the messages that will have
|
||||
* been read or written when the task is complete, or zero if the
|
||||
* total is unknown.
|
||||
*/
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,12 @@ import javax.annotation.Nullable;
|
||||
@NotNullByDefault
|
||||
public interface SimplexPlugin extends Plugin {
|
||||
|
||||
/**
|
||||
* Returns true if the transport is likely to lose streams and the cost of
|
||||
* transmitting redundant copies of data is cheap.
|
||||
*/
|
||||
boolean isLossyAndCheap();
|
||||
|
||||
/**
|
||||
* Attempts to create and return a reader for the given transport
|
||||
* properties. Returns null if a reader cannot be created.
|
||||
|
||||
@@ -1,30 +1,11 @@
|
||||
package org.briarproject.bramble.api.plugin.simplex;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.briarproject.bramble.api.plugin.PluginFactory;
|
||||
|
||||
/**
|
||||
* Factory for creating a plugin for a simplex transport.
|
||||
*/
|
||||
@NotNullByDefault
|
||||
public interface SimplexPluginFactory {
|
||||
|
||||
/**
|
||||
* Returns the plugin's transport identifier.
|
||||
*/
|
||||
TransportId getId();
|
||||
|
||||
/**
|
||||
* Returns the maximum latency of the transport in milliseconds.
|
||||
*/
|
||||
int getMaxLatency();
|
||||
|
||||
/**
|
||||
* Creates and returns a plugin, or null if no plugin can be created.
|
||||
*/
|
||||
@Nullable
|
||||
SimplexPlugin createPlugin(PluginCallback callback);
|
||||
public interface SimplexPluginFactory extends PluginFactory<SimplexPlugin> {
|
||||
}
|
||||
|
||||
@@ -74,13 +74,6 @@ public interface TransportPropertyManager {
|
||||
TransportProperties getRemoteProperties(ContactId c, TransportId t)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the remote transport properties for the given contact and
|
||||
* transport.
|
||||
*/
|
||||
TransportProperties getRemoteProperties(Transaction txn, ContactId c,
|
||||
TransportId t) throws DbException;
|
||||
|
||||
/**
|
||||
* Merges the given properties with the existing local properties for the
|
||||
* given transport.
|
||||
|
||||
@@ -21,5 +21,6 @@ public interface ReportingConstants {
|
||||
* Hidden service address for reporting crashes and feedback to the
|
||||
* developers.
|
||||
*/
|
||||
String DEV_ONION_ADDRESS = "cwqmubyvnig3wag3.onion";
|
||||
String DEV_ONION_ADDRESS =
|
||||
"b2nkt5doeamvdmjzfz7g42hk5vdtlnktlgzhel2bgjcc4v4jhnx2qrqd.onion";
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.UniqueId;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
||||
|
||||
public interface SyncConstants {
|
||||
@@ -55,4 +56,9 @@ public interface SyncConstants {
|
||||
* connections.
|
||||
*/
|
||||
int PRIORITY_NONCE_BYTES = 16;
|
||||
|
||||
/**
|
||||
* The maximum allowed latency for any transport, in milliseconds.
|
||||
*/
|
||||
long MAX_TRANSPORT_LATENCY = DAYS.toMillis(365);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ public interface SyncSessionFactory {
|
||||
PriorityHandler handler);
|
||||
|
||||
SyncSession createSimplexOutgoingSession(ContactId c, TransportId t,
|
||||
int maxLatency, StreamWriter streamWriter);
|
||||
long maxLatency, boolean eager, StreamWriter streamWriter);
|
||||
|
||||
SyncSession createDuplexOutgoingSession(ContactId c, TransportId t,
|
||||
int maxLatency, int maxIdleTime, StreamWriter streamWriter,
|
||||
long maxLatency, int maxIdleTime, StreamWriter streamWriter,
|
||||
@Nullable Priority priority);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ public class MessagesSentEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final Collection<MessageId> messageIds;
|
||||
private final long totalLength;
|
||||
|
||||
public MessagesSentEvent(ContactId contactId,
|
||||
Collection<MessageId> messageIds) {
|
||||
Collection<MessageId> messageIds, long totalLength) {
|
||||
this.contactId = contactId;
|
||||
this.messageIds = messageIds;
|
||||
this.totalLength = totalLength;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
@@ -32,4 +34,8 @@ public class MessagesSentEvent extends Event {
|
||||
public Collection<MessageId> getMessageIds() {
|
||||
return messageIds;
|
||||
}
|
||||
|
||||
public long getTotalLength() {
|
||||
return totalLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,23 +10,54 @@ public interface IncomingMessageHook {
|
||||
|
||||
/**
|
||||
* Called once for each incoming message that passes validation.
|
||||
* <p>
|
||||
* If an unexpected exception occurs while handling data that is assumed
|
||||
* to be valid (e.g. locally created metadata), it may be sensible to
|
||||
* rethrow the unexpected exception as a DbException so that delivery is
|
||||
* attempted again at next startup. This will allow delivery to succeed if
|
||||
* the unexpected exception was caused by a bug that has subsequently been
|
||||
* fixed.
|
||||
*
|
||||
* @param txn A read-write transaction
|
||||
* @return Whether or not this message should be shared
|
||||
* @throws DbException Should only be used for real database errors.
|
||||
* If this is thrown, delivery will be attempted again at next startup,
|
||||
* whereas if an InvalidMessageException is thrown,
|
||||
* the message will be permanently invalidated.
|
||||
* @throws InvalidMessageException for any non-database error
|
||||
* that occurs while handling remotely created data.
|
||||
* This includes errors that occur while handling locally created data
|
||||
* in a context controlled by remotely created data
|
||||
* (for example, parsing the metadata of a dependency
|
||||
* of an incoming message).
|
||||
* Throwing this will delete the incoming message and its metadata
|
||||
* marking it as invalid in the database.
|
||||
* Never rethrow DbException as InvalidMessageException!
|
||||
* @throws DbException if a database error occurs while delivering the
|
||||
* message. Delivery will be attempted again at next startup. Throwing
|
||||
* this exception has the same effect as returning
|
||||
* {@link DeliveryAction#DEFER}.
|
||||
* @throws InvalidMessageException if the message is invalid in the context
|
||||
* of its dependencies. The message and any dependents will be marked as
|
||||
* invalid and deleted along with their metadata. Throwing this exception
|
||||
* has the same effect as returning {@link DeliveryAction#REJECT}.
|
||||
*/
|
||||
boolean incomingMessage(Transaction txn, Message m, Metadata meta)
|
||||
DeliveryAction incomingMessage(Transaction txn, Message m, Metadata meta)
|
||||
throws DbException, InvalidMessageException;
|
||||
|
||||
enum DeliveryAction {
|
||||
|
||||
/**
|
||||
* The message and any dependent messages will be moved to the
|
||||
* {@link MessageState#INVALID INVALID state} and deleted, along with
|
||||
* their metadata.
|
||||
*/
|
||||
REJECT,
|
||||
|
||||
/**
|
||||
* The message will be moved to the
|
||||
* {@link MessageState#PENDING PENDING state}. Delivery will be
|
||||
* attempted again at next startup.
|
||||
*/
|
||||
DEFER,
|
||||
|
||||
/**
|
||||
* The message will be moved to the
|
||||
* {@link MessageState#DELIVERED DELIVERED state} and shared.
|
||||
*/
|
||||
ACCEPT_SHARE,
|
||||
|
||||
/**
|
||||
* The message will be moved to the
|
||||
* {@link MessageState#DELIVERED DELIVERED state} and will not be
|
||||
* shared.
|
||||
*/
|
||||
ACCEPT_DO_NOT_SHARE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,33 @@
|
||||
package org.briarproject.bramble.api.sync.validation;
|
||||
|
||||
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook.DeliveryAction;
|
||||
|
||||
public enum MessageState {
|
||||
|
||||
UNKNOWN(0), INVALID(1), PENDING(2), DELIVERED(3);
|
||||
/**
|
||||
* A remote message that has not yet been validated.
|
||||
*/
|
||||
UNKNOWN(0),
|
||||
|
||||
/**
|
||||
* A remote message that has failed validation, has been
|
||||
* {@link DeliveryAction#REJECT rejected} by the local sync client, or
|
||||
* depends on another message that has failed validation or been rejected.
|
||||
*/
|
||||
INVALID(1),
|
||||
|
||||
/**
|
||||
* A remote message that has passed validation and is awaiting delivery to
|
||||
* the local sync client. The message will not be delivered until all its
|
||||
* dependencies have been validated and delivered.
|
||||
*/
|
||||
PENDING(2),
|
||||
|
||||
/**
|
||||
* A local message, or a remote message that has passed validation and
|
||||
* been delivered to the local sync client.
|
||||
*/
|
||||
DELIVERED(3);
|
||||
|
||||
private final int value;
|
||||
|
||||
|
||||
@@ -6,6 +6,22 @@ package org.briarproject.bramble.api.system;
|
||||
*/
|
||||
public interface Clock {
|
||||
|
||||
/**
|
||||
* The minimum reasonable value for the system clock, in milliseconds
|
||||
* since the Unix epoch.
|
||||
* <p/>
|
||||
* 1 Jan 2021, 00:00:00 UTC
|
||||
*/
|
||||
long MIN_REASONABLE_TIME_MS = 1_609_459_200_000L;
|
||||
|
||||
/**
|
||||
* The maximum reasonable value for the system clock, in milliseconds
|
||||
* since the Unix epoch.
|
||||
* <p/>
|
||||
* 1 Jan 2121, 00:00:00 UTC
|
||||
*/
|
||||
long MAX_REASONABLE_TIME_MS = 4_765_132_800_000L;
|
||||
|
||||
/**
|
||||
* @see System#currentTimeMillis()
|
||||
*/
|
||||
|
||||
@@ -22,8 +22,24 @@ public interface KeyManager {
|
||||
|
||||
/**
|
||||
* Derives and stores a set of rotation mode transport keys for
|
||||
* communicating with the given contact over each transport and returns the
|
||||
* key set IDs.
|
||||
* communicating with the given contact over the given transport and
|
||||
* returns the key set ID, or null if the transport is not supported.
|
||||
* <p/>
|
||||
* {@link StreamContext StreamContexts} for the contact can be created
|
||||
* after this method has returned.
|
||||
*
|
||||
* @param alice True if the local party is Alice
|
||||
* @param active Whether the derived keys can be used for outgoing streams
|
||||
*/
|
||||
@Nullable
|
||||
KeySetId addRotationKeys(Transaction txn, ContactId c, TransportId t,
|
||||
SecretKey rootKey, long timestamp, boolean alice,
|
||||
boolean active) throws DbException;
|
||||
|
||||
/**
|
||||
* Derives and stores a set of rotation mode transport keys for
|
||||
* communicating with the given contact over each supported transport and
|
||||
* returns the key set IDs.
|
||||
* <p/>
|
||||
* {@link StreamContext StreamContexts} for the contact can be created
|
||||
* after this method has returned.
|
||||
@@ -35,20 +51,6 @@ public interface KeyManager {
|
||||
ContactId c, SecretKey rootKey, long timestamp, boolean alice,
|
||||
boolean active) throws DbException;
|
||||
|
||||
/**
|
||||
* Derives and stores a set of rotation mode transport keys for
|
||||
* communicating with the given contact over each transport and returns the
|
||||
* key set IDs.
|
||||
* <p/>
|
||||
* {@link StreamContext StreamContexts} for the contact can be created
|
||||
* after this method has returned.
|
||||
*
|
||||
* @param alice True if the local party is Alice
|
||||
* @param active Whether the derived keys can be used for outgoing streams
|
||||
*/
|
||||
Map<TransportId, KeySetId> addRotationKeys(ContactId c, SecretKey rootKey,
|
||||
long timestamp, boolean alice, boolean active) throws DbException;
|
||||
|
||||
/**
|
||||
* Informs the key manager that a new contact has been added. Derives and
|
||||
* stores a set of handshake mode transport keys for communicating with the
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.briarproject.bramble.api.transport.agreement;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface TransportKeyAgreementManager {
|
||||
|
||||
/**
|
||||
* The unique ID of the transport key agreement client.
|
||||
*/
|
||||
ClientId CLIENT_ID =
|
||||
new ClientId("org.briarproject.bramble.transport.agreement");
|
||||
|
||||
/**
|
||||
* The current major version of the transport key agreement client.
|
||||
*/
|
||||
int MAJOR_VERSION = 0;
|
||||
|
||||
/**
|
||||
* The current minor version of the transport key agreement client.
|
||||
*/
|
||||
int MINOR_VERSION = 0;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.briarproject.bramble.util;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.list;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@NotNullByDefault
|
||||
public class NetworkUtils {
|
||||
|
||||
private static final Logger LOG = getLogger(NetworkUtils.class.getName());
|
||||
|
||||
public static List<NetworkInterface> getNetworkInterfaces() {
|
||||
try {
|
||||
Enumeration<NetworkInterface> ifaces =
|
||||
NetworkInterface.getNetworkInterfaces();
|
||||
// Despite what the docs say, the return value can be null
|
||||
//noinspection ConstantConditions
|
||||
return ifaces == null ? emptyList() : list(ifaces);
|
||||
} catch (SocketException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
return emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,9 @@ import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class ValidationUtils {
|
||||
|
||||
@@ -64,4 +66,9 @@ public class ValidationUtils {
|
||||
if (dictionary != null && dictionary.size() != size)
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
public static void checkRange(@Nullable Long l, long min, long max)
|
||||
throws FormatException {
|
||||
if (l != null && (l < min || l > max)) throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,10 +163,15 @@ public class TestUtils {
|
||||
|
||||
public static Message getMessage(GroupId groupId) {
|
||||
int bodyLength = 1 + random.nextInt(MAX_MESSAGE_BODY_LENGTH);
|
||||
return getMessage(groupId, bodyLength);
|
||||
return getMessage(groupId, bodyLength, timestamp);
|
||||
}
|
||||
|
||||
public static Message getMessage(GroupId groupId, int bodyLength) {
|
||||
return getMessage(groupId, bodyLength, timestamp);
|
||||
}
|
||||
|
||||
public static Message getMessage(GroupId groupId, int bodyLength,
|
||||
long timestamp) {
|
||||
MessageId id = new MessageId(getRandomId());
|
||||
byte[] body = getRandomBytes(bodyLength);
|
||||
return new Message(id, groupId, timestamp, body);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.briarproject.bramble.test;
|
||||
|
||||
public interface TimeTravel {
|
||||
|
||||
void setCurrentTimeMillis(long now) throws InterruptedException;
|
||||
|
||||
void addCurrentTimeMillis(long add) throws InterruptedException;
|
||||
}
|
||||
@@ -3,15 +3,15 @@ dependencyVerification {
|
||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.dagger:dagger:2.24:dagger-2.24.jar:550a6e46a6dfcdf1d764887b6090cea94f783327e50e5c73754f18facfc70b64',
|
||||
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
|
||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||
'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',
|
||||
'org.codehaus.mojo:animal-sniffer-ant-tasks:1.16:animal-sniffer-ant-tasks-1.16.jar:890040976fbe2d584619a6a61b1fd2e925b3b5eb342a85eb2762c467c0d64e90',
|
||||
'org.codehaus.mojo:animal-sniffer:1.16:animal-sniffer-1.16.jar:72be8bcc226ba43b937c722a08a07852bfa1b11400089265d5df0ee7b38b1d52',
|
||||
'org.codehaus.mojo:animal-sniffer-ant-tasks:1.20:animal-sniffer-ant-tasks-1.20.jar:bb7d2498144118311d968bb08ff6fae3fc535fb1cb9cca8b8e9ea65b189422ac',
|
||||
'org.codehaus.mojo:animal-sniffer:1.20:animal-sniffer-1.20.jar:80c422523c38db91260c6d78e5ee4b012862ab61cc55020c9e243dd7b5c62249',
|
||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||
@@ -21,7 +21,7 @@ dependencyVerification {
|
||||
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
||||
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
||||
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
|
||||
'org.ow2.asm:asm-all:5.2:asm-all-5.2.jar:7fbffbc1db3422e2101689fd88df8384b15817b52b9b2b267b9f6d2511dc198d',
|
||||
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
|
||||
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ apply from: '../dagger.gradle'
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-api', configuration: 'default')
|
||||
implementation 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.69'
|
||||
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
|
||||
implementation 'org.bitlet:weupnp:0.1.4'
|
||||
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||
implementation 'org.briarproject:jtorctl:0.3'
|
||||
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6
|
||||
@@ -25,9 +25,9 @@ dependencies {
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-imposters:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-legacy:$jmock_version"
|
||||
|
||||
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.24'
|
||||
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble;
|
||||
|
||||
import org.briarproject.bramble.cleanup.CleanupModule;
|
||||
import org.briarproject.bramble.contact.ContactModule;
|
||||
import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
||||
import org.briarproject.bramble.db.DatabaseExecutorModule;
|
||||
@@ -10,10 +11,13 @@ import org.briarproject.bramble.properties.PropertiesModule;
|
||||
import org.briarproject.bramble.rendezvous.RendezvousModule;
|
||||
import org.briarproject.bramble.sync.validation.ValidationModule;
|
||||
import org.briarproject.bramble.transport.TransportModule;
|
||||
import org.briarproject.bramble.transport.agreement.TransportKeyAgreementModule;
|
||||
import org.briarproject.bramble.versioning.VersioningModule;
|
||||
|
||||
public interface BrambleCoreEagerSingletons {
|
||||
|
||||
void inject(CleanupModule.EagerSingletons init);
|
||||
|
||||
void inject(ContactModule.EagerSingletons init);
|
||||
|
||||
void inject(CryptoExecutorModule.EagerSingletons init);
|
||||
@@ -30,6 +34,8 @@ public interface BrambleCoreEagerSingletons {
|
||||
|
||||
void inject(RendezvousModule.EagerSingletons init);
|
||||
|
||||
void inject(TransportKeyAgreementModule.EagerSingletons init);
|
||||
|
||||
void inject(TransportModule.EagerSingletons init);
|
||||
|
||||
void inject(ValidationModule.EagerSingletons init);
|
||||
@@ -39,6 +45,7 @@ public interface BrambleCoreEagerSingletons {
|
||||
class Helper {
|
||||
|
||||
public static void injectEagerSingletons(BrambleCoreEagerSingletons c) {
|
||||
c.inject(new CleanupModule.EagerSingletons());
|
||||
c.inject(new ContactModule.EagerSingletons());
|
||||
c.inject(new CryptoExecutorModule.EagerSingletons());
|
||||
c.inject(new DatabaseExecutorModule.EagerSingletons());
|
||||
@@ -47,6 +54,7 @@ public interface BrambleCoreEagerSingletons {
|
||||
c.inject(new RendezvousModule.EagerSingletons());
|
||||
c.inject(new PluginModule.EagerSingletons());
|
||||
c.inject(new PropertiesModule.EagerSingletons());
|
||||
c.inject(new TransportKeyAgreementModule.EagerSingletons());
|
||||
c.inject(new TransportModule.EagerSingletons());
|
||||
c.inject(new ValidationModule.EagerSingletons());
|
||||
c.inject(new VersioningModule.EagerSingletons());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble;
|
||||
|
||||
import org.briarproject.bramble.cleanup.CleanupModule;
|
||||
import org.briarproject.bramble.client.ClientModule;
|
||||
import org.briarproject.bramble.connection.ConnectionModule;
|
||||
import org.briarproject.bramble.contact.ContactModule;
|
||||
@@ -21,15 +22,15 @@ import org.briarproject.bramble.rendezvous.RendezvousModule;
|
||||
import org.briarproject.bramble.settings.SettingsModule;
|
||||
import org.briarproject.bramble.sync.SyncModule;
|
||||
import org.briarproject.bramble.sync.validation.ValidationModule;
|
||||
import org.briarproject.bramble.system.ClockModule;
|
||||
import org.briarproject.bramble.transport.TransportModule;
|
||||
import org.briarproject.bramble.transport.agreement.TransportKeyAgreementModule;
|
||||
import org.briarproject.bramble.versioning.VersioningModule;
|
||||
|
||||
import dagger.Module;
|
||||
|
||||
@Module(includes = {
|
||||
CleanupModule.class,
|
||||
ClientModule.class,
|
||||
ClockModule.class,
|
||||
ConnectionModule.class,
|
||||
ContactModule.class,
|
||||
CryptoModule.class,
|
||||
@@ -49,6 +50,7 @@ import dagger.Module;
|
||||
RendezvousModule.class,
|
||||
SettingsModule.class,
|
||||
SyncModule.class,
|
||||
TransportKeyAgreementModule.class,
|
||||
TransportModule.class,
|
||||
ValidationModule.class,
|
||||
VersioningModule.class
|
||||
|
||||
@@ -176,18 +176,6 @@ class AccountManagerImpl implements AccountManager {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean restoreAccount(Identity identity, String password) {
|
||||
synchronized (stateChangeLock) {
|
||||
if (hasDatabaseKey())
|
||||
throw new AssertionError("Already have a database key");
|
||||
identityManager.registerIdentity(identity);
|
||||
SecretKey key = crypto.generateSecretKey();
|
||||
if (!encryptAndStoreDatabaseKey(key, password)) return false;
|
||||
databaseKey = key;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("stateChangeLock")
|
||||
private boolean encryptAndStoreDatabaseKey(SecretKey key, String password) {
|
||||
byte[] plaintext = key.getBytes();
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
package org.briarproject.bramble.cleanup;
|
||||
|
||||
import org.briarproject.bramble.api.cleanup.CleanupHook;
|
||||
import org.briarproject.bramble.api.cleanup.CleanupManager;
|
||||
import org.briarproject.bramble.api.cleanup.event.CleanupTimerStartedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.lifecycle.Service;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.TaskScheduler;
|
||||
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.db.DatabaseComponent.NO_CLEANUP_DEADLINE;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@ThreadSafe
|
||||
@NotNullByDefault
|
||||
class CleanupManagerImpl implements CleanupManager, Service, EventListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(CleanupManagerImpl.class.getName());
|
||||
|
||||
private final Executor dbExecutor;
|
||||
private final DatabaseComponent db;
|
||||
private final TaskScheduler taskScheduler;
|
||||
private final Clock clock;
|
||||
private final Map<ClientMajorVersion, CleanupHook> hooks =
|
||||
new ConcurrentHashMap<>();
|
||||
private final Object lock = new Object();
|
||||
|
||||
@GuardedBy("lock")
|
||||
private final Set<CleanupTask> pending = new HashSet<>();
|
||||
|
||||
@Inject
|
||||
CleanupManagerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
DatabaseComponent db, TaskScheduler taskScheduler, Clock clock) {
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.db = db;
|
||||
this.taskScheduler = taskScheduler;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCleanupHook(ClientId c, int majorVersion,
|
||||
CleanupHook hook) {
|
||||
hooks.put(new ClientMajorVersion(c, majorVersion), hook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startService() {
|
||||
maybeScheduleTask(clock.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof CleanupTimerStartedEvent) {
|
||||
CleanupTimerStartedEvent a = (CleanupTimerStartedEvent) e;
|
||||
maybeScheduleTask(a.getCleanupDeadline());
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeScheduleTask(long deadline) {
|
||||
synchronized (lock) {
|
||||
for (CleanupTask task : pending) {
|
||||
if (task.deadline <= deadline) return;
|
||||
}
|
||||
CleanupTask task = new CleanupTask(deadline);
|
||||
pending.add(task);
|
||||
scheduleTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleTask(CleanupTask task) {
|
||||
long now = clock.currentTimeMillis();
|
||||
long delay = max(0, task.deadline - now + BATCH_DELAY_MS);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Scheduling cleanup task in " + delay + " ms");
|
||||
}
|
||||
taskScheduler.schedule(() -> deleteMessagesAndScheduleNextTask(task),
|
||||
dbExecutor, delay, MILLISECONDS);
|
||||
}
|
||||
|
||||
private void deleteMessagesAndScheduleNextTask(CleanupTask task) {
|
||||
try {
|
||||
synchronized (lock) {
|
||||
pending.remove(task);
|
||||
}
|
||||
long deadline = db.transactionWithResult(false, txn -> {
|
||||
deleteMessages(txn);
|
||||
return db.getNextCleanupDeadline(txn);
|
||||
});
|
||||
if (deadline != NO_CLEANUP_DEADLINE) {
|
||||
maybeScheduleTask(deadline);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteMessages(Transaction txn) throws DbException {
|
||||
Map<GroupId, Collection<MessageId>> ids = db.getMessagesToDelete(txn);
|
||||
for (Entry<GroupId, Collection<MessageId>> e : ids.entrySet()) {
|
||||
GroupId groupId = e.getKey();
|
||||
Collection<MessageId> messageIds = e.getValue();
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info(messageIds.size() + " messages to delete");
|
||||
}
|
||||
for (MessageId m : messageIds) db.stopCleanupTimer(txn, m);
|
||||
Group group = db.getGroup(txn, groupId);
|
||||
ClientMajorVersion cv = new ClientMajorVersion(group.getClientId(),
|
||||
group.getMajorVersion());
|
||||
CleanupHook hook = hooks.get(cv);
|
||||
if (hook == null) {
|
||||
throw new IllegalStateException("No cleanup hook for " + cv);
|
||||
}
|
||||
hook.deleteMessages(txn, groupId, messageIds);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CleanupTask {
|
||||
|
||||
private final long deadline;
|
||||
|
||||
private CleanupTask(long deadline) {
|
||||
this.deadline = deadline;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.bramble.cleanup;
|
||||
|
||||
import org.briarproject.bramble.api.cleanup.CleanupManager;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class CleanupModule {
|
||||
|
||||
public static class EagerSingletons {
|
||||
@Inject
|
||||
CleanupManager cleanupManager;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
CleanupManager provideCleanupManager(LifecycleManager lifecycleManager,
|
||||
EventBus eventBus, CleanupManagerImpl cleanupManager) {
|
||||
lifecycleManager.registerService(cleanupManager);
|
||||
eventBus.addListener(cleanupManager);
|
||||
return cleanupManager;
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,13 @@ package org.briarproject.bramble.client;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
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.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
@@ -32,6 +34,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -39,6 +42,7 @@ import java.util.Map.Entry;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.client.ContactGroupConstants.GROUP_KEY_CONTACT_ID;
|
||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
@@ -151,6 +155,12 @@ class ClientHelperImpl implements ClientHelper {
|
||||
return metadataParser.parse(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MessageId> getMessageIds(Transaction txn, GroupId g,
|
||||
BdfDictionary query) throws DbException, FormatException {
|
||||
return db.getMessageIds(txn, g, metadataEncoder.encode(query));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary getMessageMetadataAsDictionary(MessageId m)
|
||||
throws DbException, FormatException {
|
||||
@@ -389,4 +399,27 @@ class ClientHelperImpl implements ClientHelper {
|
||||
return tpMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactId getContactId(Transaction txn, GroupId contactGroupId)
|
||||
throws DbException {
|
||||
try {
|
||||
BdfDictionary meta =
|
||||
getGroupMetadataAsDictionary(txn, contactGroupId);
|
||||
return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e); // Invalid group metadata
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContactId(Transaction txn, GroupId contactGroupId,
|
||||
ContactId c) throws DbException {
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_CONTACT_ID, c.getInt()));
|
||||
try {
|
||||
mergeGroupMetadata(txn, contactGroupId, meta);
|
||||
} catch (FormatException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ abstract class Connection {
|
||||
@Nullable
|
||||
StreamContext recogniseTag(TransportConnectionReader reader,
|
||||
TransportId transportId) {
|
||||
StreamContext ctx;
|
||||
try {
|
||||
byte[] tag = readTag(reader.getInputStream());
|
||||
return keyManager.getStreamContext(transportId, tag);
|
||||
|
||||
@@ -76,7 +76,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
ioExecutor.execute(new IncomingDuplexSyncConnection(keyManager,
|
||||
connectionRegistry, streamReaderFactory, streamWriterFactory,
|
||||
syncSessionFactory, transportPropertyManager, ioExecutor,
|
||||
t, d, handshakeManager));
|
||||
t, d));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,7 +101,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
ioExecutor.execute(new OutgoingDuplexSyncConnection(keyManager,
|
||||
connectionRegistry, streamReaderFactory, streamWriterFactory,
|
||||
syncSessionFactory, transportPropertyManager, ioExecutor,
|
||||
secureRandom, handshakeManager, c, t, d));
|
||||
secureRandom, c, t, d));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.connection;
|
||||
import org.briarproject.bramble.api.connection.ConnectionRegistry;
|
||||
import org.briarproject.bramble.api.connection.InterruptibleConnection;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.HandshakeManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
||||
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.connection;
|
||||
|
||||
import org.briarproject.bramble.api.connection.ConnectionRegistry;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.HandshakeManager;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
@@ -14,11 +13,9 @@ import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.bramble.api.transport.KeyManager;
|
||||
import org.briarproject.bramble.api.transport.StreamContext;
|
||||
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
||||
import org.briarproject.bramble.api.transport.StreamWriter;
|
||||
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
@@ -27,10 +24,6 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
@NotNullByDefault
|
||||
class IncomingDuplexSyncConnection extends DuplexSyncConnection
|
||||
implements Runnable {
|
||||
private final HandshakeManager handshakeManager;
|
||||
|
||||
// FIXME: Exchange timestamp as part of handshake protocol?
|
||||
private static final long TIMESTAMP = 1617235200; // 1 April 2021 00:00 UTC
|
||||
|
||||
IncomingDuplexSyncConnection(KeyManager keyManager,
|
||||
ConnectionRegistry connectionRegistry,
|
||||
@@ -39,18 +32,14 @@ class IncomingDuplexSyncConnection extends DuplexSyncConnection
|
||||
SyncSessionFactory syncSessionFactory,
|
||||
TransportPropertyManager transportPropertyManager,
|
||||
Executor ioExecutor, TransportId transportId,
|
||||
DuplexTransportConnection connection,
|
||||
HandshakeManager handshakeManager) {
|
||||
DuplexTransportConnection connection) {
|
||||
super(keyManager, connectionRegistry, streamReaderFactory,
|
||||
streamWriterFactory, syncSessionFactory,
|
||||
transportPropertyManager, ioExecutor, transportId, connection);
|
||||
this.handshakeManager = handshakeManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.info("Running IncomingDuplexSyncConnection on transport " +
|
||||
transportId.getString());
|
||||
// Read and recognise the tag
|
||||
StreamContext ctx = recogniseTag(reader, transportId);
|
||||
if (ctx == null) {
|
||||
@@ -65,22 +54,10 @@ class IncomingDuplexSyncConnection extends DuplexSyncConnection
|
||||
return;
|
||||
}
|
||||
if (ctx.isHandshakeMode()) {
|
||||
if (!performHandshake(ctx, contactId)) {
|
||||
LOG.warning("Handshake failed");
|
||||
return;
|
||||
}
|
||||
// Allocate a rotation mode stream context
|
||||
ctx = allocateStreamContext(contactId, transportId);
|
||||
if (ctx == null) {
|
||||
LOG.warning("Could not allocate stream context");
|
||||
onWriteError();
|
||||
return;
|
||||
}
|
||||
if (ctx.isHandshakeMode()) {
|
||||
LOG.warning("Got handshake mode context after handshaking");
|
||||
onWriteError();
|
||||
return;
|
||||
}
|
||||
// TODO: Support handshake mode for contacts
|
||||
LOG.warning("Received handshake tag, expected rotation mode");
|
||||
onReadError(true);
|
||||
return;
|
||||
}
|
||||
connectionRegistry.registerIncomingConnection(contactId, transportId,
|
||||
this);
|
||||
@@ -126,35 +103,5 @@ class IncomingDuplexSyncConnection extends DuplexSyncConnection
|
||||
onWriteError();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean performHandshake(StreamContext ctxIn, ContactId contactId) {
|
||||
LOG.info("Performing handshake (Incoming)");
|
||||
// Allocate the outgoing stream context
|
||||
StreamContext ctxOut =
|
||||
allocateStreamContext(contactId, transportId);
|
||||
if (ctxOut == null) {
|
||||
LOG.warning("Could not allocate stream context");
|
||||
onReadError(true);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
InputStream in = streamReaderFactory.createStreamReader(
|
||||
reader.getInputStream(), ctxIn);
|
||||
// Flush the output stream to send the outgoing stream header
|
||||
StreamWriter out = streamWriterFactory.createStreamWriter(
|
||||
writer.getOutputStream(), ctxOut);
|
||||
out.getOutputStream().flush();
|
||||
HandshakeManager.HandshakeResult result =
|
||||
handshakeManager.handshake(contactId, in, out);
|
||||
keyManager.addRotationKeys(contactId, result.getMasterKey(),
|
||||
TIMESTAMP, result.isAlice(), true);
|
||||
LOG.info("Rotation keys added");
|
||||
return true;
|
||||
} catch (IOException | DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
onReadError(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.bramble.connection;
|
||||
|
||||
import org.briarproject.bramble.api.connection.ConnectionRegistry;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.HandshakeManager;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
@@ -15,11 +14,9 @@ import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.bramble.api.transport.KeyManager;
|
||||
import org.briarproject.bramble.api.transport.StreamContext;
|
||||
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
||||
import org.briarproject.bramble.api.transport.StreamWriter;
|
||||
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -31,38 +28,26 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
class OutgoingDuplexSyncConnection extends DuplexSyncConnection
|
||||
implements Runnable {
|
||||
|
||||
// FIXME: Exchange timestamp as part of handshake protocol?
|
||||
private static final long TIMESTAMP = 1617235200; // 1 April 2021 00:00 UTC
|
||||
|
||||
private final SecureRandom secureRandom;
|
||||
private final HandshakeManager handshakeManager;
|
||||
private final ContactId contactId;
|
||||
|
||||
OutgoingDuplexSyncConnection(
|
||||
KeyManager keyManager,
|
||||
OutgoingDuplexSyncConnection(KeyManager keyManager,
|
||||
ConnectionRegistry connectionRegistry,
|
||||
StreamReaderFactory streamReaderFactory,
|
||||
StreamWriterFactory streamWriterFactory,
|
||||
SyncSessionFactory syncSessionFactory,
|
||||
TransportPropertyManager transportPropertyManager,
|
||||
Executor ioExecutor,
|
||||
SecureRandom secureRandom,
|
||||
HandshakeManager handshakeManager,
|
||||
ContactId contactId,
|
||||
TransportId transportId,
|
||||
DuplexTransportConnection connection) {
|
||||
Executor ioExecutor, SecureRandom secureRandom, ContactId contactId,
|
||||
TransportId transportId, DuplexTransportConnection connection) {
|
||||
super(keyManager, connectionRegistry, streamReaderFactory,
|
||||
streamWriterFactory, syncSessionFactory,
|
||||
transportPropertyManager, ioExecutor, transportId, connection);
|
||||
this.secureRandom = secureRandom;
|
||||
this.handshakeManager = handshakeManager;
|
||||
this.contactId = contactId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.info("Running OutgoingDuplexSyncConnection on transport " +
|
||||
transportId.getString());
|
||||
// Allocate a stream context
|
||||
StreamContext ctx = allocateStreamContext(contactId, transportId);
|
||||
if (ctx == null) {
|
||||
@@ -71,22 +56,10 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
|
||||
return;
|
||||
}
|
||||
if (ctx.isHandshakeMode()) {
|
||||
if (!performHandshake(ctx)) {
|
||||
LOG.warning("Handshake failed");
|
||||
return;
|
||||
}
|
||||
// Allocate a rotation mode stream context
|
||||
ctx = allocateStreamContext(contactId, transportId);
|
||||
if (ctx == null) {
|
||||
LOG.warning("Could not allocate stream context");
|
||||
onWriteError();
|
||||
return;
|
||||
}
|
||||
if (ctx.isHandshakeMode()) {
|
||||
LOG.warning("Got handshake mode context after handshaking");
|
||||
onWriteError();
|
||||
return;
|
||||
}
|
||||
// TODO: Support handshake mode for contacts
|
||||
LOG.warning("Cannot use handshake mode stream context");
|
||||
onWriteError();
|
||||
return;
|
||||
}
|
||||
// Start the incoming session on another thread
|
||||
Priority priority = generatePriority();
|
||||
@@ -154,59 +127,6 @@ class OutgoingDuplexSyncConnection extends DuplexSyncConnection
|
||||
}
|
||||
}
|
||||
|
||||
private boolean performHandshake(StreamContext ctxOut) {
|
||||
LOG.info("Performing handshake (Outgoing)");
|
||||
// Flush the output stream to send the outgoing stream header
|
||||
StreamWriter out;
|
||||
try {
|
||||
out = streamWriterFactory.createStreamWriter(
|
||||
writer.getOutputStream(), ctxOut);
|
||||
out.getOutputStream().flush();
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
onWriteError();
|
||||
return false;
|
||||
}
|
||||
// Read and recognise the tag
|
||||
StreamContext ctxIn = recogniseTag(reader, transportId);
|
||||
// Unrecognised tags are suspicious in this case
|
||||
if (ctxIn == null) {
|
||||
LOG.warning("Unrecognised tag for returning stream");
|
||||
onReadError();
|
||||
return false;
|
||||
}
|
||||
// Check that the stream comes from the expected contact
|
||||
ContactId inContactId = ctxIn.getContactId();
|
||||
if (contactId == null) {
|
||||
LOG.warning("Expected contact tag, got rendezvous tag");
|
||||
onReadError();
|
||||
return false;
|
||||
}
|
||||
if (!inContactId.equals(contactId)) {
|
||||
LOG.warning("Wrong contact ID for returning stream");
|
||||
onReadError();
|
||||
return false;
|
||||
}
|
||||
// TODO: Register the connection, close it if it's redundant
|
||||
// Handshake and exchange contacts
|
||||
try {
|
||||
InputStream in = streamReaderFactory.createStreamReader(
|
||||
reader.getInputStream(), ctxIn);
|
||||
HandshakeManager.HandshakeResult result =
|
||||
handshakeManager.handshake(contactId, in, out);
|
||||
keyManager.addRotationKeys(contactId, result.getMasterKey(),
|
||||
TIMESTAMP, result.isAlice(), true);
|
||||
LOG.info("Rotation keys added");
|
||||
return true;
|
||||
} catch (IOException | DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
onWriteError();
|
||||
return false;
|
||||
} finally {
|
||||
// TODO: Unregister the connection
|
||||
}
|
||||
}
|
||||
|
||||
private void onReadError() {
|
||||
// 'Recognised' is always true for outgoing connections
|
||||
onReadError(true);
|
||||
|
||||
@@ -71,8 +71,10 @@ class OutgoingSimplexSyncConnection extends SyncConnection implements Runnable {
|
||||
StreamWriter streamWriter = streamWriterFactory.createStreamWriter(
|
||||
w.getOutputStream(), ctx);
|
||||
ContactId c = requireNonNull(ctx.getContactId());
|
||||
// Use eager retransmission if the transport is lossy and cheap
|
||||
return syncSessionFactory.createSimplexOutgoingSession(c,
|
||||
ctx.getTransportId(), w.getMaxLatency(), streamWriter);
|
||||
ctx.getTransportId(), w.getMaxLatency(), w.isLossyAndCheap(),
|
||||
streamWriter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.briarproject.bramble.api.contact;
|
||||
package org.briarproject.bramble.contact;
|
||||
|
||||
public interface ContactExchangeConstants {
|
||||
interface ContactExchangeConstants {
|
||||
|
||||
/**
|
||||
* The current version of the contact exchange protocol.
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.bramble.api.contact;
|
||||
package org.briarproject.bramble.contact;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
@@ -6,7 +6,7 @@ import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface ContactExchangeCrypto {
|
||||
interface ContactExchangeCrypto {
|
||||
|
||||
/**
|
||||
* Derives the header key for a contact exchange stream from the master key.
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.contact;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeCrypto;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
@@ -11,12 +10,12 @@ import java.security.GeneralSecurityException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.ALICE_KEY_LABEL;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.ALICE_NONCE_LABEL;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.BOB_KEY_LABEL;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.BOB_NONCE_LABEL;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.SIGNING_LABEL;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.ALICE_KEY_LABEL;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.ALICE_NONCE_LABEL;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.BOB_KEY_LABEL;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.BOB_NONCE_LABEL;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.SIGNING_LABEL;
|
||||
|
||||
@NotNullByDefault
|
||||
class ContactExchangeCryptoImpl implements ContactExchangeCrypto {
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Predicate;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeCrypto;
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
@@ -48,8 +47,9 @@ import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.contact.ContactExchangeRecordTypes.CONTACT_INFO;
|
||||
import static org.briarproject.bramble.api.system.Clock.MIN_REASONABLE_TIME_MS;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.contact.ContactExchangeRecordTypes.CONTACT_INFO;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
|
||||
@@ -82,8 +82,7 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
||||
private final ContactManager contactManager;
|
||||
private final IdentityManager identityManager;
|
||||
private final TransportPropertyManager transportPropertyManager;
|
||||
private final org.briarproject.bramble.api.contact.ContactExchangeCrypto
|
||||
contactExchangeCrypto;
|
||||
private final ContactExchangeCrypto contactExchangeCrypto;
|
||||
private final StreamReaderFactory streamReaderFactory;
|
||||
private final StreamWriterFactory streamWriterFactory;
|
||||
|
||||
@@ -186,6 +185,10 @@ class ContactExchangeManagerImpl implements ContactExchangeManager {
|
||||
|
||||
// The agreed timestamp is the minimum of the peers' timestamps
|
||||
long timestamp = Math.min(localTimestamp, remoteInfo.timestamp);
|
||||
if (timestamp < MIN_REASONABLE_TIME_MS) {
|
||||
LOG.warning("Timestamp is too old");
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
// Add the contact
|
||||
Contact contact = addContact(p, remoteInfo.author, localAuthor,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.bramble.contact;
|
||||
|
||||
/**
|
||||
* Record types for the contact exchange protocol.
|
||||
*/
|
||||
interface ContactExchangeRecordTypes {
|
||||
|
||||
byte CONTACT_INFO = 0;
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||
import org.briarproject.bramble.api.crypto.CryptoConstants;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
@@ -120,18 +119,6 @@ class ContactManagerImpl implements ContactManager, EventListener {
|
||||
verified, active));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactId addContact(Transaction txn, Author remote, AuthorId local,
|
||||
PublicKey handshake, boolean verified)
|
||||
throws DbException, GeneralSecurityException {
|
||||
ContactId c = db.addContact(txn, remote, local, handshake, verified);
|
||||
Contact contact = db.getContact(txn, c);
|
||||
KeyPair ourKeyPair = identityManager.getHandshakeKeys(txn);
|
||||
keyManager.addContact(txn, c, handshake, ourKeyPair);
|
||||
for (ContactHook hook : hooks) hook.addingContact(txn, contact);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHandshakeLink() throws DbException {
|
||||
KeyPair keyPair = db.transactionWithResult(true,
|
||||
@@ -247,25 +234,6 @@ class ContactManagerImpl implements ContactManager, EventListener {
|
||||
db.transaction(false, txn -> setContactAlias(txn, c, alias));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHandshakePublicKey(Transaction txn, ContactId c,
|
||||
PublicKey handshakePublicKey) throws DbException, GeneralSecurityException {
|
||||
if (handshakePublicKey.getKeyType() !=
|
||||
CryptoConstants.KEY_TYPE_AGREEMENT) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
db.setHandshakePublicKey(txn, c, handshakePublicKey);
|
||||
KeyPair ourKeyPair = identityManager.getHandshakeKeys(txn);
|
||||
keyManager.addContact(txn, c, handshakePublicKey, ourKeyPair);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHandshakePublicKey(ContactId c, PublicKey handshakePublicKey)
|
||||
throws DbException, GeneralSecurityException {
|
||||
db.transaction(false,
|
||||
txn -> setHandshakePublicKey(txn, c, handshakePublicKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contactExists(Transaction txn, AuthorId remoteAuthorId,
|
||||
AuthorId localAuthorId) throws DbException {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.contact;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeCrypto;
|
||||
import org.briarproject.bramble.api.contact.ContactExchangeManager;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.HandshakeManager;
|
||||
|
||||
@@ -3,8 +3,6 @@ package org.briarproject.bramble.contact;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.Predicate;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.HandshakeManager;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
@@ -90,27 +88,6 @@ class HandshakeManagerImpl implements HandshakeManager {
|
||||
});
|
||||
PublicKey theirStaticPublicKey = keys.getFirst();
|
||||
KeyPair ourStaticKeyPair = keys.getSecond();
|
||||
return handshake(theirStaticPublicKey, ourStaticKeyPair, in, out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandshakeResult handshake(ContactId c, InputStream in,
|
||||
StreamWriter out) throws DbException, IOException {
|
||||
Pair<PublicKey, KeyPair> keys = db.transactionWithResult(true, txn -> {
|
||||
Contact contact = contactManager.getContact(txn, c);
|
||||
PublicKey handshakePublicKey = contact.getHandshakePublicKey();
|
||||
if (handshakePublicKey == null) throw new DbException();
|
||||
KeyPair keyPair = identityManager.getHandshakeKeys(txn);
|
||||
return new Pair<>(handshakePublicKey, keyPair);
|
||||
});
|
||||
PublicKey theirStaticPublicKey = keys.getFirst();
|
||||
KeyPair ourStaticKeyPair = keys.getSecond();
|
||||
return handshake(theirStaticPublicKey, ourStaticKeyPair, in, out);
|
||||
}
|
||||
|
||||
private HandshakeResult handshake(PublicKey theirStaticPublicKey,
|
||||
KeyPair ourStaticKeyPair, InputStream in, StreamWriter out)
|
||||
throws IOException {
|
||||
boolean alice = transportCrypto.isAlice(theirStaticPublicKey,
|
||||
ourStaticKeyPair);
|
||||
RecordReader recordReader = recordReaderFactory.createRecordReader(in);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package org.briarproject.bramble.api.crypto;
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface AuthenticatedCipher {
|
||||
interface AuthenticatedCipher {
|
||||
|
||||
/**
|
||||
* Initializes this cipher for encryption or decryption with a key and an
|
||||
@@ -4,9 +4,11 @@ import net.i2p.crypto.eddsa.EdDSAPrivateKey;
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey;
|
||||
import net.i2p.crypto.eddsa.KeyPairGenerator;
|
||||
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
import org.bouncycastle.crypto.Digest;
|
||||
import org.bouncycastle.crypto.digests.Blake2bDigest;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.DecryptionException;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
@@ -21,9 +23,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.spongycastle.crypto.CryptoException;
|
||||
import org.spongycastle.crypto.Digest;
|
||||
import org.spongycastle.crypto.digests.Blake2bDigest;
|
||||
import org.whispersystems.curve25519.Curve25519;
|
||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
|
||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.bouncycastle.crypto.BasicAgreement;
|
||||
import org.bouncycastle.crypto.BlockCipher;
|
||||
import org.bouncycastle.crypto.CipherParameters;
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
import org.bouncycastle.crypto.DerivationFunction;
|
||||
import org.bouncycastle.crypto.KeyEncoder;
|
||||
import org.bouncycastle.crypto.Mac;
|
||||
import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||
import org.bouncycastle.crypto.engines.AESLightEngine;
|
||||
import org.bouncycastle.crypto.engines.IESEngine;
|
||||
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
|
||||
import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator;
|
||||
import org.bouncycastle.crypto.generators.KDF2BytesGenerator;
|
||||
import org.bouncycastle.crypto.macs.HMac;
|
||||
import org.bouncycastle.crypto.modes.CBCBlockCipher;
|
||||
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
|
||||
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.crypto.params.IESWithCipherParameters;
|
||||
import org.bouncycastle.crypto.parsers.ECIESPublicKeyParser;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
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 org.briarproject.bramble.util.StringUtils;
|
||||
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
|
||||
import org.spongycastle.asn1.x9.X9ECParameters;
|
||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.spongycastle.crypto.BasicAgreement;
|
||||
import org.spongycastle.crypto.BlockCipher;
|
||||
import org.spongycastle.crypto.CipherParameters;
|
||||
import org.spongycastle.crypto.CryptoException;
|
||||
import org.spongycastle.crypto.DerivationFunction;
|
||||
import org.spongycastle.crypto.KeyEncoder;
|
||||
import org.spongycastle.crypto.Mac;
|
||||
import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||
import org.spongycastle.crypto.engines.AESLightEngine;
|
||||
import org.spongycastle.crypto.engines.IESEngine;
|
||||
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||
import org.spongycastle.crypto.generators.EphemeralKeyPairGenerator;
|
||||
import org.spongycastle.crypto.generators.KDF2BytesGenerator;
|
||||
import org.spongycastle.crypto.macs.HMac;
|
||||
import org.spongycastle.crypto.modes.CBCBlockCipher;
|
||||
import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
|
||||
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.spongycastle.crypto.params.ECDomainParameters;
|
||||
import org.spongycastle.crypto.params.ECKeyGenerationParameters;
|
||||
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.spongycastle.crypto.params.IESWithCipherParameters;
|
||||
import org.spongycastle.crypto.parsers.ECIESPublicKeyParser;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.bouncycastle.crypto.generators.SCrypt;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.spongycastle.crypto.generators.SCrypt;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.math.ec.ECCurve;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
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 org.spongycastle.crypto.params.ECDomainParameters;
|
||||
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.spongycastle.math.ec.ECCurve;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.crypto.StreamDecrypter;
|
||||
import org.briarproject.bramble.api.crypto.StreamDecrypterFactory;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.crypto.StreamDecrypter;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user