Skip to content

Commit 87e8cf3

Browse files
committed
Prepare SNMessage to be used in SN2 Android App
1 parent 172fdc1 commit 87e8cf3

File tree

11 files changed

+202
-413
lines changed

11 files changed

+202
-413
lines changed

src/net/sharksystem/asap/sharknet/SharkNetMessage.java renamed to src/net/sharksystem/asap/sharknet/InMemoSNMessage.java

Lines changed: 92 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import java.io.ByteArrayInputStream;
1010
import java.io.ByteArrayOutputStream;
1111
import java.io.IOException;
12+
import java.sql.Timestamp;
13+
import java.util.Date;
1214
import java.util.HashSet;
1315
import java.util.Set;
1416

@@ -17,87 +19,54 @@
1719
* null (to anybody), one or more recipients. A message can be signed. A message that is for a single recipient
1820
* can be encrypted.
1921
*/
20-
public class SharkNetMessage {
21-
private static final int SIGNED_MASK = 0x1;
22-
private static final int ENCRYPTED_MASK = 0x2;
23-
public static final CharSequence ANY_RECIPIENT = "SN_ANY";
24-
public static final CharSequence ANONYMOUS = "SN_ANON";
22+
public class InMemoSNMessage implements SNMessage {
2523
private byte[] snContent;
2624
private final CharSequence snSender;
27-
private byte[] serializedMessage;
2825
private boolean verified;
2926
private boolean encrypted;
30-
private final CharSequence topic;
3127
private Set<CharSequence> snRecipients;
32-
33-
SharkNetMessage(byte[] snContent, String snSender, boolean verified, boolean encrypted) {
34-
this(snContent, null, snSender, new HashSet<>(), verified, encrypted);
35-
}
28+
private Timestamp creationTime;
3629

3730
/**
3831
* Received
3932
* @param message
40-
* @param topic
4133
* @param sender
4234
* @param verified
4335
* @param encrypted
4436
*/
45-
SharkNetMessage(byte[] message, CharSequence topic, CharSequence sender,
46-
Set<CharSequence> snRecipients,
47-
boolean verified, boolean encrypted) {
37+
private InMemoSNMessage(byte[] message, CharSequence sender,
38+
Set<CharSequence> snRecipients, Timestamp creationTime,
39+
boolean verified, boolean encrypted) {
4840
this.snContent = message;
4941
this.snSender = sender;
5042
this.verified = verified;
5143
this.encrypted = encrypted;
52-
this.topic = topic;
5344
this.snRecipients = snRecipients;
45+
this.creationTime = creationTime;
5446
}
5547

56-
/**
57-
* Use this constructor to set a message that is to be sent
58-
* @param content content
59-
* @param topic uri
60-
* @param sender sender - me - or a synonym
61-
* @param recipient message recipient
62-
* @param sign sing message
63-
* @param encrypt encrypt message
64-
*/
65-
public SharkNetMessage(byte[] content, CharSequence topic, CharSequence sender, CharSequence recipient,
66-
boolean sign, boolean encrypt, BasicKeyStore basicKeyStore)
67-
throws IOException, ASAPException {
48+
static byte[] serializeMessage(byte[] content, CharSequence sender, CharSequence recipient)
49+
throws IOException, ASAPException {
6850

69-
this.snContent = content;
70-
this.snSender = sender;
71-
this.topic = topic;
51+
Set<CharSequence> recipients = null;
52+
if(recipient != null) {
53+
recipients = new HashSet<>();
54+
recipients.add(recipient);
55+
}
7256

73-
this.serializedMessage =
74-
SharkNetMessage.serializeMessage(content, topic, recipient,
75-
sign, encrypt, sender, basicKeyStore);
57+
return InMemoSNMessage.serializeMessage(content, sender, recipients,
58+
false, false, null);
7659
}
7760

78-
/**
79-
* Use this constructor to set a message that is to be sent
80-
* @param content
81-
* @param topic
82-
* @param sender
83-
* @param recipients more than one recipient - such a message cannot (yet) be signed. See group key project.
84-
* @param sign
85-
*/
86-
public SharkNetMessage(byte[] content, CharSequence topic, CharSequence sender,
87-
Set<CharSequence> recipients, boolean sign,
88-
BasicKeyStore basicKeyStore) throws IOException, ASAPException {
89-
90-
this.snSender = sender;
91-
this.topic = topic;
92-
93-
this.serializedMessage =
94-
SharkNetMessage.serializeMessage(content, topic, recipients,
95-
sign, false, sender, basicKeyStore);
61+
static byte[] serializeMessage(byte[] content, CharSequence sender, Set<CharSequence> recipients)
62+
throws IOException, ASAPException {
9663

64+
return InMemoSNMessage.serializeMessage(content, sender, recipients,
65+
false, false, null);
9766
}
9867

99-
static byte[] serializeMessage(byte[] message, CharSequence topic, CharSequence recipient,
100-
boolean sign, boolean encrypt, CharSequence ownerID,
68+
static byte[] serializeMessage(byte[] content, CharSequence sender, CharSequence recipient,
69+
boolean sign, boolean encrypt,
10170
BasicKeyStore basicKeyStore)
10271
throws IOException, ASAPException {
10372

@@ -107,13 +76,13 @@ static byte[] serializeMessage(byte[] message, CharSequence topic, CharSequence
10776
recipients.add(recipient);
10877
}
10978

110-
return SharkNetMessage.serializeMessage(message, topic, recipients,
111-
sign, encrypt, ownerID, basicKeyStore);
79+
return InMemoSNMessage.serializeMessage(content, sender, recipients,
80+
sign, encrypt, basicKeyStore);
11281

11382
}
11483

115-
static byte[] serializeMessage(byte[] content, CharSequence topic, Set<CharSequence> recipients,
116-
boolean sign, boolean encrypt, CharSequence sender, BasicKeyStore basicKeyStore)
84+
static byte[] serializeMessage(byte[] content, CharSequence sender, Set<CharSequence> recipients,
85+
boolean sign, boolean encrypt, BasicKeyStore basicKeyStore)
11786
throws IOException, ASAPException {
11887

11988
if( (recipients != null && recipients.size() > 1) && encrypt) {
@@ -122,19 +91,28 @@ static byte[] serializeMessage(byte[] content, CharSequence topic, Set<CharSeque
12291

12392
if(recipients == null) {
12493
recipients = new HashSet<>();
125-
recipients.add(SharkNetMessage.ANY_RECIPIENT);
94+
recipients.add(SNMessage.ANY_RECIPIENT);
12695
}
12796

12897
if(sender == null) {
129-
sender = SharkNetMessage.ANONYMOUS;
98+
sender = SNMessage.ANONYMOUS;
13099
}
131100

101+
/////////// produce serialized structure
102+
132103
// merge content, sender and recipient
133104
ByteArrayOutputStream baos = new ByteArrayOutputStream();
105+
///// content
134106
ASAPSerialization.writeByteArray(content, baos);
107+
///// sender
135108
ASAPSerialization.writeCharSequenceParameter(sender, baos);
136-
// ASAPSerialization.writeCharSequenceParameter(recipient, baos);
109+
///// recipients
137110
ASAPSerialization.writeCharSequenceSetParameter(recipients, baos);
111+
///// timestamp
112+
Timestamp creationTime = new Timestamp(System.currentTimeMillis());
113+
String timestampString = creationTime.toString();
114+
ASAPSerialization.writeCharSequenceParameter(timestampString, baos);
115+
138116
content = baos.toByteArray();
139117

140118
byte flags = 0;
@@ -165,24 +143,58 @@ static byte[] serializeMessage(byte[] content, CharSequence topic, Set<CharSeque
165143
return baos.toByteArray();
166144
}
167145

168-
public static SharkNetMessage parseMessage(byte[] message, String uri,
169-
CharSequence ownerID, BasicKeyStore basicKeyStore) throws IOException, ASAPException {
146+
@Override
147+
public byte[] getContent() { return this.snContent;}
148+
@Override
149+
public CharSequence getSender() { return this.snSender; }
150+
@Override
151+
public Set<CharSequence> getRecipients() { return this.snRecipients; }
152+
@Override
153+
public boolean verified() { return this.verified; }
154+
@Override
155+
public boolean encrypted() { return this.encrypted; }
156+
157+
@Override
158+
public Timestamp getCreationTime() {
159+
return this.creationTime;
160+
}
161+
162+
@Override
163+
public boolean isLaterThan(SNMessage message) throws ASAPException, IOException {
164+
Date sentDateMessage = message.getCreationTime();
165+
Date sentDateMe = this.getCreationTime();
166+
167+
return sentDateMe.after(sentDateMessage);
168+
}
169+
//////////////////////////////////////////////////////////////////////////////////////////
170+
// factory methods //
171+
//////////////////////////////////////////////////////////////////////////////////////////
172+
173+
static InMemoSNMessage parseMessage(byte[] message)
174+
throws IOException, ASAPException {
175+
176+
return InMemoSNMessage.parseMessage(message, null);
177+
178+
}
179+
180+
static InMemoSNMessage parseMessage(byte[] message, BasicKeyStore basicKeyStore)
181+
throws IOException, ASAPException {
170182

171183
ByteArrayInputStream bais = new ByteArrayInputStream(message);
172184
byte flags = ASAPSerialization.readByte(bais);
173185
byte[] tmpMessage = ASAPSerialization.readByteArray(bais);
174186

175-
boolean signed = (flags & SIGNED_MASK) != 0;
176-
boolean encrypted = (flags & ENCRYPTED_MASK) != 0;
187+
boolean signed = (flags & SNMessage.SIGNED_MASK) != 0;
188+
boolean encrypted = (flags & SNMessage.ENCRYPTED_MASK) != 0;
177189

178-
if(encrypted) {
190+
if (encrypted) {
179191
// decrypt
180192
bais = new ByteArrayInputStream(tmpMessage);
181193
ASAPCryptoAlgorithms.EncryptedMessagePackage
182194
encryptedMessagePackage = ASAPCryptoAlgorithms.parseEncryptedMessagePackage(bais);
183195

184196
// for me?
185-
if(!encryptedMessagePackage.getRecipient().equals(ownerID)) {
197+
if (!basicKeyStore.isOwner(encryptedMessagePackage.getRecipient())) {
186198
throw new ASAPException("SharkNetMessage: message not for me");
187199
}
188200

@@ -193,41 +205,38 @@ public static SharkNetMessage parseMessage(byte[] message, String uri,
193205

194206
byte[] signature = null;
195207
byte[] signedMessage = null;
196-
if(signed) {
208+
if (signed) {
197209
// split message from signature
198210
bais = new ByteArrayInputStream(tmpMessage);
199211
tmpMessage = ASAPSerialization.readByteArray(bais);
200212
signedMessage = tmpMessage;
201213
signature = ASAPSerialization.readByteArray(bais);
202214
}
215+
216+
///////////////// produce object form serialized bytes
203217
bais = new ByteArrayInputStream(tmpMessage);
218+
219+
////// content
204220
byte[] snMessage = ASAPSerialization.readByteArray(bais);
221+
////// sender
205222
String snSender = ASAPSerialization.readCharSequenceParameter(bais);
223+
////// recipients
206224
Set<CharSequence> snReceivers = ASAPSerialization.readCharSequenceSetParameter(bais);
207-
//String snReceiver = ASAPSerialization.readCharSequenceParameter(bais);
225+
///// timestamp
226+
String timestampString = ASAPSerialization.readCharSequenceParameter(bais);
227+
Timestamp creationTime = Timestamp.valueOf(timestampString);
208228

209229
boolean verified = false; // initialize
210-
if(signature != null) {
230+
if (signature != null) {
211231
try {
212232
verified = ASAPCryptoAlgorithms.verify(
213233
signedMessage, signature, snSender, basicKeyStore);
214-
}
215-
catch(ASAPSecurityException e) {
234+
} catch (ASAPSecurityException e) {
216235
// verified definitely false
217236
verified = false;
218237
}
219238
}
220239

221-
return new SharkNetMessage(snMessage, uri, snSender, snReceivers, verified, encrypted);
222-
}
223-
224-
public byte[] getContent() { return this.snContent;}
225-
public CharSequence getSender() { return this.snSender; }
226-
public Set<CharSequence> getRecipients() { return this.snRecipients; }
227-
public boolean verified() { return this.verified; }
228-
public boolean encrypted() { return this.encrypted; }
229-
230-
public byte[] getSerializedMessage() {
231-
return this.serializedMessage;
240+
return new InMemoSNMessage(snMessage, snSender, snReceivers, creationTime, verified, encrypted);
232241
}
233242
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package net.sharksystem.asap.sharknet;
2+
3+
import net.sharksystem.asap.ASAPException;
4+
5+
import java.io.IOException;
6+
import java.sql.Timestamp;
7+
import java.util.Set;
8+
9+
public interface SNMessage {
10+
CharSequence ANY_RECIPIENT = "SN_ANY";
11+
CharSequence ANONYMOUS = "SN_ANON";
12+
int SIGNED_MASK = 0x1;
13+
int ENCRYPTED_MASK = 0x2;
14+
15+
/**
16+
* Content - can be encrypted and signed
17+
* @return
18+
*/
19+
byte[] getContent();
20+
21+
/**
22+
* Sender - can be encrypted and signed
23+
* @return
24+
*/
25+
CharSequence getSender();
26+
27+
/**
28+
* Recipients are always visible - the only recipient is in the unencrypted head if message
29+
* is encrypted - maybe we change this in a later version.
30+
* @return
31+
*/
32+
Set<CharSequence> getRecipients();
33+
34+
/**
35+
* Not part of the transferred message - just a flag that indicates if this message could now
36+
* be verified. This can change over time, though. A non-verifiable message can be verified if the
37+
* right certificate arrives. A verifiable message can become non-verifiable due to loss of certificates
38+
* validity. In short: Result can change state of your local PKI
39+
* @return
40+
*/
41+
boolean verified();
42+
43+
/**
44+
* Not part of the transferred message - just a flag that indicates if this message can be encrypted.
45+
* This can change over time depending on status of local PKI. Any encrypted message is unencryptable
46+
* if the local private key gets invalid or if this message was not sent to this local peer.
47+
* @return
48+
*/
49+
boolean encrypted();
50+
51+
/**
52+
* Creation date is produced when an object is serialized. It becomes part of the message.
53+
* @return
54+
* @throws ASAPException
55+
* @throws IOException
56+
*/
57+
Timestamp getCreationTime() throws ASAPException, IOException;
58+
59+
/**
60+
* Compare two message what creation date is earlier. It depends on local clocks. It is a hint not more.
61+
* Could need a better solution.
62+
*
63+
* @param message
64+
* @return
65+
* @throws ASAPException
66+
* @throws IOException
67+
*/
68+
boolean isLaterThan(SNMessage message) throws ASAPException, IOException;
69+
}

src/net/sharksystem/asap/sharknet/SharkNet.java

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/net/sharksystem/asap/sharknet/SharkNetMessageListener.java

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/net/sharksystem/asap/sharknet/SharkNetPeer.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)