source: trunk/src/org/expeditee/auth/EncryptedExpReader.java@ 1227

Last change on this file since 1227 was 1227, checked in by bln4, 5 years ago

org.expeditee.auth.EncryptedExpReader ->
org.expeditee.auth.EncryptedExpWriter ->
Actions ->
AttributeUtils ->
Frame ->
FrameIO ->
UserSettings ->

Changed how reading and writing encrypted files worked. A Frame attribute is now consulted to determine what to use as key for encryption. The 'profile' attribute setting is used to signal that the users personal aes key is used. Further enhancement will mean that other labels will be able to be used.


Actions ->

MailMode action now consults the database to reaquire the mail.

File size: 8.8 KB
Line 
1package org.expeditee.auth;
2
3import java.io.BufferedReader;
4import java.io.FileInputStream;
5import java.io.FileReader;
6import java.io.IOException;
7import java.io.InputStreamReader;
8import java.io.Reader;
9import java.io.UnsupportedEncodingException;
10import java.security.InvalidKeyException;
11import java.security.NoSuchAlgorithmException;
12import java.util.Arrays;
13import java.util.Base64;
14
15import javax.crypto.BadPaddingException;
16import javax.crypto.Cipher;
17import javax.crypto.IllegalBlockSizeException;
18import javax.crypto.NoSuchPaddingException;
19import javax.crypto.SecretKey;
20import javax.crypto.spec.SecretKeySpec;
21
22import org.expeditee.gui.Frame;
23import org.expeditee.io.ExpReader;
24import org.expeditee.items.Text;
25import org.expeditee.settings.auth.secrets.KeyList;
26import org.ngikm.cryptography.CryptographyConstants;
27
28import sun.reflect.generics.reflectiveObjects.NotImplementedException;
29
30public class EncryptedExpReader extends ExpReader implements CryptographyConstants {
31 static final String ENCRYPTED_EXP_FLAG = "EncryptedExp";
32 private SecretKey personalKey;
33 //private List<SecretKey> multiKey;
34 private boolean accessDenied = false;
35 //private boolean usePersonalKey;
36
37 public EncryptedExpReader(final String frameName) throws UnsupportedEncodingException {
38 super(frameName);
39 }
40
41 public static boolean isEncryptedExpediteeFile(final String path) throws IOException {
42 final BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
43 final String firstLine = in.readLine();
44 in.close();
45 return firstLine.startsWith(ENCRYPTED_EXP_FLAG);
46 }
47
48 public int getVersionEnc(String fullpath) {
49 try {
50 BufferedReader reader = new EncryptedLineReader(new BufferedReader(new FileReader(fullpath)));
51 //if (usePersonalKey) {
52 // reader = new EncryptedProfileLineReader(new BufferedReader(new FileReader(fullpath)));
53 //} else {
54 // reader = new EncryptedLineReader(new BufferedReader(new FileReader(fullpath)));
55 //}
56 String next = "";
57 // First read the header lines until we get the version number
58 while (reader.ready() && !(next = reader.readLine()).equals("Z")) {
59 if (isValidLine(next)) {
60 Character tag = getTag(next);
61 String value = getValue(next);
62 if (tag.equals('V')) {
63 reader.close();
64 return Integer.parseInt(value);
65 }
66 }
67 }
68 reader.close();
69 } catch (Exception e) {
70 }
71 return -1;
72 }
73
74 @Override
75 public Frame readFrame(final String fullPath) throws IOException {
76 Reader in = new InputStreamReader(new FileInputStream(fullPath), "UTF-8");
77 return readFrame(new EncryptedLineReader(in));
78 //if (usePersonalKey) {
79 // return readFrame(new EncryptedProfileLineReader(new BufferedReader(in)));
80 //} else {
81 // return readFrame(new EncryptedLineReader(new BufferedReader(in)));
82 //}
83 }
84
85 @Override
86 public Frame readFrame(final BufferedReader reader) throws IOException {
87 if (accessDenied) { return null; }
88 else return super.readFrame(reader);
89 }
90
91 private static byte[] DecryptSymmetric(final byte[] toDecrypt, final SecretKey key) {
92 try {
93 final Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
94 cipher.init(Cipher.DECRYPT_MODE, key);
95 final byte[] decryptedBytes = cipher.doFinal(toDecrypt);
96 int indexOfZero = decryptedBytes.length - 1;
97 for (int i = decryptedBytes.length - 1; i >= 0; i--) {
98 if (decryptedBytes[i] != (byte) 0) {
99 indexOfZero = i + 1;
100 break;
101 }
102 }
103 if (indexOfZero < 0) { return decryptedBytes; }
104 else { return Arrays.copyOf(decryptedBytes, indexOfZero); }
105 } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
106 | IllegalBlockSizeException | BadPaddingException e) {
107 e.printStackTrace();
108 return null;
109 }
110 }
111
112 private class EncryptedLineReader extends BufferedReader {
113 public EncryptedLineReader(Reader in) {
114 super(in);
115 }
116
117 @Override
118 /**
119 * Reads a line from an encrypted exp file that uses an encryption specified by the first line of the file.
120 * Returns that line to process, null if the currently logged in users doesn't own the appropriate key (access denied).
121 */
122 public String readLine() throws IOException {
123 String line = super.readLine();
124
125 if (line.isEmpty()) {
126 return "";
127 }
128 if (line.startsWith(ENCRYPTED_EXP_FLAG)) {
129 String label = line.replace(ENCRYPTED_EXP_FLAG, "");
130 // if using Profile label, use personal key
131 if (label.startsWith("Profile")) {
132 Text text = KeyList.PersonalKey.get();
133 byte[] keyBytes = Base64.getDecoder().decode(text.getData().get(0));
134 personalKey = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
135 return readLine();
136 } else {
137 // TODO: resolve encryption label, what does this mean?
138 personalKey = resolveLabel(label);
139 return readLine();
140 }
141 }
142
143 // decrypt line and return result
144 byte[] toDecrypt = Base64.getDecoder().decode(line);
145 byte[] decrypted = DecryptSymmetric(toDecrypt, personalKey);
146 if (decrypted == null) {
147 accessDenied = true;
148 return null; // access denied
149 } else {
150 String decryptedLine = new String(decrypted);
151 if (decryptedLine.startsWith("Z")) {
152 return decryptedLine.trim();
153 } else {
154 return decryptedLine;
155 }
156 }
157 }
158
159 private SecretKeySpec resolveLabel(String label) {
160 throw new NotImplementedException();
161 }
162 }
163
164// private class EncryptedProfileLineReader extends BufferedReader {
165//
166// public EncryptedProfileLineReader(final Reader in) {
167// super(in);
168// }
169//
170// @Override
171// /**
172// * Reads a line from an encrypted exp file that uses profile encryption (single key; personal key)
173// * Returns that line to process, null if the currently logged in users personal key is not the appropriate one (access denied).
174// */
175// public String readLine() throws IOException {
176// // read encrypted line
177// final String line = super.readLine();
178//
179// if (line.isEmpty()) { return ""; }
180// if (line.startsWith(ENCRYPTED_EXP_FLAG)) {
181// // record/overwrite previous personal key then ignore this line by recursing
182// final Text text = KeyList.PersonalKey.get();
183// final byte[] keyBytes = Base64.getDecoder().decode(text.getData().get(0));
184// personalKey = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
185// return readLine();
186// }
187//
188// // decrypt line and return result
189// final byte[] toDecrypt = Base64.getDecoder().decode(line);
190// final byte[] decrypted = DecryptSymmetric(toDecrypt, personalKey);
191// if (decrypted == null) {
192// accessDenied = true;
193// return null; // access denied
194// } else {
195// final String decryptedLine = new String(decrypted);
196// if (decryptedLine.startsWith("Z")) { return decryptedLine.trim(); }
197// else { return decryptedLine; }
198// }
199// }
200// }
201//
202// private class EncryptedLineReader extends BufferedReader {
203//
204// public EncryptedLineReader(final Reader in) {
205// super(in);
206// }
207//
208// @Override
209// /**
210// * Reads a line from an encrypted exp file that uses (potentially multiple) labeled keys
211// * Returns that line to process, null if the ...
212// */
213// public String readLine() throws IOException {
214// // read encrypted line
215// final String line = super.readLine();
216//
217// if (line.isEmpty()) { return ""; }
218// if (line.startsWith(ENCRYPTED_EXP_FLAG)) {
219// // resolve labels to secret keys
220// final List<String> labels = Arrays.asList(line.split(" ")).stream().skip(1).collect(Collectors.toList());
221// final ThrowingFunction<String, SecretKey, Exception> worker = new ThrowingFunction<String, SecretKey, Exception>() {
222// @Override
223// public SecretKey applyThrows(final String label) throws Exception {
224// return Authenticator.getInstance().getSecretKey(label, System.getProperty("password"));
225// }
226// };
227// multiKey = labels.stream().map(l -> {
228// try {
229// return worker.apply(l);
230// } catch (final Exception e) {
231// return null;
232// }
233// }).collect(Collectors.toList());
234//
235// // confirm you have all the keys necessary for decryption
236// if (multiKey.contains(null)) {
237// return null;
238// }
239//
240// // move onto the next line
241// return readLine();
242// }
243//
244// // decrypt line and return result
245// final byte[] toDecrypt = Base64.getDecoder().decode(line);
246// byte[] decryptedBytes = null;
247// for (final SecretKey key: multiKey) {
248// decryptedBytes = DecryptSymmetric(toDecrypt, key);
249// if (decryptedBytes == null) { return null; }
250// }
251// final String decrypted = new String(decryptedBytes);
252// if (decrypted.startsWith("Z")) { return decrypted.trim(); }
253// else { return decrypted; }
254// }
255// }
256}
Note: See TracBrowser for help on using the repository browser.