Skip to content

Commit 8ec7ce7

Browse files
committed
Add contributing file, update license, readme and releasing file
1 parent 17d3e57 commit 8ec7ce7

File tree

4 files changed

+242
-38
lines changed

4 files changed

+242
-38
lines changed

CONTRIBUTING.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Contributors Guideline
2+
3+
Thanks a lot for any contribution!
4+
5+
To keep code quality high and maintenance work low, please adhere to the
6+
following guidelines when creating a pull request:
7+
8+
## Style Guide
9+
10+
Try to write clean code and to adhere to the already used coding style.
11+
12+
Lines should be kept below 120 characters.
13+
14+
## Tests
15+
16+
If possible, new code should be covered by automated tests.
17+
18+
## Commit messages
19+
20+
Use meaningful commit messages: Please follow the advice in [this
21+
blogpost](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
22+
First line of your commit message should be a very short summary (ideally 50
23+
characters or less) in the imperative mood. After the first line of the commit
24+
message, add a blank line and then a more detailed explanation (when relevant).

LICENSE-MIT

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2016-2017 Threema GmbH
1+
Copyright (c) 2016-2019 Threema GmbH
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy
44
of this software and associated documentation files (the "Software"), to deal

README.md

+215-34
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
# SaltyRTC WebRTC Task for Java
22

3-
[![Java Version](https://img.shields.io/badge/java-8%2B-orange.svg)](https://github.com/saltyrtc/saltyrtc-client-java)
4-
[![License](https://img.shields.io/badge/license-MIT%20%2F%20Apache%202.0-blue.svg)](https://github.com/saltyrtc/saltyrtc-client-java)
3+
[![Build status](https://circleci.com/gh/saltyrtc/saltyrtc-task-webrtc-java.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/saltyrtc/saltyrtc-task-webrtc-java)
4+
[![Java Version](https://img.shields.io/badge/java-8%2B-orange.svg)](https://github.com/saltyrtc/saltyrtc-task-webrtc-java)
5+
[![License](https://img.shields.io/badge/license-MIT%20%2F%20Apache%202.0-blue.svg)](https://github.com/saltyrtc/saltyrtc-task-webrtc-java)
56
[![Chat on Gitter](https://badges.gitter.im/saltyrtc/Lobby.svg)](https://gitter.im/saltyrtc/Lobby)
67

78
This is a [SaltyRTC](https://github.com/saltyrtc/saltyrtc-meta) [WebRTC
89
task](https://github.com/saltyrtc/saltyrtc-meta/blob/master/Task-WebRTC.md)
910
implementation for Java 8+.
1011

11-
For now, as long as `RTCPeerConnection` only works on Android, this library
12-
will not work outside of projects.
13-
14-
The development is still ongoing, the current version is only at alpha-level
15-
and should not be used for production yet.
16-
1712
For an application example, please see our [demo
1813
application](https://github.com/saltyrtc/saltyrtc-demo).
1914

2015

2116
## Installing
2217

2318
The package is available [on
24-
Bintray](https://bintray.com/saltyrtc/maven/saltyrtc-client/).
19+
Bintray](https://bintray.com/saltyrtc/maven/saltyrtc-task-webrtc).
2520

2621
Gradle:
2722

@@ -43,70 +38,171 @@ Maven:
4338

4439
## Usage
4540

46-
Instantiate the task.
41+
To create the task instance, you need to use the `WebRTCTaskBuilder` instance
42+
which can be used to configure the task before creating it.
43+
44+
The below configuration represents the default values chosen by the builder as
45+
if you had not configured the builder and just called `.build()` directly.
4746

4847
```java
49-
final WebRTCTask task = new WebRTCTask();
48+
final WebRTCTask task = new WebRTCTaskBuilder()
49+
.withVersion(WebRTCTaskVersion.V1)
50+
.withHandover(true)
51+
.withMaxChunkLength(262144)
52+
.build();
5053
```
5154

52-
Then, register a message handler:
55+
To send offers, answers and candidates, use the following task methods:
56+
57+
* `task.sendOffer(offer: @NonNull Offer): void`
58+
* `task.sendAnswer(answer: @NonNull Answer): void`
59+
* `task.sendCandidates(candidate: @NonNull Candidate[]): void`
60+
61+
You can register an event handler in the following way:
5362

5463
```java
5564
task.setMessageHandler(new MessageHandler() {
5665
@Override
57-
public void onOffer(SessionDescription sd) {
66+
public void onOffer(@NonNull Offer offer) {
5867
// Handle offer
5968
}
6069

6170
@Override
62-
public void onAnswer(SessionDescription sd) {
71+
public void onAnswer(@NonNull Answer answer) {
6372
// Handle answer
6473
}
6574

6675
@Override
67-
public void onCandidates(List<IceCandidate> candidates) {
68-
for (IceCandidate candidate : candidates) {
69-
peerConnection.addIceCandidate(candidate);
70-
}
76+
public void onCandidates(@NonNull Candidate[] candidates) {
77+
// Handle candidates
7178
}
7279
});
7380
```
7481

75-
Finally, pass the task instance to the `SaltyRTCBuilder` through the
76-
`.usingTasks(...)` method.
82+
### Data Channel Crypto Context
83+
84+
The task provides another security layer for data channels which can be
85+
leveraged by usage of a `DataChannelCryptoContext` instance. To retrieve such
86+
an instance, call:
87+
88+
```java
89+
final DataChannelCryptoContext context = task.createCryptoContext(dataChannel.id);
90+
```
91+
92+
You can encrypt messages on the sending end in the following way:
93+
94+
```java
95+
final Box box = context.encrypt(yourData);
96+
dataChannel.send(ByteBuffer.wrap(box.toBytes()));
97+
```
98+
99+
On the receiving end, decrypt the message by the use of the crypto context:
100+
101+
```java
102+
final Box box = new Box(message);
103+
final byte[] yourData = context.decrypt(
104+
box, DataChannelCryptoContext.NONCE_LENGTH);
105+
```
77106

78-
Once the signaling channel is open, create offer/answer/candidates as usual and
79-
send them through the signaling channel using the corresponding methods:
107+
Note, that you should not use a crypto context for a data channel that is being
108+
used for handover. The task will take care of encryption and decryption itself.
80109

81-
- `task.sendOffer(offer)`
82-
- `task.sendAnswer(answer)`
83-
- `task.sendCandidates(candidates)`
110+
### Handover
111+
112+
Before initiating the handover, the application needs to fetch the
113+
`SignalingTransportLink` instance which contains the necessary information to
114+
create a data channel.
115+
116+
```java
117+
final SignalingTransportLink link = task.getTransportLink();
118+
119+
final DataChannel.Init parameters = new DataChannel.Init();
120+
parameters.id = link.getId();
121+
parameters.negotiated = true;
122+
parameters.ordered = true;
123+
parameters.protocol = link.getProtocol();
124+
125+
final DataChannel dataChannel = peerConnection.createDataChannel(
126+
link.getLabel(), parameters);
127+
```
128+
129+
Note that the data channel used for handover **must** be created with the
130+
label and parameters as shown in the above code snippet.
131+
132+
Now that you have created the channel, you need to implement the
133+
`ISignalingTransportHandler` interface. Below is a minimal handler that forwards
134+
the necessary events and messages to the created data channel.
135+
136+
```java
137+
final ISignalingTransportHandler handler = new ISignalingTransportHandler() {
138+
@Override
139+
public long getMaxMessageSize() {
140+
return peerConnection.sctp().getMaxMessageSize();
141+
}
142+
143+
@Override
144+
public void close() {
145+
dataChannel.close();
146+
}
147+
148+
@Override
149+
public void send(@NonNull final ByteBuffer message) {
150+
// Note: Always send binary
151+
dataChannel.send(new DataChannel.Buffer(message, true));
152+
}
153+
};
154+
```
84155

85-
As soon as the data channel is open, request a handover of the signaling channel:
156+
Furthermore, you have to bind all necessary events in order to connect the data
157+
channel to the `SignalingTransportLink`.
86158

87159
```java
88-
dc.registerObserver(new DataChannel.Observer() {
89-
// ...
160+
dataChannel.registerObserver(new DataChannel.Observer() {
161+
// [...]
90162

91163
@Override
92164
public void onStateChange() {
93-
if (dc.state() == DataChannel.State.OPEN) {
94-
task.handover();
165+
switch (dataChannel.state()) {
166+
case OPEN:
167+
task.handover(handler);
168+
break;
169+
case CLOSING:
170+
link.closing();
171+
break;
172+
case CLOSED:
173+
link.closed();
174+
break;
95175
}
96176
}
177+
178+
@Override
179+
public void onMessage(@NonNull final DataChannel.Buffer buffer) {
180+
if (!buffer.binary) {
181+
// Note: This should be handled as a protocol error
182+
task.close(CloseCode.PROTOCOL_ERROR);
183+
} else {
184+
link.receive(buffer.data);
185+
}
186+
}
187+
188+
// [...]
97189
});
98190
```
99191

100-
To know when the handover is done, subscribe to the SaltyRTC `handover` event.
192+
The above setup will forward the `CLOSING`/`CLOSED` state and all messages to
193+
the task by the use of the `SignalingTransportLink`. On `OPEN`, the handover
194+
will be initiated.
101195

196+
To be signalled once the handover is finished, you need to register the
197+
`handover` event on the SaltyRTC client instance.
102198

103-
## Logging
199+
### Logging
104200

105201
The library uses the slf4j logging API. Configure a logger (e.g. slf4j-simple)
106202
to see the log output.
107203

108204

109-
## Testing
205+
## Manual Testing
110206

111207
To try a development version of the library, you can build a local version to
112208
the maven repository at `/tmp/maven`:
@@ -121,7 +217,76 @@ Include it in your project like this:
121217
}
122218

123219

124-
## Hashes
220+
## Coding Guidelines
221+
222+
Unfortunately we cannot use all Java 8 features, in order to be compatible with
223+
Android API <24. Please avoid using the following APIs:
224+
225+
- `java.lang.annotation.Repeatable`
226+
- `AnnotatedElement.getAnnotationsByType(Class)`
227+
- `java.util.stream`
228+
- `java.lang.FunctionalInterface`
229+
- `java.lang.reflect.Method.isDefault()`
230+
- `java.util.function`
231+
232+
The CI tests contains a script to ensure that these APIs aren't being called.
233+
You can also run it manually:
234+
235+
bash .circleci/check_android_support.sh
236+
237+
238+
## Automated Testing
239+
240+
### 1. Preparing the Server
241+
242+
First, clone the `saltyrtc-server-python` repository.
243+
244+
git clone https://github.com/saltyrtc/saltyrtc-server-python
245+
cd saltyrtc-server-python
246+
247+
Then create a test certificate for localhost, valid for 5 years.
248+
249+
openssl req -new -newkey rsa:1024 -nodes -sha256 \
250+
-out saltyrtc.csr -keyout saltyrtc.key \
251+
-subj '/C=CH/O=SaltyRTC/CN=localhost/'
252+
openssl x509 -req -days 1825 \
253+
-in saltyrtc.csr \
254+
-signkey saltyrtc.key -out saltyrtc.crt
255+
256+
Create a Java keystore containing this certificate.
257+
258+
keytool -import -trustcacerts -alias root \
259+
-file saltyrtc.crt -keystore saltyrtc.jks \
260+
-storetype JKS -storepass saltyrtc -noprompt
261+
262+
Create a Python virtualenv with dependencies:
263+
264+
python3 -m virtualenv venv
265+
venv/bin/pip install .[logging]
266+
267+
Finally, start the server with the following test permanent key:
268+
269+
export SALTYRTC_SERVER_PERMANENT_KEY=0919b266ce1855419e4066fc076b39855e728768e3afa773105edd2e37037c20 # Public: 09a59a5fa6b45cb07638a3a6e347ce563a948b756fd22f9527465f7c79c2a864
270+
venv/bin/saltyrtc-server -v 5 serve -p 8765 \
271+
-sc saltyrtc.crt -sk saltyrtc.key \
272+
-k $SALTYRTC_SERVER_PERMANENT_KEY
273+
274+
### 2. Running Tests
275+
276+
Make sure that the certificate keystore from the server is copied or symlinked
277+
to this repository:
278+
279+
ln -s path/to/saltyrtc-server-python/saltyrtc.jks
280+
281+
With the server started in the background and the `saltyrtc.jks` file in the
282+
current directory, run the tests:
283+
284+
./gradlew test
285+
286+
287+
## Security
288+
289+
### Release Checksums
125290

126291
These are the SHA256 hashes for the published releases of this project:
127292

@@ -152,6 +317,22 @@ You can use tools like [gradle
152317
witness](https://github.com/WhisperSystems/gradle-witness) to make sure that
153318
your application always gets the correct version of this library.
154319

320+
### Responsible Disclosure / Reporting Security Issues
321+
322+
Please report security issues directly to one or both of the following contacts:
323+
324+
- Danilo Bargen
325+
326+
- Threema: EBEP4UCA
327+
- GPG: [EA456E8BAF0109429583EED83578F667F2F3A5FA][keybase-dbrgn]
328+
- Lennart Grahl
329+
330+
- Threema: MSFVEW6C
331+
- GPG: [3FDB14868A2B36D638F3C495F98FBED10482ABA6][keybase-lgrahl]
332+
333+
[keybase-dbrgn]: https://keybase.io/dbrgn
334+
[keybase-lgrahl]: https://keybase.io/lgrahl
335+
155336

156337
## License
157338

RELEASING.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ Update version numbers:
1414
Build:
1515

1616
rm -r build
17-
./gradlew build
17+
./gradlew build publish
1818

1919
Add hash to README.md:
2020

21-
sha256sum build/outputs/aar/saltyrtc-task-webrtc-release.aar
21+
sha256sum build/libs/saltyrtc-task-webrtc.jar
2222

2323
Add and commit:
2424

@@ -32,4 +32,3 @@ Tag and push:
3232

3333
git tag -s -u ${GPG_KEY} v${VERSION} -m "Version ${VERSION}"
3434
git push && git push --tags
35-

0 commit comments

Comments
 (0)