99import java .io .ByteArrayInputStream ;
1010import java .io .ByteArrayOutputStream ;
1111import java .io .IOException ;
12-
12+ import java .util .HashSet ;
13+ import java .util .Set ;
14+
15+ /**
16+ * A SharkNet message is issued by a peer (sender), has content and can be tagged with an URI. It can have
17+ * null (to anybody), one or more recipients. A message can be signed. A message that is for a single recipient
18+ * can be encrypted.
19+ */
1320class SharkNetMessage {
1421 private static final int SIGNED_MASK = 0x1 ;
1522 private static final int ENCRYPTED_MASK = 0x2 ;
16- private final byte [] snMessage ;
23+ public static final CharSequence ANY_RECIPIENT = "SN_ANY" ;
24+ public static final CharSequence ANONYMOUS = "SN_ANON" ;
25+ private byte [] snContent ;
1726 private final CharSequence snSender ;
18- private final boolean verified ;
19- private final boolean encrypted ;
27+ private byte [] serializedMessage ;
28+ private boolean verified ;
29+ private boolean encrypted ;
2030 private final CharSequence topic ;
31+ private Set <CharSequence > snRecipients ;
2132
22- public SharkNetMessage (byte [] snMessage , String snSender , boolean verified , boolean encrypted ) {
23- this (snMessage , null , snSender , verified , encrypted );
33+ SharkNetMessage (byte [] snContent , String snSender , boolean verified , boolean encrypted ) {
34+ this (snContent , null , snSender , new HashSet <>() , verified , encrypted );
2435 }
2536
26- public SharkNetMessage (byte [] message , CharSequence topic , CharSequence sender , boolean verified , boolean encrypted ) {
27- this .snMessage = message ;
37+ /**
38+ * Received
39+ * @param message
40+ * @param topic
41+ * @param sender
42+ * @param verified
43+ * @param encrypted
44+ */
45+ SharkNetMessage (byte [] message , CharSequence topic , CharSequence sender ,
46+ Set <CharSequence > snRecipients ,
47+ boolean verified , boolean encrypted ) {
48+ this .snContent = message ;
2849 this .snSender = sender ;
2950 this .verified = verified ;
3051 this .encrypted = encrypted ;
3152 this .topic = topic ;
53+ this .snRecipients = snRecipients ;
54+ }
55+
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 , BasicCryptoParameters basicCryptoParameters )
67+ throws IOException , ASAPException {
68+
69+ this .snContent = content ;
70+ this .snSender = sender ;
71+ this .topic = topic ;
72+
73+ this .serializedMessage =
74+ SharkNetMessage .serializeMessage (content , topic , recipient ,
75+ sign , encrypt , sender , basicCryptoParameters );
76+ }
77+
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+ BasicCryptoParameters basicCryptoParameters ) 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 , basicCryptoParameters );
96+
3297 }
3398
3499 static byte [] serializeMessage (byte [] message , CharSequence topic , CharSequence recipient ,
35- boolean sign , boolean encrypt , CharSequence ownerID , BasicCryptoParameters basicCryptoParameters )
100+ boolean sign , boolean encrypt , CharSequence ownerID ,
101+ BasicCryptoParameters basicCryptoParameters )
36102 throws IOException , ASAPException {
37103
104+ Set <CharSequence > recipients = null ;
105+ if (recipient != null ) {
106+ recipients = new HashSet <>();
107+ recipients .add (recipient );
108+ }
109+
110+ return SharkNetMessage .serializeMessage (message , topic , recipients ,
111+ sign , encrypt , ownerID , basicCryptoParameters );
112+
113+ }
114+
115+ static byte [] serializeMessage (byte [] content , CharSequence topic , Set <CharSequence > recipients ,
116+ boolean sign , boolean encrypt , CharSequence sender , BasicCryptoParameters basicCryptoParameters )
117+ throws IOException , ASAPException {
118+
119+ if ( (recipients != null && recipients .size () > 1 ) && encrypt ) {
120+ throw new ASAPSecurityException ("cannot (yet) encrypt one message for more than one recipient - split it into more messages" );
121+ }
122+
123+ if (recipients == null ) {
124+ recipients = new HashSet <>();
125+ recipients .add (SharkNetMessage .ANY_RECIPIENT );
126+ }
127+
128+ if (sender == null ) {
129+ sender = SharkNetMessage .ANONYMOUS ;
130+ }
131+
38132 // merge content, sender and recipient
39133 ByteArrayOutputStream baos = new ByteArrayOutputStream ();
40- ASAPSerialization .writeByteArray (message , baos );
41- ASAPSerialization .writeCharSequenceParameter (ownerID , baos );
42- ASAPSerialization .writeCharSequenceParameter (recipient , baos );
43- message = baos .toByteArray ();
134+ ASAPSerialization .writeByteArray (content , baos );
135+ ASAPSerialization .writeCharSequenceParameter (sender , baos );
136+ // ASAPSerialization.writeCharSequenceParameter(recipient, baos);
137+ ASAPSerialization .writeCharSequenceSetParameter (recipients , baos );
138+ content = baos .toByteArray ();
44139
45140 byte flags = 0 ;
46141 if (sign ) {
47- byte [] signature = ASAPCryptoAlgorithms .sign (message , basicCryptoParameters );
142+ byte [] signature = ASAPCryptoAlgorithms .sign (content , basicCryptoParameters );
48143 baos = new ByteArrayOutputStream ();
49- ASAPSerialization .writeByteArray (message , baos ); // message has three parts: content, sender, receiver
144+ ASAPSerialization .writeByteArray (content , baos ); // message has three parts: content, sender, receiver
50145 // append signature
51146 ASAPSerialization .writeByteArray (signature , baos );
52147 // attach signature to message
53- message = baos .toByteArray ();
148+ content = baos .toByteArray ();
54149 flags += SIGNED_MASK ;
55150 }
56151
57152 if (encrypt ) {
58- message = ASAPCryptoAlgorithms .produceEncryptedMessagePackage (
59- message , recipient , basicCryptoParameters );
153+ content = ASAPCryptoAlgorithms .produceEncryptedMessagePackage (
154+ content ,
155+ recipients .iterator ().next (), // already checked if one and only one is recipient
156+ basicCryptoParameters );
60157 flags += ENCRYPTED_MASK ;
61158 }
62159
63160 // serialize SN message
64161 baos = new ByteArrayOutputStream ();
65162 ASAPSerialization .writeByteParameter (flags , baos );
66- ASAPSerialization .writeByteArray (message , baos );
163+ ASAPSerialization .writeByteArray (content , baos );
67164
68165 return baos .toByteArray ();
69166 }
@@ -106,7 +203,8 @@ static SharkNetMessage parseMessage(byte[] message, String sender, String uri,
106203 bais = new ByteArrayInputStream (tmpMessage );
107204 byte [] snMessage = ASAPSerialization .readByteArray (bais );
108205 String snSender = ASAPSerialization .readCharSequenceParameter (bais );
109- String snReceiver = ASAPSerialization .readCharSequenceParameter (bais );
206+ Set <CharSequence > snReceivers = ASAPSerialization .readCharSequenceSetParameter (bais );
207+ //String snReceiver = ASAPSerialization.readCharSequenceParameter(bais);
110208
111209 boolean verified = false ; // initialize
112210 if (signature != null ) {
@@ -120,12 +218,16 @@ static SharkNetMessage parseMessage(byte[] message, String sender, String uri,
120218 }
121219 }
122220
123- return new SharkNetMessage (snMessage , snSender , verified , encrypted );
221+ return new SharkNetMessage (snMessage , uri , snSender , snReceivers , verified , encrypted );
124222 }
125223
126- public byte [] getContent () { return this .snMessage ;}
127-
224+ public byte [] getContent () { return this .snContent ;}
128225 public CharSequence getSender () { return this .snSender ; }
226+ public Set <CharSequence > getRecipients () { return this .snRecipients ; }
129227 public boolean verified () { return this .verified ; }
130228 public boolean encrypted () { return this .encrypted ; }
229+
230+ public byte [] getSerializedMessage () {
231+ return this .serializedMessage ;
232+ }
131233}
0 commit comments