source: trunk/src/org/expeditee/encryption/io/EncryptedExpWriter.java@ 1415

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

Renamed Frame.getItems() to Frame.getSortedItems() to better represent its functionality.

-> org.apollo.ApolloGestureActions
-> org.apollo.ApolloSystem
-> org.expeditee.actions.Actions
-> org.expeditee.actions.Debug
-> org.expeditee.actions.ExploratorySearchActions
-> org.expeditee.actions.JfxBrowserActions
-> org.expeditee.actions.Misc
-> org.expeditee.actions.Navigation
-> org.expeditee.actions.ScriptBase
-> org.expeditee.actions.Simple
-> org.expeditee.agents.ComputeTree
-> org.expeditee.agents.CopyTree
-> org.expeditee.agents.DisplayComet
-> org.expeditee.agents.DisplayTree
-> org.expeditee.agents.DisplayTreeLeaves
-> org.expeditee.agents.GraphFramesetLinks
-> org.expeditee.agents.TreeProcessor
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.DisplayController
-> org.expeditee.gui.FrameCreator
-> org.expeditee.gui.FrameIO
-> org.expeditee.io.DefaultTreeWriter
-> org.expeditee.io.JavaWriter
-> org.expeditee.io.PDF2Writer
-> org.expeditee.io.TXTWriter
-> org.expeditee.io.WebParser
-> org.expeditee.io.flowlayout.XGroupItem
-> org.expeditee.items.Dot
-> org.expeditee.items.Item
-> org.expeditee.items.ItemUtils
-> org.expeditee.network.FrameShare
-> org.expeditee.stats.TreeStats


Created ItemsList class to wrap ArrayList<Item>. Frames now use this new class to store its body list (used for display) as well as its primaryBody and surrogateBody.

-> org.expeditee.agents.Format
-> org.expeditee.agents.HFormat
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.Frame
-> org.expeditee.gui.FrameUtils


Refactorted Frame.setResort(bool) to Frame.invalidateSorted() to better function how it is intended to with a more accurate name.

-> org.expeditee.agents.Sort


When writing out .exp files and getting attributes to respond to LEFT + RIGHT click, boolean items are by default true. This has always been the case. An ammendment to this is that defaults can now be established.
Also added 'EnterClick' functionality. If cursored over a item with this property and you press enter, it acts as if you have clicked on it instead.

-> org.expeditee.assets.resources-public.framesets.authentication.1.exp to 6.exp
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gio.input.KBMInputEvent
-> org.expeditee.gio.javafx.JavaFXConversions
-> org.expeditee.gio.swing.SwingConversions
-> org.expeditee.gui.AttributeUtils
-> org.expeditee.io.Conversion
-> org.expeditee.io.DefaultFrameWriter
-> org.expeditee.items.Item


Fixed a bug caused by calling Math.abs on Integer.MIN_VALUE returning unexpected result. Due to zero being a thing, you cannot represent Math.abs(Integer.MIN_VALUE) in a Integer object. The solution is to use Integer.MIN_VALUE + 1 instead of Integer.MIN_VALUE.

-> org.expeditee.core.bounds.CombinationBounds
-> org.expeditee.io.flowlayout.DimensionExtent


Recoded the contains function in EllipticalBounds so that intersection tests containing circles work correctly.

-> org.expeditee.core.bounds.EllipticalBounds


Added toString() to PolygonBounds to allow for useful printing during debugging.

-> org.expeditee.core.bounds.PolygonBounds

Implemented Surrogate Mode!

-> org.expeditee.encryption.io.EncryptedExpReader
-> org.expeditee.encryption.io.EncryptedExpWriter
-> org.expeditee.encryption.items.surrogates.EncryptionDetail
-> org.expeditee.encryption.items.surrogates.Label
-> org.expeditee.gui.FrameUtils
-> org.expeditee.gui.ItemsList
-> org.expeditee.items.Item
-> org.expeditee.items.Text


???? Use Integer.MAX_VALUE cast to a float instead of Float.MAX_VALUE. This fixed some bug which I cannot remember.

-> org.expeditee.gio.TextLayoutManager
-> org.expeditee.gio.swing.SwingTextLayoutManager


Improved solution for dealing with the F10 key taking focus away from Expeditee due to it being a assessibility key.

-> org.expeditee.gio.swing.SwingInputManager


Renamed variable visibleItems in FrameGraphics.paintFrame to itemsToPaintCanditates to better represent functional intent.

-> org.expeditee.gui.FrameGraphics


Improved checking for if personal resources exist before recreating them

-> org.expeditee.gui.FrameIO


Repeated messages to message bay now have a visual feedback instead of just a beep. This visual feedback is in the form of a count of the amount of times it has repeated.

-> org.expeditee.gui.MessageBay


Updated comment on the Vector class to explain what vectors are.

-> org.expeditee.gui.Vector


Added constants to represent all of the property keys in DefaultFrameReader and DefaultFrameWriter.

-> org.expeditee.io.DefaultFrameReader
-> org.expeditee.io.DefaultFrameWriter


Updated the KeyList setting to be more heirarcial with how users will store their Secrets.

-> org.expeditee.settings.identity.secrets.KeyList

File size: 9.8 KB
Line 
1package org.expeditee.encryption.io;
2
3import java.io.IOException;
4import java.lang.reflect.InvocationTargetException;
5import java.lang.reflect.Method;
6import java.security.InvalidKeyException;
7import java.security.NoSuchAlgorithmException;
8import java.util.Arrays;
9import java.util.Base64;
10import java.util.LinkedHashMap;
11import java.util.List;
12import java.util.function.BinaryOperator;
13import java.util.function.Function;
14import java.util.stream.Collectors;
15
16import javax.crypto.BadPaddingException;
17import javax.crypto.Cipher;
18import javax.crypto.IllegalBlockSizeException;
19import javax.crypto.NoSuchPaddingException;
20import javax.crypto.SecretKey;
21import javax.crypto.spec.SecretKeySpec;
22
23import org.expeditee.encryption.CryptographyConstants;
24import org.expeditee.encryption.items.surrogates.EncryptionDetail;
25import org.expeditee.encryption.items.surrogates.EncryptionDetail.Type;
26import org.expeditee.encryption.items.surrogates.Label;
27import org.expeditee.encryption.items.surrogates.Label.LabelResult;
28import org.expeditee.gui.Frame;
29import org.expeditee.gui.Frame.BodyType;
30import org.expeditee.gui.MessageBay;
31import org.expeditee.io.Conversion;
32import org.expeditee.io.ExpWriter;
33import org.expeditee.items.Item;
34import org.expeditee.items.Line;
35import org.expeditee.items.Text;
36import org.expeditee.settings.identity.secrets.KeyList;
37import org.expeditee.stats.SessionStats;
38
39public class EncryptedExpWriter extends ExpWriter implements CryptographyConstants {
40 private SecretKey key;
41
42 private final String label;
43
44 private static final String ENCRYPTED_EXP_FLAG = "EncryptedExp";
45 private static final String nl = "\n";
46 private static final String labelProfile = "Profile";
47 private static final String labelNone = "None";
48 protected static final char TERMINATOR = 'Z';
49 protected static final String TERMINATOR_WITH_CONTINUATION = TERMINATOR + "...";
50
51 public EncryptedExpWriter(String encryptionLabel) {
52 label = encryptionLabel;
53 if (label.equals(labelNone)) {
54 return;
55 }
56
57 if (label.equals(labelProfile)) {
58 // obtain personal key
59 Text text = KeyList.PersonalKey.get();
60 List<String> data = text.getData();
61 if (data != null && !data.isEmpty()) {
62 byte[] keyBytes = Base64.getDecoder().decode(data.get(0));
63 key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
64 }
65 } else {
66 LabelResult res = Label.getLabel(label);
67 if (res == LabelResult.SuccessResolveLabelToKey) {
68 byte[] keyBytes = res.key;
69 key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
70 } else if (res == LabelResult.ErrorUnableToFindLabel) {
71 MessageBay.errorMessage(res.toString() + encryptionLabel);
72 key = null;
73 } else {
74 MessageBay.errorMessage(res.toString());
75 }
76 }
77 }
78
79 @Override
80 protected void preOutputFrame() {
81 try {
82 String line = ENCRYPTED_EXP_FLAG + label + nl;
83 _writer.write(line);
84 _stringWriter.append(line);
85 } catch (final IOException e) {
86 e.printStackTrace();
87 }
88 }
89
90 @Override
91 public void outputFrame(Frame frame) throws IOException {
92 if (_writer == null) { return; }
93
94 preOutputFrame();
95 writeHeader(frame);
96
97 // write item
98 writeItemData(frame, true);
99 writeTerminator();
100 // write lines and constraints
101 writeLineData();
102 writeTerminator();
103 writeConstraintData();
104
105 // write surrogate items
106 if (frame.hasSurrogates()) {
107 writeSurrogateTerminator();
108 writeItemData(frame, false);
109 writeTerminator();
110 } else {
111 writeTerminator();
112 }
113
114 writeLine(SessionStats.getFrameEventList(frame));
115 }
116
117 @Override
118 protected void writeLine(String line) throws IOException {
119 // do not write empty lines
120 if (line == null) { return; }
121
122 String toWrite;
123 if (key == null && label.equals(labelNone)) {
124 toWrite = line + nl;
125 } else {
126 // prepare line to write out
127 byte[] encrypted = EncryptSymmetric(line.getBytes(), key);
128 toWrite = Base64.getEncoder().encodeToString(encrypted) + nl;
129 }
130
131 // output
132 _writer.write(toWrite);
133 _stringWriter.append(toWrite);
134 }
135
136 protected void writeClass(Item toWrite) throws IOException {
137 if (toWrite instanceof Text && toWrite.getText().equals("Content for Label Two")) {
138 System.err.println("EncryptedExpWriter::writeClass::breakpoint");
139 } else if (toWrite instanceof Text && toWrite.getText().equals("Encrypted") && toWrite.getPrimary().getText().equals("Content for Label One")) {
140 System.err.println("EncryptedExpWriter::writeClass::breakpoint");
141 }
142
143 LinkedHashMap<Character,Method> itemTags = new LinkedHashMap<Character, Method>(getItemTags());
144 LinkedHashMap<String,Method> itemTagsExt = new LinkedHashMap<String, Method>(getItemTagsExt());
145
146 writeTag(toWrite, new Object[] {}, itemTags, 'S');
147 writeTag(toWrite, new Object[] {}, itemTagsExt, "_el");
148
149 if (toWrite.isSurrogate()) {
150 writeLine("SurrogateFor " + toWrite.getPrimary().getID());
151 }
152
153 itemTags.remove('S');
154 itemTagsExt.remove("_el");
155
156 writeTags(toWrite, new Object[] {}, itemTags);
157 writeTags(toWrite, new Object[] {}, itemTagsExt);
158 }
159
160 @Override
161 protected <T> void writeTag(Item toWrite, Object[] param, LinkedHashMap<T, Method> tags, T tag) {
162 if (toWrite.isSurrogate() && toWrite.isTagInherited(tag + "")) {
163 return;
164 }
165 EncryptionDetail encryptionDetail = toWrite.getEncryptionDetailForTag(tag + "");
166 Type encryptionDetailType = encryptionDetail.getEncryptionDetailType();
167
168 switch(encryptionDetailType) {
169 case UnencryptedOnSave:
170 writeTagUnencryptedOnSave(toWrite, param, tags, tag);
171 break;
172 case InheritanceCheckOnSave:
173 writeTagInheritanceCheckOnSave(toWrite, tags, tag);
174 break;
175 case ReencryptOnSave:
176 writeTagReencryptOnSave(toWrite, tags, tag);
177 break;
178 case UseUndecipheredValueOnSave:
179 writeTagUseUndecipheredValueOnSave(toWrite, tags, tag);
180 break;
181 }
182 }
183
184 private void writeItemData(Frame frame, boolean primaryItems) throws IOException {
185 // write each item in the frame
186 BodyType bodyType = primaryItems ? BodyType.PrimaryBody : BodyType.SurrogateBody;
187 for (Item i : frame.getItemsToSave(bodyType)) {
188 assert (!(i instanceof Line));
189 writeItem(i);
190 }
191
192 for (Item i: frame.getBodyItemsWithInsufficientPermissions()) {
193 assert (!(i instanceof Line));
194 writeItem(i);
195 }
196 }
197
198 private <T> void writeTagInheritanceCheckOnSave(Item toWrite, LinkedHashMap<T, Method> tags, T tag) {
199 List<Item> surrogateItems = toWrite.getSurrogates().stream().collect(Collectors.toList());
200 Function<Item, Boolean> isTagInherited = surrogate -> surrogate.isTagInherited(tag + "");
201 BinaryOperator<Boolean> trueExists = (a, b) -> a || b;
202 boolean surrogatesInherit = surrogateItems.stream().map(isTagInherited).collect(Collectors.reducing(trueExists)).get();
203 boolean userHasKey = Label.getLabel(toWrite.getEncryptionLabel()) == LabelResult.SuccessResolveLabelToKey;
204
205 if (!surrogatesInherit && userHasKey) {
206 EncryptionDetail reencryptOnSave = new EncryptionDetail(EncryptionDetail.Type.ReencryptOnSave);
207 toWrite.setEncryptionDetailForTag(tag + "", reencryptOnSave);
208 writeTagReencryptOnSave(toWrite, tags, tag);
209 } else {
210 EncryptionDetail unencryptedOnSave = new EncryptionDetail(EncryptionDetail.Type.UnencryptedOnSave);
211 toWrite.setEncryptionDetailForTag(tag + "", unencryptedOnSave);
212 writeTagUnencryptedOnSave(toWrite, new Object[] {}, tags, tag);
213 }
214 }
215
216 private <T> void writeTagReencryptOnSave(Item toWrite, LinkedHashMap<T, Method> tags, T tag) {
217 Method toRun = tags.get(tag);
218 Class<?> declarer = toRun.getDeclaringClass();
219 LabelResult res = Label.getLabel(toWrite.getEncryptionLabel());
220 if (declarer.isAssignableFrom(toWrite.getClass()) && res == LabelResult.SuccessResolveLabelToKey) {
221 try {
222 Object o = toRun.invoke(toWrite, new Object[] {});
223 o = Conversion.ConvertToExpeditee(toRun, o);
224 if (o == null) {
225 return;
226 }
227 if (o instanceof List) {
228 for (Object line: (List<?>) o) {
229 writeLineEnc(tag, line, res.key);
230 }
231 } else {
232 writeLineEnc(tag, o, res.key);
233 }
234 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
235 e.printStackTrace();
236 } catch (IOException e) {
237 e.printStackTrace();
238 }
239 }
240 }
241
242 private <T> void writeTagUseUndecipheredValueOnSave(Item toWrite, LinkedHashMap<T, Method> tags, T tag) {
243 EncryptionDetail encryptionDetail = toWrite.getEncryptionDetailForTag(tag + "");
244 try {
245 writeLine(tag + "E", encryptionDetail.getUndecipheredValue());
246 } catch (IOException e) {
247 e.printStackTrace();
248 }
249 }
250
251 private <T> void writeTagUnencryptedOnSave(Item toWrite, Object[] param, LinkedHashMap<T, Method> tags, T tag) {
252 super.writeTag(toWrite, param, tags, tag);
253 }
254
255 private void writeSurrogateTerminator() throws IOException {
256 writeLine(TERMINATOR_WITH_CONTINUATION + nl);
257 }
258
259 private <T> void writeLineEnc(T tag, Object line, byte[] keyBytes) throws IOException {
260 SecretKey key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
261 byte[] lineEncryptedBytes = EncryptSymmetric(line.toString().getBytes(), key);
262 line = Base64.getEncoder().encodeToString(lineEncryptedBytes);
263 writeLine(tag + "E", line.toString());
264 }
265
266 private static byte[] EncryptSymmetric(byte[] toEncrypt, SecretKey key) {
267 try {
268 Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
269 cipher.init(Cipher.ENCRYPT_MODE, key);
270 //could use modulus
271 int length = (int) ((Math.ceil(toEncrypt.length / 16f)) * 16);
272 byte[] toEncryptSizeAdjusted = Arrays.copyOf(toEncrypt, length);
273 byte[] result = cipher.doFinal(toEncryptSizeAdjusted);
274 return result;
275 } catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
276 | IllegalBlockSizeException | BadPaddingException e) {
277 e.printStackTrace();
278 return null;
279 }
280 }
281}
Note: See TracBrowser for help on using the repository browser.