// Read a v5 archive, which is a proprietary binary format. bool readV5Config( const char *configFile, EncfsConfig &config, ConfigInfo *) { bool ok = false; // use Config to parse the file and query it.. ConfigReader cfgRdr; if(cfgRdr.load( configFile )) { try { config.set_revision(cfgRdr["subVersion"].readInt(0)); if(config.revision() > V5Latest) { /* config file specifies a version outside our supported range.. */ LOG(ERROR) << "Config subversion " << config.revision() << " found, but this version of encfs only supports up to version " << V5Latest; return false; } if( config.revision() < V5Latest ) { LOG(ERROR) << "This version of EncFS doesn't support " << "filesystems created with EncFS releases before 2004-08-13"; return false; } cfgRdr["creator"] >> (*config.mutable_creator()); cfgRdr["cipher"] >> (*config.mutable_cipher()); cfgRdr["naming"] >> (*config.mutable_naming()); int blockSize; cfgRdr["blockSize"] >> blockSize; config.set_block_size(blockSize); EncryptedKey *encryptedKey = config.mutable_key(); int keySize; cfgRdr["keySize"] >> keySize; encryptedKey->set_size(keySize / 8); cfgRdr["keyData"] >> (*encryptedKey->mutable_ciphertext()); config.set_unique_iv( cfgRdr["uniqueIV"].readBool( false ) ); config.set_chained_iv( cfgRdr["chainedIV"].readBool( false ) ); config.set_external_iv( cfgRdr["externalIV"].readBool( false ) ); config.set_block_mac_bytes( cfgRdr["blockMACBytes"].readInt(0) ); config.set_block_mac_rand_bytes( cfgRdr["blockMACRandBytes"].readInt(0) ); ok = true; } catch( Error &err) { LOG(WARNING) << "Error parsing data in config file " << configFile << "; " << err.what(); ok = false; } } return ok; }
// Read a boost::serialization config file using an Xml reader.. bool readV6Config( const char *configFile, EncfsConfig &cfg, ConfigInfo *info) { (void)info; XmlReader rdr; if (!rdr.load(configFile)) { LOG(ERROR) << "Failed to load config file " << configFile; return false; } XmlValuePtr serialization = rdr["boost_serialization"]; XmlValuePtr config = (*serialization)["cfg"]; if (!config) { config = (*serialization)["config"]; } if (!config) { LOG(ERROR) << "Unable to find XML configuration in file " << configFile; return false; } int version; if (!config->read("version", &version) && !config->read("@version", &version)) { LOG(ERROR) << "Unable to find version in config file"; return false; } // version numbering was complicated by boost::archive if (version == 20 || version >= 20100713) { VLOG(1) << "found new serialization format"; cfg.set_revision(version); } else if (version == 26800) { VLOG(1) << "found 20080816 version"; cfg.set_revision(20080816); } else if (version == 26797) { VLOG(1) << "found 20080813"; cfg.set_revision(20080813); } else if (version < V5Latest) { LOG(ERROR) << "Invalid version " << version << " - please fix config file"; } else { LOG(INFO) << "Boost <= 1.41 compatibility mode"; cfg.set_revision(version); } VLOG(1) << "subVersion = " << cfg.revision(); config->read("creator", cfg.mutable_creator()); config->read("cipherAlg", cfg.mutable_cipher()); config->read("nameAlg", cfg.mutable_naming()); //(*config)["keySize"] >> cfg.keySize; int blockSize, blockMacBytes, blockMacRandBytes; bool uniqueIv, chainedNameIv, externalIv, allowHoles; config->read("blockSize", &blockSize); config->read("uniqueIV", &uniqueIv); config->read("chainedNameIV", &chainedNameIv); config->read("externalIVChaining", &externalIv); config->read("blockMACBytes", &blockMacBytes); config->read("blockMACRandBytes", &blockMacRandBytes); config->read("allowHoles", &allowHoles); cfg.set_block_size(blockSize); cfg.set_unique_iv(uniqueIv); cfg.set_chained_iv(chainedNameIv); cfg.set_external_iv(externalIv); cfg.set_block_mac_bytes(blockMacBytes); cfg.set_block_mac_rand_bytes(blockMacRandBytes); cfg.set_allow_holes(allowHoles); EncryptedKey *encryptedKey = cfg.mutable_key(); int encodedSize; config->read("encodedKeySize", &encodedSize); unsigned char *key = new unsigned char[encodedSize]; config->readB64("encodedKeyData", key, encodedSize); encryptedKey->set_ciphertext(key, encodedSize); delete[] key; int keySize; config->read("keySize", &keySize); encryptedKey->set_size(keySize / 8); // save as size in bytes if(cfg.revision() >= 20080816) { int saltLen; config->read("saltLen", &saltLen); unsigned char *salt = new unsigned char[saltLen]; config->readB64("saltData", salt, saltLen); encryptedKey->set_salt(salt, saltLen); delete[] salt; int kdfIterations, desiredKDFDuration; config->read("kdfIterations", &kdfIterations); config->read("desiredKDFDuration", &desiredKDFDuration); encryptedKey->set_kdf_iterations(kdfIterations); encryptedKey->set_kdf_duration(desiredKDFDuration); } else { encryptedKey->clear_salt(); encryptedKey->set_kdf_iterations(16); encryptedKey->clear_kdf_duration(); } return true; }