Skip to content

Commit 37f6127

Browse files
committed
started implementing signing and encryption
1 parent 9743374 commit 37f6127

File tree

5 files changed

+149
-7
lines changed

5 files changed

+149
-7
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.sharksystem.asap.protocol;
2+
3+
import net.sharksystem.asap.ASAPSecurityException;
4+
5+
import java.security.PrivateKey;
6+
import java.security.PublicKey;
7+
8+
public interface ASAPSignAndEncryptionKeyStorage {
9+
/**
10+
*
11+
* @return private key of local device - for signing
12+
* @throws ASAPSecurityException
13+
*/
14+
PrivateKey getPrivateKey() throws ASAPSecurityException;
15+
16+
/**
17+
*
18+
* @param subjectID
19+
* @return public key of recipient - to encrypt
20+
*/
21+
PublicKey getPublicKey(CharSequence subjectID) throws ASAPSecurityException;
22+
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.sharksystem.asap.protocol;
22

33
import net.sharksystem.asap.ASAPException;
4+
import net.sharksystem.asap.ASAPSecurityException;
45

56
import java.io.IOException;
67
import java.io.InputStream;
@@ -69,6 +70,26 @@ void interest(CharSequence peer, CharSequence sourcePeer, CharSequence format,
6970
CharSequence channel, int eraFrom, int eraTo,
7071
OutputStream os, boolean signed) throws IOException, ASAPException;
7172

73+
/**
74+
* @param peer identifies a peer - can be null
75+
* @param sourcePeer wished source (authority) of information (optional, can be null)
76+
* @param eraFrom lower limit of era range (-1 means undefined)
77+
* @param eraTo upper limit of era range (-1 means undefined)
78+
* @param channel whished / required channel (can be null)
79+
* @param format describes format - used to describe an application that can deal with transmitted data format.
80+
* @param os stream that PDU is to be sent
81+
* @param sign sign message when sending
82+
* @param encrypted encrypt method - of possible
83+
* @param mustBeEncrypted encrypt can be set true. There could not bot a public key of receipient. If hit flag ist
84+
* set true - an exception is thrown. Otherwise. message is sent unencrypted.
85+
* @throws IOException
86+
* @throws ASAPException
87+
*/
88+
void interest(CharSequence peer, CharSequence sourcePeer, CharSequence format,
89+
CharSequence channel, int eraFrom, int eraTo,
90+
OutputStream os, boolean sign, boolean encrypted, boolean mustBeEncrypted)
91+
throws IOException, ASAPException, ASAPSecurityException;
92+
7293
/**
7394
* @param peer wished source (authority) of information
7495
* @param channel whished / required channel (can be null)

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.sharksystem.asap.protocol;
22

33
import net.sharksystem.asap.ASAPException;
4+
import net.sharksystem.asap.ASAPSecurityException;
45

56
import java.io.ByteArrayInputStream;
67
import java.io.IOException;
@@ -9,8 +10,18 @@
910
import java.util.List;
1011

1112
public class ASAP_Modem_Impl implements ASAP_1_0 {
13+
private final ASAPSignAndEncryptionKeyStorage signAndEncryptionKeyStorage;
14+
15+
public ASAP_Modem_Impl() {
16+
this.signAndEncryptionKeyStorage = null; // no key storage
17+
}
18+
19+
public ASAP_Modem_Impl(ASAPSignAndEncryptionKeyStorage signAndEncryptionKeyStorage) {
20+
this.signAndEncryptionKeyStorage = signAndEncryptionKeyStorage;
21+
}
1222
// Character are transmitted as bytes: number of bytes (first byte), content following, 0 mean no content
1323

24+
1425
/*
1526
general structure:
1627
CMD | FLAGS | ... specifics
@@ -32,17 +43,28 @@ public void offer(CharSequence peer, CharSequence format, CharSequence channel,
3243

3344
@Override
3445
public void interest(CharSequence peer, CharSequence sourcePeer, CharSequence format,
35-
CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed)
46+
CharSequence channel, OutputStream os, boolean signed) throws IOException, ASAPException {
47+
48+
this.interest(peer, sourcePeer, format, channel, ERA_NOT_DEFINED, ERA_NOT_DEFINED, os, signed);
49+
}
50+
51+
@Override
52+
public void interest(CharSequence peer, CharSequence sourcePeer, CharSequence format,
53+
CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed)
3654
throws IOException, ASAPException {
3755

38-
InterestPDU_Impl.sendPDU(peer, sourcePeer, format, channel, eraFrom, eraTo, os, signed);
56+
this.interest(peer, sourcePeer, format, channel, eraFrom, eraTo, os,
57+
signed, false, false);
3958
}
4059

4160
@Override
4261
public void interest(CharSequence peer, CharSequence sourcePeer, CharSequence format,
43-
CharSequence channel, OutputStream os, boolean signed) throws IOException, ASAPException {
62+
CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed,
63+
boolean encryted, boolean mustBeEncrypted)
64+
throws IOException, ASAPException, ASAPSecurityException {
4465

45-
this.interest(peer, sourcePeer, format, channel, ERA_NOT_DEFINED, ERA_NOT_DEFINED, os, signed);
66+
InterestPDU_Impl.sendPDU(peer, sourcePeer, format, channel, eraFrom, eraTo, os,
67+
signed, encryted, mustBeEncrypted, this.signAndEncryptionKeyStorage);
4668
}
4769

4870
@Override

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

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package net.sharksystem.asap.protocol;
22

33
import net.sharksystem.asap.ASAPException;
4+
import net.sharksystem.asap.ASAPSecurityException;
5+
import net.sharksystem.asap.util.Log;
46

7+
import java.io.ByteArrayOutputStream;
58
import java.io.IOException;
69
import java.io.InputStream;
710
import java.io.OutputStream;
11+
import java.security.InvalidKeyException;
12+
import java.security.NoSuchAlgorithmException;
13+
import java.security.Signature;
14+
import java.security.SignatureException;
815

916
public class InterestPDU_Impl extends PDU_Impl implements ASAP_Interest_PDU_1_0 {
1017
private String sourcePeer;
@@ -37,7 +44,10 @@ private void readSourcePeer(InputStream is) throws IOException, ASAPException {
3744
}
3845

3946
static void sendPDU(CharSequence peer, CharSequence sourcePeer, CharSequence format,
40-
CharSequence channel, int eraFrom, int eraTo, OutputStream os, boolean signed)
47+
CharSequence channel, int eraFrom, int eraTo, OutputStream os,
48+
boolean sign, boolean encrypted, boolean mustBeEncrypted,
49+
ASAPSignAndEncryptionKeyStorage keyStorage)
50+
4151
throws IOException, ASAPException {
4252

4353
if(format == null || format.length() < 1) format = ASAP_1_0.ANY_FORMAT;
@@ -46,9 +56,12 @@ static void sendPDU(CharSequence peer, CharSequence sourcePeer, CharSequence for
4656
PDU_Impl.checkValidEra(eraFrom);
4757
PDU_Impl.checkValidEra(eraTo);
4858
PDU_Impl.checkValidFormat(format);
49-
PDU_Impl.checkValidSign(peer, signed);
59+
PDU_Impl.checkValidSign(peer, sign);
5060
PDU_Impl.checkValidStream(os);
5161

62+
// Basis test
63+
PDU_Impl.checkBasicSecurityRequirements(sign, encrypted, keyStorage);
64+
5265
// create parameter bytes
5366
int flags = 0;
5467
flags = PDU_Impl.setFlag(peer, flags, PEER_BIT_POSITION);
@@ -57,6 +70,15 @@ static void sendPDU(CharSequence peer, CharSequence sourcePeer, CharSequence for
5770
flags = PDU_Impl.setFlag(eraFrom, flags, ERA_FROM_BIT_POSITION);
5871
flags = PDU_Impl.setFlag(eraTo, flags, ERA_TO_BIT_POSITION);
5972

73+
OutputStream usedOS = os; // assume we d not sign.
74+
ByteArrayOutputStream bufferOS = null;
75+
76+
if(sign) {
77+
// we have to collect all bytes which are to be signed
78+
bufferOS = new ByteArrayOutputStream();
79+
usedOS = bufferOS;
80+
}
81+
6082
PDU_Impl.sendHeader(ASAP_1_0.INTEREST_CMD, flags, os);
6183

6284
PDU_Impl.sendCharSequenceParameter(peer, os); // opt
@@ -66,7 +88,27 @@ static void sendPDU(CharSequence peer, CharSequence sourcePeer, CharSequence for
6688
PDU_Impl.sendNonNegativeIntegerParameter(eraFrom, os); // opt
6789
PDU_Impl.sendNonNegativeIntegerParameter(eraTo, os); // opt
6890

69-
// TODO: signature
91+
if(sign) {
92+
// anything was written into a bytearray
93+
94+
// produce signature
95+
Signature signature = null;
96+
try {
97+
signature = Signature.getInstance("TODO_signing_algorithm");
98+
signature.initSign(keyStorage.getPrivateKey()); // desperate try
99+
byte[] bytes2Sign = bufferOS.toByteArray();
100+
signature.update(bytes2Sign);
101+
byte[] signatureBytes = signature.sign();
102+
103+
// send out anything, including signature
104+
105+
// TODO need number of bytes payload to find signature later.
106+
os.write(bytes2Sign);
107+
os.write(signatureBytes);
108+
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
109+
throw new ASAPSecurityException(e.getLocalizedMessage());
110+
}
111+
}
70112
}
71113

72114
@Override

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.sharksystem.asap.protocol;
22

33
import net.sharksystem.asap.ASAPException;
4+
import net.sharksystem.asap.ASAPSecurityException;
45

56
import java.io.IOException;
67
import java.io.InputStream;
@@ -304,4 +305,38 @@ static void checkValidEra(int era) throws ASAPException {
304305
if(era > maxEra) throw new ASAPException("era exceeded max limit of " + Integer.MAX_VALUE);
305306
}
306307

308+
/**
309+
* basis tests. if sign or encrypted true - at least a key store must be there. If sign. Public key must be there.
310+
* @param sign
311+
* @param encrypted
312+
* @param keyStorage
313+
* @throws ASAPSecurityException
314+
*/
315+
static void checkBasicSecurityRequirements(boolean sign, boolean encrypted,
316+
ASAPSignAndEncryptionKeyStorage keyStorage) throws ASAPSecurityException {
317+
if(sign) {
318+
// there must be a keyStorage
319+
if(keyStorage == null) {
320+
throw new ASAPSecurityException("asap message is to be signed but there is not key store - fatal, give up");
321+
}
322+
323+
// signing needs a private key - check of available
324+
if(keyStorage.getPrivateKey() == null) {
325+
// assume, an exception already documented lack of a private key. if not
326+
throw new ASAPSecurityException("asap message is to be signed but no private key - fatal, give up");
327+
}
328+
329+
// ok, we can sign
330+
}
331+
332+
if(encrypted) {
333+
// there must be a keyStorage
334+
if(keyStorage == null) {
335+
throw new ASAPSecurityException("asap message is to be encrypted if possible " +
336+
"but there is not key store at all - fatal, give up");
337+
}
338+
339+
// we have at least the chance
340+
}
341+
}
307342
}

0 commit comments

Comments
 (0)