55
66import javax .crypto .KeyGenerator ;
77import javax .crypto .SecretKey ;
8+ import java .io .*;
89import java .security .*;
10+ import java .security .spec .InvalidKeySpecException ;
11+ import java .security .spec .X509EncodedKeySpec ;
912import java .util .HashMap ;
1013
1114public class BasicCryptoKeyStorage implements BasicCryptoParameters {
@@ -20,8 +23,11 @@ public class BasicCryptoKeyStorage implements BasicCryptoParameters {
2023 public static int DEFAULT_AES_KEY_SIZE = 128 ; // TODO we can do better
2124 public static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withRSA" ;
2225
26+ // for debugging only - we don't have private key in real apps
2327 private HashMap <String , KeyPair > peerKeyPairs = new HashMap <>();
2428
29+ private HashMap <CharSequence , PublicKey > peerPublicKeys = new HashMap <CharSequence , PublicKey >();
30+
2531 public BasicCryptoKeyStorage (String ownerID ) throws ASAPSecurityException {
2632 // generate owners key pair;
2733 this .ownerID = ownerID ;
@@ -95,11 +101,24 @@ public PublicKey getPublicKey() throws ASAPSecurityException {
95101 @ Override
96102 public PublicKey getPublicKey (CharSequence subjectID ) throws ASAPSecurityException {
97103 KeyPair keyPair = this .peerKeyPairs .get (subjectID );
98- if (keyPair == null ) throw new ASAPSecurityException ("no key pair for " + subjectID );
104+ if (keyPair == null ) {
105+ // try there - which is more likely
106+ PublicKey publicKey = this .peerPublicKeys .get (subjectID );
107+ if (publicKey != null ) {
108+ // got it
109+ return publicKey ;
110+ }
111+ // else
112+ throw new ASAPSecurityException ("no key pair for " + subjectID );
113+ }
99114
100115 return keyPair .getPublic ();
101116 }
102117
118+ void putPublicKey (CharSequence peer , PublicKey key ) {
119+ this .peerPublicKeys .put (peer , key );
120+ }
121+
103122 /**
104123 * In reality there cannot be such a method - but we are in a test.
105124 * @param subjectID
@@ -142,4 +161,59 @@ public void addKeyPair(String peerID, KeyPair keyPair) {
142161
143162 this .peerKeyPairs .put (peerID , keyPair );
144163 }
164+
165+ /**
166+ * Write storage owners' public key to stream
167+ * @param os
168+ */
169+ public void writePublicKey (OutputStream os ) throws ASAPSecurityException , IOException {
170+ PublicKey publicKey = this .getPublicKey ();
171+
172+ String format = publicKey .getFormat ();
173+ String algorithm = publicKey .getAlgorithm ();
174+ byte [] byteEncodedPublicKey = publicKey .getEncoded ();
175+ int length = byteEncodedPublicKey .length ;
176+
177+ // makes it much easier to serialize simple data
178+ DataOutputStream dos = new DataOutputStream (os );
179+
180+ // write to stream
181+ dos .writeUTF (format );
182+ dos .writeUTF (algorithm );
183+ dos .writeInt (byteEncodedPublicKey .length );
184+
185+ // write encoded key directly on stream
186+ os .write (byteEncodedPublicKey );
187+ }
188+
189+ /**
190+ * Read public key from another peer from an extern source (input stream)
191+ * @param peer
192+ * @param is
193+ */
194+ public void readPublicKey (CharSequence peer , InputStream is ) throws ASAPSecurityException , IOException , NoSuchAlgorithmException , InvalidKeySpecException {
195+ DataInputStream dis = new DataInputStream (is );
196+
197+ // read in same order as written
198+ String format = dis .readUTF ();
199+ String algorithm = dis .readUTF ();
200+ int len = dis .readInt ();
201+
202+ // allocate memory
203+ byte [] byteEncodedPublicKey = new byte [len ];
204+
205+ // read encoded key directly from stream
206+ is .read (byteEncodedPublicKey );
207+
208+ // create key object
209+
210+ // should be revised - why?
211+ X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec (byteEncodedPublicKey );
212+
213+ KeyFactory keyFactory = KeyFactory .getInstance (algorithm );
214+ PublicKey publicKey = keyFactory .generatePublic (pubKeySpec );
215+
216+ // store it
217+ this .putPublicKey (peer , publicKey );
218+ }
145219}
0 commit comments