1package eu.siacs.conversations.xmpp.jingle;
2
3import com.google.common.base.MoreObjects;
4import com.google.common.base.Preconditions;
5
6import java.util.concurrent.atomic.AtomicBoolean;
7
8import eu.siacs.conversations.crypto.axolotl.AxolotlService;
9
10public class OmemoVerification {
11
12 private final AtomicBoolean deviceIdWritten = new AtomicBoolean(false);
13 private final AtomicBoolean sessionFingerprintWritten = new AtomicBoolean(false);
14 private Integer deviceId;
15 private String sessionFingerprint;
16
17 public void setDeviceId(final Integer id) {
18 if (deviceIdWritten.compareAndSet(false, true)) {
19 this.deviceId = id;
20 return;
21 }
22 throw new IllegalStateException("Device Id has already been set");
23 }
24
25 public int getDeviceId() {
26 Preconditions.checkNotNull(this.deviceId, "Device ID is null");
27 return this.deviceId;
28 }
29
30 public boolean hasDeviceId() {
31 return this.deviceId != null;
32 }
33
34 public void setSessionFingerprint(final String fingerprint) {
35 Preconditions.checkNotNull(fingerprint, "Session fingerprint must not be null");
36 if (sessionFingerprintWritten.compareAndSet(false, true)) {
37 this.sessionFingerprint = fingerprint;
38 return;
39 }
40 throw new IllegalStateException("Session fingerprint has already been set");
41 }
42
43 public String getFingerprint() {
44 return this.sessionFingerprint;
45 }
46
47 public void setOrEnsureEqual(AxolotlService.OmemoVerifiedPayload<?> omemoVerifiedPayload) {
48 setOrEnsureEqual(omemoVerifiedPayload.getDeviceId(), omemoVerifiedPayload.getFingerprint());
49 }
50
51 public void setOrEnsureEqual(final int deviceId, final String sessionFingerprint) {
52 Preconditions.checkNotNull(sessionFingerprint, "Session fingerprint must not be null");
53 if (this.deviceIdWritten.get() || this.sessionFingerprintWritten.get()) {
54 if (this.sessionFingerprint == null) {
55 throw new IllegalStateException("No session fingerprint has been previously provided");
56 }
57 if (!sessionFingerprint.equals(this.sessionFingerprint)) {
58 throw new SecurityException("Session Fingerprints did not match");
59 }
60 if (this.deviceId == null) {
61 throw new IllegalStateException("No Device Id has been previously provided");
62 }
63 if (this.deviceId != deviceId) {
64 throw new IllegalStateException("Device Ids did not match");
65 }
66 } else {
67 this.setSessionFingerprint(sessionFingerprint);
68 this.setDeviceId(deviceId);
69 }
70 }
71
72 public boolean hasFingerprint() {
73 return this.sessionFingerprint != null;
74 }
75
76 @Override
77 public String toString() {
78 return MoreObjects.toStringHelper(this)
79 .add("deviceId", deviceId)
80 .add("fingerprint", sessionFingerprint)
81 .toString();
82 }
83}