/* * EncFS Java Library * Copyright (C) 2011-2012 Mark R. Pariente * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. */ package org.mrpdaemon.sec.encfs; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Properties; /** * Writer methods that write an EncFSConfig into a file */ public final class EncFSConfigWriter { // Version to use if the properties file can't be read private static final String ENCFS_JAVA_LIB_VERSION_DEV = "JFileSync3"; // Property file private static final String ENCFS_JAVA_LIB_PROPERTY_FILE = "library.properties"; // Property key for version private static final String ENCFS_JAVA_LIB_VERSION_KEY = "library.version"; private EncFSConfigWriter() { } // Retrieve library version private static String getLibraryVersion() { Properties prop = new Properties(); InputStream in = EncFSConfigWriter.class .getResourceAsStream(ENCFS_JAVA_LIB_PROPERTY_FILE); if (in!=null) { try { prop.load(in); String version = prop.getProperty(ENCFS_JAVA_LIB_VERSION_KEY); if (version!=null) { return version; } else { return ENCFS_JAVA_LIB_VERSION_DEV; } } catch (IOException e) { return ENCFS_JAVA_LIB_VERSION_DEV; } } else { return ENCFS_JAVA_LIB_VERSION_DEV; } } // Create config file contents from a given EncFSConfig / password private static String createConfigFileContents(EncFSConfig config) { // TODO: This implementation is pretty horrible, but it works :) String result = ""; result += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"; result += "<!DOCTYPE boost_serialization>\n"; result += "<boost_serialization signature=\"serialization::archive\" version=\"9\">\n"; result += " <cfg class_id=\"0\" tracking_level=\"0\" version=\"20\">\n"; result += "\t<version>20100713</version>\n"; result += "\t<creator>encfs-java "+getLibraryVersion() +"</creator>\n"; result += "\t<cipherAlg class_id=\"1\" tracking_level=\"0\" version=\"0\">\n"; result += "\t\t<name>ssl/aes</name>\n"; result += "\t\t<major>3</major>\n"; result += "\t\t<minor>0</minor>\n"; result += "\t</cipherAlg>\n"; result += "\t<nameAlg>\n"; EncFSFilenameEncryptionAlgorithm algorithm = config .getFilenameAlgorithm(); result += "\t\t<name>"+algorithm.getIdentifier()+"</name>\n"; result += "\t\t<major>"+algorithm.getMajor()+"</major>\n"; result += "\t\t<minor>"+algorithm.getMinor()+"</minor>\n"; result += "\t</nameAlg>\n"; result += "\t<keySize>" +Integer.toString(config.getVolumeKeySizeInBits()) +"</keySize>\n"; result += "\t<blockSize>" +Integer.toString(config.getEncryptedFileBlockSizeInBytes()) +"</blockSize>\n"; result += "\t<uniqueIV>"+(config.isUseUniqueIV() ? "1" : "0") +"</uniqueIV>\n"; result += "\t<chainedNameIV>"+(config.isChainedNameIV() ? "1" : "0") +"</chainedNameIV>\n"; result += "\t<externalIVChaining>" +(config.isSupportedExternalIVChaining() ? "1" : "0") +"</externalIVChaining>\n"; result += "\t<blockMACBytes>" +Integer .toString(config.getNumberOfMACBytesForEachFileBlock()) +"</blockMACBytes>\n"; result += "\t<blockMACRandBytes>" +Integer.toString(config .getNumberOfRandomBytesInEachMACHeader()) +"</blockMACRandBytes>\n"; result += "\t<allowHoles>" +(config.isHolesAllowedInFiles() ? "1" : "0") +"</allowHoles>\n"; result += "\t<encodedKeySize>" +Integer.toString(config.getEncodedKeyLengthInBytes()) +"</encodedKeySize>\n"; result += "\t<encodedKeyData>"+config.getBase64EncodedVolumeKey() +"\n</encodedKeyData>\n"; result += "\t<saltLen>"+Integer.toString(config.getSaltLengthBytes()) +"</saltLen>\n"; result += "\t<saltData>"+config.getBase64Salt()+"\n</saltData>\n"; result += "\t<kdfIterations>" +Integer.toString(config .getIterationForPasswordKeyDerivationCount()) +"</kdfIterations>\n"; // XXX: We don't support custom KDF durations result += "\t<desiredKDFDuration>500</desiredKDFDuration>\n"; result += " </cfg>\n"; result += "</boost_serialization>\n"; return result; } /** * Create a configuration file from the given EncFSConfig and write it to * the root directory of the given EncFSFileProvider */ public static void writeConfig(EncFSFileProvider fileProvider, EncFSConfig config) throws EncFSUnsupportedException, IOException { String configFileName = fileProvider.getFilesystemRootPath() +EncFSVolume.CONFIG_FILE_NAME; if (fileProvider.exists(configFileName)) { throw new EncFSUnsupportedException("Config file already exists"); } String configFileContents = createConfigFileContents(config); OutputStream os = fileProvider.openOutputStream(configFileName, configFileContents.length()); os.write(configFileContents.getBytes()); os.close(); } }