99import javax .crypto .IllegalBlockSizeException ;
1010import javax .crypto .NoSuchPaddingException ;
1111import java .io .*;
12- import java .security .InvalidKeyException ;
13- import java .security .NoSuchAlgorithmException ;
14- import java .security .PrivateKey ;
15- import java .security .PublicKey ;
12+ import java .security .*;
1613
1714class CryptoSession {
15+ private Signature signature ;
1816 private CharSequence recipient ;
1917 private ASAPReadonlyKeyStorage keyStorage ;
2018 private Cipher cipher = null ;
@@ -24,38 +22,11 @@ class CryptoSession {
2422 private OutputStream effectivOS ;
2523 private OutputStream realOS ;
2624 private ByteArrayOutputStream asapMessageOS ;
27- private byte [] asapMessageAsBytes ;
2825
2926 CryptoSession (ASAPReadonlyKeyStorage keyStorage ) {
3027 this .keyStorage = keyStorage ;
3128 }
3229
33- InputStream decrypt (InputStream is ) throws ASAPSecurityException {
34- return this .decrypt (is , this .keyStorage .getPrivateKey ());
35- }
36-
37- private InputStream decrypt (InputStream is , PrivateKey privateKey ) throws ASAPSecurityException {
38- try {
39- this .cipher = Cipher .getInstance (keyStorage .getRSAEncryptionAlgorithm ());
40- this .cipher .init (Cipher .DECRYPT_MODE , privateKey );
41-
42- // read len
43- int len = PDU_Impl .readIntegerParameter (is );
44- byte [] messageBytes = new byte [len ];
45-
46- // read encrypted bytes from stream
47- is .read (messageBytes );
48-
49- // debugging
50- // decrypt
51- byte [] decryptedBytes = this .cipher .doFinal (messageBytes );
52- return new ByteArrayInputStream (decryptedBytes );
53- } catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException |
54- NoSuchPaddingException | InvalidKeyException | IOException | ASAPException e ) {
55- throw new ASAPSecurityException (this .getLogStart (), e );
56- }
57- }
58-
5930 CryptoSession (byte cmd , OutputStream os , boolean sign , boolean encrypted ,
6031 CharSequence recipient ,
6132 ASAPReadonlyKeyStorage keyStorage )
@@ -93,13 +64,9 @@ private InputStream decrypt(InputStream is, PrivateKey privateKey) throws ASAPSe
9364 }
9465
9566 // cipher is ready - we can encrypt
96- this .asapMessageOS = new ByteArrayOutputStream ();
97- // pud will make a detour
98- this .effectivOS = this .asapMessageOS ;
67+ this .setupTempMessageStorage ();
9968 }
10069
101-
102- /*
10370 if (sign ) {
10471 // there must be a keyStorage
10572 if (keyStorage == null ) {
@@ -113,32 +80,26 @@ private InputStream decrypt(InputStream is, PrivateKey privateKey) throws ASAPSe
11380 }
11481
11582 // ok, we can sign
116- if(sign) {
117- // anything was written into a bytearray
11883
11984 // produce signature
120- Signature signature = null;
12185 try {
122- signature = Signature.getInstance("TODO_signing_algorithm");
123- signature.initSign(keyStorage.getPrivateKey()); // desperate try
124- byte[] bytes2Sign = bufferOS.toByteArray();
125- signature.update(bytes2Sign);
126- byte[] signatureBytes = signature.sign();
86+ this .signature = Signature .getInstance (this .keyStorage .getRSASigningAlgorithm ());
12787
128- // send out anything, including signature
88+ // we could sign
89+ this .setupTempMessageStorage ();
12990
130- // TODO need number of bytes payload to find signature later.
131- os.write(bytes2Sign);
132- os.write(signatureBytes);
133- } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
91+ } catch (NoSuchAlgorithmException e ) {
13492 throw new ASAPSecurityException (e .getLocalizedMessage ());
13593 }
13694 }
137- }
138-
139- */
140-
95+ }
14196
97+ private void setupTempMessageStorage () {
98+ if (this .asapMessageOS == null ) {
99+ this .asapMessageOS = new ByteArrayOutputStream ();
100+ // pud will make a detour
101+ this .effectivOS = this .asapMessageOS ;
102+ }
142103 }
143104
144105 public void sendCmd () throws IOException {
@@ -154,42 +115,111 @@ OutputStream getOutputStream() {
154115 return this .effectivOS ;
155116 }
156117
118+ private void writeByteArray (byte [] bytes2Write , OutputStream os ) throws IOException {
119+ PDU_Impl .sendNonNegativeIntegerParameter (bytes2Write .length , os );
120+ os .write (bytes2Write );
121+ }
122+
123+ private byte [] readByteArray (InputStream is ) throws IOException , ASAPException {
124+ // read len
125+ int len = PDU_Impl .readIntegerParameter (is );
126+ byte [] messageBytes = new byte [len ];
127+
128+ // read encrypted bytes from stream
129+ is .read (messageBytes );
130+
131+ return messageBytes ;
132+ }
133+
157134 public void finish () throws ASAPSecurityException {
158- if (cipher != null ) {
159- // that is our asap message in clear text
160- this .asapMessageAsBytes = this .asapMessageOS .toByteArray ();
135+ // signing must come first
136+ if (this .signature != null ) {
137+ try {
138+ byte [] asapMessageAsBytes = this .asapMessageOS .toByteArray ();
139+ this .signature .initSign (this .keyStorage .getPrivateKey ());
140+ this .signature .update (asapMessageAsBytes );
141+ byte [] signatureBytes = signature .sign ();
142+
143+ if (this .cipher != null ) {
144+ // have to store it - anything will be encrypted
145+ this .writeByteArray (signatureBytes , this .asapMessageOS );
146+ } else {
147+ // can write anything now
148+ this .realOS .write (asapMessageAsBytes );
149+ this .writeByteArray (signatureBytes , this .realOS );
150+ }
151+ } catch (InvalidKeyException | SignatureException | IOException e ) {
152+ throw new ASAPSecurityException (this .getLogStart (), e );
153+ }
154+ }
155+
156+ if (this .cipher != null ) {
161157 try {
162158 // encrypted asap message
163- byte [] encryptedBytes = this .cipher . doFinal ( this . asapMessageAsBytes );
164- //this.debuggingRememberEncryptedASAPMessage = encryptedBytes ;
159+ byte [] asapMessageAsBytes = this .asapMessageOS . toByteArray ( );
160+ byte [] encryptedBytes = this . cipher . doFinal ( asapMessageAsBytes ) ;
165161
166- // write len
167- PDU_Impl .sendNonNegativeIntegerParameter (encryptedBytes .length , this .realOS );
168- // write data
162+ this .writeByteArray (encryptedBytes , this .realOS );
169163 this .realOS .write (encryptedBytes );
164+ } catch (IllegalBlockSizeException | BadPaddingException | IOException e ) {
165+ throw new ASAPSecurityException (this .getLogStart (), e );
166+ }
167+ }
168+ }
170169
171- /*
172- // debugging - decrypt
170+ ////////////////////////////////// verify
173171
174- // make a test
175- ByteArrayOutputStream senderSiteTest = new ByteArrayOutputStream();
176- PDU_Impl.sendNonNegativeIntegerParameter(encryptedBytes.length, senderSiteTest );
177- senderSiteTest.write(encryptedBytes) ;
172+ public boolean verify ( String sender , InputStream is ) throws IOException , ASAPException {
173+ // try to get senders' public key
174+ PublicKey publicKey = this . keyStorage . getPublicKey ( sender );
175+ if ( publicKey == null ) return false ;
178176
179- this.debuggingEncryptedASAPMessageWithLen = senderSiteTest.toByteArray();
177+ try {
178+ this .signature = Signature .getInstance (this .keyStorage .getRSASigningAlgorithm ());
179+ this .signature .initVerify (publicKey );
180+ byte [] signatureBytes = this .readByteArray (is );
181+ boolean wasVerified = this .signature .verify (signatureBytes );
182+ return wasVerified ;
183+ } catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e ) {
184+ throw new ASAPSecurityException (this .getLogStart (), e );
185+ }
186+ }
180187
181- PrivateKey privateKey = this.keyStorage.getPrivateKey(this.recipient);
182- // ByteArrayInputStream decrypt = (ByteArrayInputStream) this.decrypt(new ByteArrayInputStream(senderSiteTest.toByteArray()), privateKey);
183- ByteArrayInputStream decrypt = (ByteArrayInputStream) this.decrypt(new ByteArrayInputStream(this.debuggingEncryptedASAPMessageWithLen), privateKey);
184- int i = 42;
185- */
186- } catch (IllegalBlockSizeException | BadPaddingException | IOException e ) {
187- throw new ASAPSecurityException (this .getLogStart (), e );
188- }
188+ ////////////////////////////////// decrypt
189+
190+ InputStream decrypt (InputStream is ) throws ASAPSecurityException {
191+ return this .decrypt (is , this .keyStorage .getPrivateKey ());
192+ }
193+
194+ // parameter private key is usually no option. There is just one - burt was good for debugging
195+ private InputStream decrypt (InputStream is , PrivateKey privateKey ) throws ASAPSecurityException {
196+ try {
197+ this .cipher = Cipher .getInstance (keyStorage .getRSAEncryptionAlgorithm ());
198+ this .cipher .init (Cipher .DECRYPT_MODE , privateKey );
199+
200+ // read encrypted message
201+ byte [] messageBytes = this .readByteArray (is );
202+
203+ /*
204+ // read len
205+ int len = PDU_Impl.readIntegerParameter(is);
206+ byte[] messageBytes = new byte[len];
207+
208+ // read encrypted bytes from stream
209+ is.read(messageBytes);
210+ */
211+
212+ // decrypt
213+ byte [] decryptedBytes = this .cipher .doFinal (messageBytes );
214+ return new ByteArrayInputStream (decryptedBytes );
215+ } catch (BadPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException |
216+ NoSuchPaddingException | InvalidKeyException | IOException | ASAPException e ) {
217+ throw new ASAPSecurityException (this .getLogStart (), e );
189218 }
190219 }
191220
192221 private String getLogStart () {
193222 return this .getClass ().getSimpleName () + ": " ;
194223 }
224+
195225}
0 commit comments