source: trunk/src/org/expeditee/auth/Mail.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: 6.3 KB
Line 
1package org.expeditee.auth;
2
3import java.nio.file.Path;
4import java.security.InvalidKeyException;
5import java.security.NoSuchAlgorithmException;
6import java.security.PrivateKey;
7import java.security.PublicKey;
8import java.sql.Connection;
9import java.sql.DriverManager;
10import java.sql.PreparedStatement;
11import java.sql.SQLException;
12import java.util.ArrayList;
13import java.util.Arrays;
14import java.util.Base64;
15import java.util.HashMap;
16import java.util.List;
17import java.util.Map;
18
19import javax.crypto.BadPaddingException;
20import javax.crypto.Cipher;
21import javax.crypto.IllegalBlockSizeException;
22import javax.crypto.NoSuchPaddingException;
23
24import org.ngikm.cryptography.CryptographyConstants;
25
26public class Mail implements CryptographyConstants {
27
28 private static List<MailEntry> messages = new ArrayList<MailEntry>();
29
30 /**
31 * Add a piece of mail, used during initialisation.
32 */
33 public static void addEntry(MailEntry mail) {
34 messages.add(mail);
35 }
36
37 public static void clear() {
38 messages.clear();
39 }
40
41 public static void sendMail(MailEntry mail, PublicKey key, Path outbox) {
42 try {
43 Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
44
45 // encrypt the necessary parts of the message
46 cipher.init(Cipher.ENCRYPT_MODE, key);
47 String time = Base64.getEncoder().encodeToString(cipher.doFinal(mail.timestamp.getBytes()));
48 cipher.init(Cipher.ENCRYPT_MODE, key);
49 String sender = Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
50 cipher.init(Cipher.ENCRYPT_MODE, key);
51 String rec = Base64.getEncoder().encodeToString(cipher.doFinal(mail.receiver.getBytes()));
52 cipher.init(Cipher.ENCRYPT_MODE, key);
53 String message = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message.getBytes()));
54 cipher.init(Cipher.ENCRYPT_MODE, key);
55 String message2 = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message2.getBytes()));
56
57 Map<String, String> options = new HashMap<String, String>();
58 for (String label: mail.options.keySet()) {
59 cipher.init(Cipher.ENCRYPT_MODE, key);
60 String labelEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(label.getBytes()));
61 cipher.init(Cipher.ENCRYPT_MODE, key);
62 String actionNameEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(mail.options.get(label).getBytes()));
63 options.put(labelEncrypted, actionNameEncrypted);
64 }
65
66 // write to mail database
67 Connection c = DriverManager.getConnection("jdbc:sqlite:" + outbox.resolve("expmail.db"));
68 String sql = "INSERT INTO EXPMAIL (TIME,SND,REC,MSG,MSG2,OPTS,OPTSVAL) VALUES (?, ?, ?, ?, ?, ?, ?);";
69 PreparedStatement statement = c.prepareStatement(sql);
70 statement.setString(1, time);
71 statement.setString(2, sender);
72 statement.setString(3, rec);
73 statement.setString(4, message);
74 statement.setString(5, message2);
75 String opts = Arrays.toString(options.keySet().toArray());
76 statement.setString(6, opts);
77 String optsval = Arrays.toString(options.values().toArray());
78 statement.setString(7, optsval);
79 statement.execute();
80 statement.close();
81 c.close();
82 } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | SQLException e) {
83 e.printStackTrace();
84 }
85 }
86
87 /**
88 * Gets the mail messages that the specified user is able to read.
89 * The caller supplies their username and private key.
90 * If the private key can decrypt a message, then it was encrypted using the users public key, and is therefore for them.
91 */
92 public static List<MailEntry> getEntries(String name, PrivateKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
93 List<MailEntry> filtered = new ArrayList<MailEntry>();
94
95 for (MailEntry mail: messages) {
96 // confirm this is a message for the requester of entries
97 String receiver = mail.receiver;
98 byte[] receiverBytes = Base64.getDecoder().decode(receiver);
99 String receiverDecrypted = null;
100 Cipher c = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
101 try {
102 c.init(Cipher.DECRYPT_MODE, key);
103 receiverDecrypted = new String(c.doFinal(receiverBytes));
104 } catch (InvalidKeyException | BadPaddingException e) {
105 // this is not a message for 'us'
106 continue;
107 }
108
109 // add an unencrypted version of the message to the return list
110 if (receiverDecrypted.compareToIgnoreCase(name) == 0) {
111 c.init(Cipher.DECRYPT_MODE, key);
112 String timestamp = new String(c.doFinal(Base64.getDecoder().decode(mail.timestamp)));
113 c.init(Cipher.DECRYPT_MODE, key);
114 String sender = new String(c.doFinal(Base64.getDecoder().decode(mail.sender)));
115 c.init(Cipher.DECRYPT_MODE, key);
116 String message = new String(c.doFinal(Base64.getDecoder().decode(mail.message)));
117 c.init(Cipher.DECRYPT_MODE, key);
118 String message2 = new String(c.doFinal(Base64.getDecoder().decode(mail.message2)));
119
120 Map<String, String> options = new HashMap<String, String>(); //mail.options;
121 for (String label: mail.options.keySet()) {
122 c.init(Cipher.DECRYPT_MODE, key);
123 String labelDecrypted = new String(c.doFinal(Base64.getDecoder().decode(label)));
124 c.init(Cipher.DECRYPT_MODE, key);
125 String actionNameDecrypted = new String(c.doFinal(Base64.getDecoder().decode(mail.options.get(label))));
126 options.put(labelDecrypted, actionNameDecrypted);
127 }
128
129 //String arguments = new String(c.doFinal(Base64.getDecoder().decode(mail.args)));
130 filtered.add(new MailEntry(timestamp, sender, receiverDecrypted, message, message2, options));
131 }
132 }
133
134 return filtered;
135 }
136
137 /**
138 * Describes a piece of mail, either encrypted or decrypted.
139 */
140 public static class MailEntry {
141 public String timestamp;
142 public String sender;
143 public String receiver;
144 public String message;
145 public String message2;
146 public Map<String, String> options;
147
148 public MailEntry(String timestamp, String sender, String rec, String message, String message2, Map<String, String> options) {
149 this.timestamp = timestamp;
150 this.sender = sender;
151 this.receiver = rec;
152 this.message = message;
153 this.message2 = message2;
154 this.options = options;
155 }
156 }
157}
Note: See TracBrowser for help on using the repository browser.