Skip to content

Commit d15d097

Browse files
committed
Encryption also runs with assimilation. Offer is not yet supported. I strongly consider to remove that protocol primitive anyway.
1 parent f3bb7ef commit d15d097

File tree

7 files changed

+396
-50
lines changed

7 files changed

+396
-50
lines changed

src/net/sharksystem/asap/protocol/CryptoMessage.java renamed to src/net/sharksystem/asap/protocol/ASAPCryptoMessage.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.io.*;
1010
import java.security.*;
1111

12-
class CryptoMessage {
12+
class ASAPCryptoMessage {
1313
private Signature signature;
1414
private CharSequence recipient;
1515
private ASAPBasicKeyStorage keyStorage;
@@ -24,13 +24,13 @@ class CryptoMessage {
2424
private byte[] encryptedSymmetricKey;
2525
private byte[] encryptedContent;
2626

27-
CryptoMessage(ASAPBasicKeyStorage keyStorage) {
27+
ASAPCryptoMessage(ASAPBasicKeyStorage keyStorage) {
2828
this.keyStorage = keyStorage;
2929
}
3030

31-
CryptoMessage(byte cmd, OutputStream os, boolean sign, boolean encrypted,
32-
CharSequence recipient,
33-
ASAPBasicKeyStorage keyStorage)
31+
ASAPCryptoMessage(byte cmd, OutputStream os, boolean sign, boolean encrypted,
32+
CharSequence recipient,
33+
ASAPBasicKeyStorage keyStorage)
3434
throws ASAPSecurityException {
3535

3636
this.cmd = cmd;
@@ -233,7 +233,7 @@ byte[] getCopy() {
233233
}
234234
}
235235

236-
public InputStream setupInputStreamCopier(int priorInt, InputStream is)
236+
public InputStream initVerifiction(int priorInt, InputStream is)
237237
throws IOException {
238238

239239
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -281,7 +281,7 @@ public boolean verify(String sender, InputStream is) throws IOException, ASAPExc
281281
*/
282282
public boolean initDecryption(byte cmd, InputStream is) throws IOException, ASAPException {
283283
// make a copy of read data
284-
InputStream copyStream = this.setupInputStreamCopier(cmd, is);
284+
InputStream copyStream = this.initVerifiction(cmd, is);
285285

286286
// read recipient
287287
this.recipient = PDU_Impl.readCharSequenceParameter(copyStream);
@@ -292,6 +292,11 @@ public boolean initDecryption(byte cmd, InputStream is) throws IOException, ASAP
292292
// read content
293293
this.encryptedContent = this.readByteArray(copyStream);
294294

295+
if(this.keyStorage == null) {
296+
System.out.println(this.getLogStart() + "no keystore set: cannot handle encrypted messages");
297+
return false;
298+
}
299+
295300
// read anything - are we recipient?
296301
if(this.keyStorage.isOwner(this.recipient)) {
297302
return true;

src/net/sharksystem/asap/protocol/ASAP_1_0.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,25 @@ void assimilate(CharSequence sender, CharSequence recipient, CharSequence format
141141
long length, List<Long> offsets, InputStream dataIS, OutputStream os, boolean signed)
142142
throws IOException, ASAPException;
143143

144+
/**
145+
*
146+
* @param sender sender (optional, can be null)
147+
* @param recipient wished recipient (optional, can be null)
148+
* @param channelUri mandatory
149+
* @param format mandatory
150+
* @param offsets applications will probably store a number of messages in a data block. This (optional) list
151+
* of numbers represents the offset where a new app specific message begins.
152+
* @param dataIS stream from which are read to be transmitted to recipient mandatory
153+
* @param os stream that PDU is to be sent
154+
* @param signed message is signed
155+
* @param encrypted encrypt or not
156+
* @throws IOException exception during writing on stream
157+
* @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, ..
158+
*/
159+
void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, CharSequence channelUri, int era,
160+
long length, List<Long> offsets, InputStream dataIS, OutputStream os, boolean signed, boolean encrypted)
161+
throws IOException, ASAPException;
162+
144163
/**
145164
*
146165
* @param sender sender (optional, can be null)
@@ -159,6 +178,25 @@ void assimilate(CharSequence sender, CharSequence recipient, CharSequence format
159178
List<Long> offsets, byte[] data, OutputStream os, boolean signed)
160179
throws IOException, ASAPException;
161180

181+
/**
182+
*
183+
* @param sender sender (optional, can be null)
184+
* @param recipient wished recipient (optional, can be null)
185+
* @param channel mandatory
186+
* @param format mandatory
187+
* @param offsets applications will probably store a number of messages in a data block. This (optional) list
188+
* of numbers represents the offset where a new app specific message begins.
189+
* @param data which are read to be transmitted to recipient mandatory
190+
* @param os stream that PDU is to be sent
191+
* @param signed message is signed
192+
* @param encrypted encrypt or not
193+
* @throws IOException exception during writing on stream
194+
* @throws ASAPException protocol exception: mandatory parameter missing, invalid combination of parameters, ..
195+
*/
196+
void assimilate(CharSequence sender, CharSequence recipient, CharSequence format, CharSequence channel, int era,
197+
List<Long> offsets, byte[] data, OutputStream os, boolean signed, boolean encrypted)
198+
throws IOException, ASAPException;
199+
162200

163201
ASAP_PDU_1_0 readPDU(InputStream is) throws IOException, ASAPException;
164202

src/net/sharksystem/asap/protocol/ASAP_AssimilationPDU_1_0.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ public interface ASAP_AssimilationPDU_1_0 extends ASAP_PDU_1_0 {
3838
* @param os
3939
* @throws IOException
4040
*/
41-
void streamData(OutputStream os, long length) throws IOException;
41+
void streamData(OutputStream os) throws IOException;
4242

4343
/**
4444
* return row input stream from protocol - handle with care!
4545
* @return
4646
*/
47-
public InputStream getInputStream();
47+
public InputStream getInputStream() throws IOException;
4848
}

src/net/sharksystem/asap/protocol/ASAP_Modem_Impl.java

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,10 @@ public void interest(CharSequence sender, CharSequence recipient, CharSequence f
7171
@Override
7272
public void interest(CharSequence sender, CharSequence recipient, CharSequence format,
7373
CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed,
74-
boolean encrypted)
75-
throws IOException, ASAPException, ASAPSecurityException {
74+
boolean encrypted) throws IOException, ASAPException {
7675

7776
// prepare encryption and signing if required
78-
CryptoMessage cryptoMessage = new CryptoMessage(ASAP_1_0.INTEREST_CMD,
77+
ASAPCryptoMessage cryptoMessage = new ASAPCryptoMessage(ASAP_1_0.INTEREST_CMD,
7978
os, signed, encrypted, recipient,
8079
this.signAndEncryptionKeyStorage);
8180

@@ -84,7 +83,7 @@ public void interest(CharSequence sender, CharSequence recipient, CharSequence f
8483
InterestPDU_Impl.sendPDUWithoutCmd(sender, recipient, format, channel, eraFrom, eraTo,
8584
cryptoMessage.getOutputStream(), signed);
8685

87-
// finish crypto session - if any
86+
// finish crypto session - maybe nothing has to be done
8887
cryptoMessage.finish();
8988
}
9089

@@ -93,19 +92,46 @@ public void assimilate(CharSequence sender, CharSequence recipient, CharSequence
9392
CharSequence channel, int era, long length, List<Long> offsets, InputStream dataIS,
9493
OutputStream os, boolean signed) throws IOException, ASAPException {
9594

96-
AssimilationPDU_Impl.sendPDU(sender, recipient, format, channel, era, length, offsets, dataIS, os, signed);
95+
this.assimilate(sender, recipient, format, channel, era, length, offsets, dataIS, os, signed, false);
96+
}
97+
98+
@Override
99+
public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format,
100+
CharSequence channel, int era, long length, List<Long> offsets, InputStream dataIS,
101+
OutputStream os, boolean signed, boolean encrypted) throws IOException, ASAPException {
102+
103+
// prepare encryption and signing if required
104+
ASAPCryptoMessage cryptoMessage = new ASAPCryptoMessage(ASAP_1_0.ASSIMILATE_CMD,
105+
os, signed, encrypted, recipient,
106+
this.signAndEncryptionKeyStorage);
107+
108+
cryptoMessage.sendCmd();
109+
110+
AssimilationPDU_Impl.sendPDUWithoutCmd(sender, recipient, format, channel, era,
111+
length, offsets, dataIS, cryptoMessage.getOutputStream(), signed);
112+
113+
// finish crypto session - maybe nothing has to be done
114+
cryptoMessage.finish();
97115
}
98116

99117
@Override
100118
public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format,
101119
CharSequence channel, int era, List<Long> offsets, byte[] data,
102120
OutputStream os, boolean signed) throws IOException, ASAPException {
103121

122+
this.assimilate(sender, recipient, format, channel, era, offsets, data, os, signed, false);
123+
}
124+
125+
@Override
126+
public void assimilate(CharSequence sender, CharSequence recipient, CharSequence format,
127+
CharSequence channel, int era, List<Long> offsets, byte[] data,
128+
OutputStream os, boolean signed, boolean encrypted) throws IOException, ASAPException {
129+
104130
if(data == null || data.length == 0) throw new ASAPException("data must not be null");
105131
if(era < 0) throw new ASAPException("era must be a non-negative value: " + era);
106132

107133
this.assimilate(sender, recipient, format, channel, era, data.length, offsets,
108-
new ByteArrayInputStream(data), os, signed);
134+
new ByteArrayInputStream(data), os, signed, encrypted);
109135
}
110136

111137
@Override
@@ -116,7 +142,7 @@ public ASAP_PDU_1_0 readPDU(InputStream is) throws IOException, ASAPException {
116142
boolean encrypted = (cmd & ENCRYPTED_MASK) != 0;
117143

118144
if(encrypted) {
119-
CryptoMessage cryptoMessage = new CryptoMessage(this.signAndEncryptionKeyStorage);
145+
ASAPCryptoMessage cryptoMessage = new ASAPCryptoMessage(this.signAndEncryptionKeyStorage);
120146
boolean ownerIsRecipient = cryptoMessage.initDecryption(cmd, is);
121147
if(ownerIsRecipient) {
122148
// peer is recipient - decrypt and go ahead
@@ -133,10 +159,10 @@ public ASAP_PDU_1_0 readPDU(InputStream is) throws IOException, ASAPException {
133159
int flagsInt = PDU_Impl.readByte(is);
134160

135161
InputStream realIS = is;
136-
CryptoMessage verifyCryptoMessage = null;
162+
ASAPCryptoMessage verifyCryptoMessage = null;
137163
if(PDU_Impl.flagSet(PDU_Impl.SIGNED_TO_BIT_POSITION, flagsInt)) {
138-
verifyCryptoMessage = new CryptoMessage(this.signAndEncryptionKeyStorage);
139-
is = verifyCryptoMessage.setupInputStreamCopier(flagsInt, is);
164+
verifyCryptoMessage = new ASAPCryptoMessage(this.signAndEncryptionKeyStorage);
165+
is = verifyCryptoMessage.initVerifiction(flagsInt, is);
140166
}
141167

142168
PDU_Impl pdu = null;

src/net/sharksystem/asap/protocol/AssimilationPDU_Impl.java

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
import net.sharksystem.asap.ASAPException;
44

5-
import java.io.ByteArrayOutputStream;
6-
import java.io.IOException;
7-
import java.io.InputStream;
8-
import java.io.OutputStream;
5+
import java.io.*;
96
import java.util.ArrayList;
107
import java.util.List;
118
import java.util.StringTokenizer;
@@ -17,6 +14,9 @@ class AssimilationPDU_Impl extends PDU_Impl implements ASAP_AssimilationPDU_1_0
1714
public static final String OFFSET_DELIMITER = ",";
1815
private List<Integer> offsets = new ArrayList<>();
1916

17+
private byte[] data = null;
18+
private boolean dataNoLongerOnStream = false;
19+
2020
// PDU: CMD | FLAGS | PEER | RECIPIENT | FORMAT | CHANNEL | ERA | OFFSETS | LENGTH | DATA
2121

2222
public AssimilationPDU_Impl(int flagsInt, boolean encrypted, InputStream is) throws IOException, ASAPException {
@@ -34,6 +34,11 @@ public AssimilationPDU_Impl(int flagsInt, boolean encrypted, InputStream is) thr
3434
this.dataLength = this.readLongParameter(is);
3535

3636
this.is = is;
37+
38+
if(this.signed()) {
39+
// read data from stream, verification needs to reach signature
40+
this.getData();
41+
}
3742
}
3843

3944
private void readOffsets(InputStream is) throws IOException, ASAPException {
@@ -44,28 +49,29 @@ private void readRecipientPeer(InputStream is) throws IOException, ASAPException
4449
this.recipientPeer = this.readCharSequenceParameter(is);
4550
}
4651

47-
static void sendPDU(CharSequence peer, CharSequence recipientPeer, CharSequence format, CharSequence channel,
48-
int era, long length, List<Long> offsets, InputStream is, OutputStream os, boolean signed)
52+
static void sendPDUWithoutCmd(CharSequence peer, CharSequence recipient, CharSequence format, CharSequence channel,
53+
int era, long length, List<Long> offsets, InputStream is, OutputStream os,
54+
boolean signed)
4955
throws IOException, ASAPException {
5056

5157
// first: check protocol errors
5258
PDU_Impl.checkValidEra(era);
5359
PDU_Impl.checkValidFormat(format);
54-
// PDU_Impl.checkValidSign(peer, signed);
5560
PDU_Impl.checkValidStream(os);
5661

5762
// create parameter bytes
5863
int flags = 0;
5964
flags = PDU_Impl.setFlag(peer, flags, SENDER_BIT_POSITION);
60-
flags = PDU_Impl.setFlag(recipientPeer, flags, RECIPIENT_BIT_POSITION);
65+
flags = PDU_Impl.setFlag(recipient, flags, RECIPIENT_BIT_POSITION);
6166
flags = PDU_Impl.setFlag(channel, flags, CHANNEL_BIT_POSITION);
6267
flags = PDU_Impl.setFlag(era, flags, ERA_BIT_POSITION);
6368
flags = PDU_Impl.setFlag(offsets, flags, OFFSETS_BIT_POSITION);
69+
flags = PDU_Impl.setFlag(signed, flags, SIGNED_TO_BIT_POSITION);
6470

65-
PDU_Impl.sendHeader(ASAP_1_0.ASSIMILATE_CMD, flags, os);
71+
PDU_Impl.sendFlags(flags, os);
6672

6773
PDU_Impl.sendCharSequenceParameter(peer, os); // opt
68-
PDU_Impl.sendCharSequenceParameter(recipientPeer, os); // opt
74+
PDU_Impl.sendCharSequenceParameter(recipient, os); // opt
6975
PDU_Impl.sendCharSequenceParameter(format, os); // mand
7076
PDU_Impl.sendCharSequenceParameter(channel, os); // opt
7177
PDU_Impl.sendNonNegativeIntegerParameter(era, os); // opt
@@ -77,8 +83,6 @@ static void sendPDU(CharSequence peer, CharSequence recipientPeer, CharSequence
7783
while(length-- > 0) {
7884
os.write(is.read());
7985
}
80-
81-
// TODO: signature
8286
}
8387

8488
static String list2string(List<Long> list) {
@@ -130,20 +134,56 @@ public List<Integer> getMessageOffsets() {
130134

131135
@Override
132136
public byte[] getData() throws IOException {
133-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
134-
this.streamData(baos, this.dataLength);
137+
if(data == null) {
138+
if(this.dataNoLongerOnStream)
139+
throw new IOException(this.getLogStart() + "data are already read from stream, probably with streamData");
140+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
141+
this.streamData(baos);
142+
this.data = baos.toByteArray();
143+
}
144+
145+
return this.data;
146+
}
135147

136-
return baos.toByteArray();
148+
private String getLogStart() {
149+
return this.getClass().getSimpleName() + ": ";
137150
}
138151

139-
public InputStream getInputStream() {
152+
public InputStream getInputStream() throws IOException {
153+
if(this.dataNoLongerOnStream) {
154+
if(this.data == null) {
155+
throw new IOException(this.getLogStart()
156+
+ "data are no longer in stream, probably due to a previous call of streamData or getInputStream");
157+
} else {
158+
return new ByteArrayInputStream(this.data);
159+
}
160+
}
161+
162+
this.dataNoLongerOnStream = true; // educated guess - they will be gone very soon.
140163
return this.is;
141164
}
142165

143166
@Override
144-
public void streamData(OutputStream os, long length) throws IOException {
145-
for(int i = 0; i < length; i++) {
146-
os.write(this.is.read());
167+
public void streamData(OutputStream os) throws IOException {
168+
InputStream useIS;
169+
170+
if(this.data == null) {
171+
if(this.dataNoLongerOnStream) {
172+
throw new IOException(this.getLogStart()
173+
+ "data are already read from stream, probably previous call of streamData");
174+
} else {
175+
// data are still on stream
176+
useIS = this.is;
177+
// but not any longer
178+
this.dataNoLongerOnStream = true;
179+
}
180+
} else {
181+
// already read
182+
useIS = new ByteArrayInputStream(this.data);
183+
}
184+
185+
for (int i = 0; i < this.dataLength; i++) {
186+
os.write(useIS.read());
147187
}
148188
}
149189
}

0 commit comments

Comments
 (0)