22
33import net .sharksystem .asap .ASAPException ;
44import net .sharksystem .asap .ASAPSecurityException ;
5- import net .sharksystem .asap .protocol .ASAP_1_0 ;
6- import net .sharksystem .asap .protocol .PDU_Impl ;
75import net .sharksystem .crypto .ASAPBasicKeyStorage ;
86
97import javax .crypto .*;
108import javax .crypto .spec .SecretKeySpec ;
119import java .io .*;
1210import java .security .*;
1311
14- class CryptoSession {
15- private static final int MAX_ENCRYPTION_BLOCK_SIZE = 128 ;
12+ class CryptoMessage {
1613 private Signature signature ;
1714 private CharSequence recipient ;
1815 private ASAPBasicKeyStorage keyStorage ;
@@ -23,13 +20,15 @@ class CryptoSession {
2320 private OutputStream effectivOS ;
2421 private OutputStream realOS ;
2522 private ByteArrayOutputStream asapMessageOS ;
26- private InputStreamCopy verifyStream ;
23+ private InputStreamCopy inputStreamCopy ;
24+ private byte [] encryptedSymmetricKey ;
25+ private byte [] encryptedContent ;
2726
28- CryptoSession (ASAPBasicKeyStorage keyStorage ) {
27+ CryptoMessage (ASAPBasicKeyStorage keyStorage ) {
2928 this .keyStorage = keyStorage ;
3029 }
3130
32- CryptoSession (byte cmd , OutputStream os , boolean sign , boolean encrypted ,
31+ CryptoMessage (byte cmd , OutputStream os , boolean sign , boolean encrypted ,
3332 CharSequence recipient ,
3433 ASAPBasicKeyStorage keyStorage )
3534 throws ASAPSecurityException {
@@ -50,6 +49,10 @@ class CryptoSession {
5049 "but there is not key store at all - fatal, give up" );
5150 }
5251
52+ if (this .recipient == null ) {
53+ throw new ASAPSecurityException ("cannot encrypt message with no specified receiver - fatal, give up" );
54+ }
55+
5356 this .publicKey = keyStorage .getPublicKey (recipient );
5457 // there should be an exception - but better safe than sorry
5558 if (this .publicKey == null ) {
@@ -158,6 +161,9 @@ public void finish() throws ASAPSecurityException {
158161 // must be after signing
159162 if (this .cipher != null ) {
160163 try {
164+ // send receiver - unencrypted - need this for ad-hoc routing
165+ PDU_Impl .sendCharSequenceParameter (this .recipient , this .realOS );
166+
161167 // get symmetric key
162168 SecretKey encryptionKey = this .keyStorage .generateSymmetricKey ();
163169 byte [] encodedSymmetricKey = encryptionKey .getEncoded ();
@@ -186,6 +192,7 @@ public void finish() throws ASAPSecurityException {
186192
187193 int lastStepLen = asapMessageAsBytes.length - i;
188194 symmetricCipher.update(asapMessageAsBytes, i, lastStepLen);
195+ // did not work - ignored previous updates. anyway, there is a solution, see below
189196 byte[] encryptedContent = symmetricCipher.doFinal();
190197 */
191198
@@ -226,13 +233,18 @@ byte[] getCopy() {
226233 }
227234 }
228235
229- public InputStream setupInputStreamListener (InputStream is , int flagsInt ) throws IOException {
236+ public InputStream setupInputStreamCopier (int priorInt , InputStream is )
237+ throws IOException {
238+
230239 ByteArrayOutputStream baos = new ByteArrayOutputStream ();
231- PDU_Impl .sendFlags (flagsInt , baos );
240+ // if(writeInt) {
241+ // PDU_Impl.sendFlags(priorInt, baos);
242+ // }
232243
233- this . verifyStream = new InputStreamCopy ( baos .toByteArray (), is );
244+ baos .write ( priorInt );
234245
235- return this .verifyStream ;
246+ this .inputStreamCopy = new InputStreamCopy (baos .toByteArray (), is );
247+ return this .inputStreamCopy ;
236248 }
237249
238250 public boolean verify (String sender , InputStream is ) throws IOException , ASAPException {
@@ -244,7 +256,7 @@ public boolean verify(String sender, InputStream is) throws IOException, ASAPExc
244256 this .signature = Signature .getInstance (this .keyStorage .getRSASigningAlgorithm ());
245257 this .signature .initVerify (publicKey );
246258 // get data which are to be verified
247- byte [] signedData = this .verifyStream .getCopy ();
259+ byte [] signedData = this .inputStreamCopy .getCopy ();
248260 this .signature .update (signedData );
249261 byte [] signatureBytes = this .readByteArray (is );
250262 boolean wasVerified = this .signature .verify (signatureBytes );
@@ -256,35 +268,74 @@ public boolean verify(String sender, InputStream is) throws IOException, ASAPExc
256268
257269 ////////////////////////////////// decrypt
258270
259- public InputStream decrypt (InputStream is ) throws ASAPSecurityException {
260- return this .decrypt (is , this .keyStorage .getPrivateKey ());
271+ /**
272+ * Simple idea: We read anything from stream and keep a copy. Later, we figure out
273+ * if we can encrypt that message or not. Either way, we can keep and redistribute a copy.
274+ *
275+ *
276+ * @param cmd
277+ * @param is
278+ * @return
279+ * @throws IOException
280+ * @throws ASAPException
281+ */
282+ public boolean initDecryption (byte cmd , InputStream is ) throws IOException , ASAPException {
283+ // make a copy of read data
284+ InputStream copyStream = this .setupInputStreamCopier (cmd , is );
285+
286+ // read recipient
287+ this .recipient = PDU_Impl .readCharSequenceParameter (copyStream );
288+
289+ // read encrypted symmetric key
290+ this .encryptedSymmetricKey = this .readByteArray (copyStream );
291+
292+ // read content
293+ this .encryptedContent = this .readByteArray (copyStream );
294+
295+ // read anything - are we recipient?
296+ if (this .keyStorage .isOwner (this .recipient )) {
297+ return true ;
298+ }
299+
300+ return false ;
301+ }
302+
303+ byte [] getEncryptedMessage () throws ASAPSecurityException {
304+ if (this .inputStreamCopy == null ) {
305+ throw new ASAPSecurityException (
306+ this .getLogStart () + "no copy made, maybe forgot to initialize decryption?" );
307+ }
308+
309+ return this .inputStreamCopy .getCopy ();
310+ }
311+
312+ public InputStream doDecryption (InputStream is ) throws ASAPSecurityException {
313+ return this .doDecryption (is , this .keyStorage .getPrivateKey ());
261314 }
262315
263316 // parameter private key is usually not an option. Good entry for testing / debugging, though
264- private InputStream decrypt (InputStream is , PrivateKey privateKey ) throws ASAPSecurityException {
317+ public InputStream doDecryption (InputStream is , PrivateKey privateKey ) throws ASAPSecurityException {
265318 try {
266- // read encrypted symmetric key
267- byte [] encryptedSymmetricKey = this .readByteArray (is );
268-
269319 // decrypt encoded symmetric key
270320 this .cipher = Cipher .getInstance (keyStorage .getRSAEncryptionAlgorithm ());
271321 this .cipher .init (Cipher .DECRYPT_MODE , privateKey );
272- byte [] encodedSymmetricKey = this .cipher .doFinal (encryptedSymmetricKey );
322+
323+ // read encryptedKey in initDecryption
324+ byte [] encodedSymmetricKey = this .cipher .doFinal (this .encryptedSymmetricKey );
273325
274326 // create symmetric key object
275327 SecretKey symmetricKey =
276328 new SecretKeySpec (encodedSymmetricKey , this .keyStorage .getSymmetricKeyType ());
277329
278- // read content
279- byte [] encryptedContent = this .readByteArray (is );
280-
281330 // decrypt content
282331 Cipher symmetricCipher = Cipher .getInstance (keyStorage .getSymmetricEncryptionAlgorithm ());
283332 symmetricCipher .init (Cipher .DECRYPT_MODE , symmetricKey );
284- byte [] decryptedBytes = symmetricCipher .doFinal (encryptedContent );
333+
334+ // read encryptedContent in initDecryption
335+ byte [] decryptedBytes = symmetricCipher .doFinal (this .encryptedContent );
285336 return new ByteArrayInputStream (decryptedBytes );
286337 } catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException |
287- NoSuchPaddingException | InvalidKeyException | IOException | ASAPException e ) {
338+ NoSuchPaddingException | InvalidKeyException e ) {
288339 throw new ASAPSecurityException (this .getLogStart (), e );
289340 }
290341 }
0 commit comments