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

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

Alterations to how mail works to work better in a cloud environment.
General code tidying and updating to work with larger changes happening to Expeditee.

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