001/** 002 * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ 003 * 004 * This file is part of Dicoogle/dicoogle. 005 * 006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Dicoogle/dicoogle is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Dicoogle. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package pt.ua.dicoogle.server.users; 020 021import java.io.ByteArrayInputStream; 022import java.io.ByteArrayOutputStream; 023import java.io.FileInputStream; 024import java.io.FileNotFoundException; 025import java.io.FileOutputStream; 026import java.io.IOException; 027import java.io.InputStream; 028import java.io.ObjectInputStream; 029import java.io.ObjectOutputStream; 030import java.security.InvalidKeyException; 031import java.security.Key; 032import java.security.NoSuchAlgorithmException; 033import java.security.SecureRandom; 034 035import javax.crypto.BadPaddingException; 036import javax.crypto.Cipher; 037import javax.crypto.IllegalBlockSizeException; 038import javax.crypto.KeyGenerator; 039import javax.crypto.NoSuchPaddingException; 040import org.slf4j.LoggerFactory; 041 042import pt.ua.dicoogle.core.ServerSettings; 043import pt.ua.dicoogle.sdk.Utils.Platform; 044 045/** 046 * This class provides encryptation to the file that saves users information 047 * Uses the AES algorithim with 128 bit key 048 * 049 * @author Samuel Campos <samuelcampos@ua.pt> 050 */ 051public class UserFileHandle { 052 053 private String filename; 054 private String keyFile; 055 056 private Cipher cipher; 057 private Key key; 058 private boolean encrypt; 059 060 public UserFileHandle() throws IOException { 061 filename = Platform.homePath() + "users.xml"; 062 encrypt = ServerSettings.getInstance().isEncryptUsersFile(); 063 try { 064 065 if(encrypt){ 066 keyFile = "users.key"; 067 068 try { 069 ObjectInputStream in = new ObjectInputStream(new FileInputStream(keyFile)); 070 key = (Key) in.readObject(); 071 in.close(); 072 073 } catch (FileNotFoundException ex) { 074 KeyGenerator gen = KeyGenerator.getInstance("AES"); 075 076 gen.init(128, new SecureRandom()); 077 key = gen.generateKey(); 078 079 try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(keyFile))) { 080 out.writeObject(key); 081 } 082 } 083 084 cipher = Cipher.getInstance("AES"); 085 } 086 087 } catch (NoSuchAlgorithmException | ClassNotFoundException | NoSuchPaddingException ex) { 088 LoggerFactory.getLogger(UserFileHandle.class).error(ex.getMessage(), ex); 089 } 090 } 091 092 /** 093 * Print one byte array in File 094 * Encrypt that file with the key 095 * @param bytes 096 */ 097 public void printFile(byte[] bytes) throws Exception { 098 InputStream in; 099 100 if(encrypt){ 101 cipher.init(Cipher.ENCRYPT_MODE, key); 102 103 byte[] encryptedBytes = cipher.doFinal(bytes); 104 in = new ByteArrayInputStream(encryptedBytes); 105 } 106 else 107 in = new ByteArrayInputStream(bytes); 108 109 FileOutputStream out = new FileOutputStream(filename); 110 111 112 byte[] input = new byte[1024]; 113 int bytesRead; 114 while ((bytesRead = in.read(input)) != -1) { 115 out.write(input, 0, bytesRead); 116 out.flush(); 117 } 118 119 out.close(); 120 in.close(); 121 } 122 123 /** Retrieve the contents of the users configuration file. 124 * @return a byte array, or null if the configuration file is not available or corrupted 125 * @throws IOException on a failed attempt to read the file 126 */ 127 public byte[] getFileContent() throws IOException { 128 try { 129 try (FileInputStream fin = new FileInputStream(filename); 130 ByteArrayOutputStream out = new ByteArrayOutputStream()) { 131 byte[] data = new byte[1024]; 132 int bytesRead; 133 134 while ((bytesRead = fin.read(data)) != -1) { 135 out.write(data, 0, bytesRead); 136 out.flush(); 137 } 138 139 if(encrypt){ 140 cipher.init(Cipher.DECRYPT_MODE, key); 141 byte[] Bytes = cipher.doFinal(out.toByteArray()); 142 return Bytes; 143 } 144 145 return out.toByteArray(); 146 } 147 } catch (FileNotFoundException ex) { 148 LoggerFactory.getLogger(UserFileHandle.class).info("No such users file \"{}\", will create one with default settings.", filename); 149 } catch (IllegalBlockSizeException ex) { 150 LoggerFactory.getLogger(UserFileHandle.class).error("Users file \"{}\" is corrupted, will override it with default settings.", filename, ex); 151 } catch (InvalidKeyException ex) { 152 LoggerFactory.getLogger(UserFileHandle.class).error("Invalid Key to decrypt users file! Please contact your system administator."); 153 System.exit(1); // FIXME this is too dangerous 154 } 155 catch(BadPaddingException ex){ 156 LoggerFactory.getLogger(UserFileHandle.class).error("Invalid Key to decrypt users file! Please contact your system administator."); 157 System.exit(2); // FIXME this is too dangerous 158 } 159 return null; 160 } 161}