void save(Archive &ar, const EncFSConfig &cfg, unsigned int version) { (void)version; // version 20 (aka 20100613) if (cfg.subVersion == 0) ar << make_nvp("version", V6SubVersion); else ar << make_nvp("version", cfg.subVersion); ar << make_nvp("creator", cfg.creator); ar << make_nvp("cipherAlg", cfg.cipherIface); ar << make_nvp("nameAlg", cfg.nameIface); ar << make_nvp("keySize", cfg.keySize); ar << make_nvp("blockSize", cfg.blockSize); ar << make_nvp("uniqueIV", cfg.uniqueIV); ar << make_nvp("chainedNameIV", cfg.chainedNameIV); ar << make_nvp("externalIVChaining", cfg.externalIVChaining); ar << make_nvp("blockMACBytes", cfg.blockMACBytes); ar << make_nvp("blockMACRandBytes", cfg.blockMACRandBytes); ar << make_nvp("allowHoles", cfg.allowHoles); int encodedSize = cfg.keyData.size(); ar << make_nvp("encodedKeySize", encodedSize); ar << make_nvp("encodedKeyData", serial::make_binary_object(cfg.getKeyData(), encodedSize)); // version 20080816 int size = cfg.salt.size(); ar << make_nvp("saltLen", size); ar << make_nvp("saltData", serial::make_binary_object(cfg.getSaltData(), size)); ar << make_nvp("kdfIterations", cfg.kdfIterations); ar << make_nvp("desiredKDFDuration", cfg.desiredKDFDuration); }
static int do_chpasswd(bool useStdin, bool annotate, bool checkOnly, int argc, char **argv) { (void)argc; string rootDir = argv[1]; if (!checkDir(rootDir)) return EXIT_FAILURE; EncFSConfig *config = new EncFSConfig; ConfigType cfgType = readConfig(rootDir, config); if (cfgType == Config_None) { cout << _("Unable to load or parse config file\n"); return EXIT_FAILURE; } // instanciate proper cipher std::shared_ptr<Cipher> cipher = Cipher::New(config->cipherIface, config->keySize); if (!cipher) { cout << autosprintf(_("Unable to find specified cipher \"%s\"\n"), config->cipherIface.name().c_str()); return EXIT_FAILURE; } // ask for existing password cout << _("Enter current Encfs password\n"); if (annotate) cerr << "$PROMPT$ passwd" << endl; CipherKey userKey = config->getUserKey(useStdin); if (!userKey) return EXIT_FAILURE; // decode volume key using user key -- at this point we detect an incorrect // password if the key checksum does not match (causing readKey to fail). CipherKey volumeKey = cipher->readKey(config->getKeyData(), userKey); if (!volumeKey) { cout << _("Invalid password\n"); return EXIT_FAILURE; } if (checkOnly) { cout << _("Password is correct\n"); return EXIT_SUCCESS; } // Now, get New user key.. userKey.reset(); cout << _("Enter new Encfs password\n"); // reinitialize salt and iteration count config->kdfIterations = 0; // generate new if (useStdin) { if (annotate) cerr << "$PROMPT$ new_passwd" << endl; userKey = config->getUserKey(true); } else userKey = config->getNewUserKey(); // re-encode the volume key using the new user key and write it out.. int result = EXIT_FAILURE; if (userKey) { int encodedKeySize = cipher->encodedKeySize(); unsigned char *keyBuf = new unsigned char[encodedKeySize]; // encode volume key with new user key cipher->writeKey(volumeKey, keyBuf, userKey); userKey.reset(); config->assignKeyData(keyBuf, encodedKeySize); delete[] keyBuf; if (saveConfig(cfgType, rootDir, config)) { // password modified -- changes volume key of filesystem.. cout << _("Volume Key successfully updated.\n"); result = EXIT_SUCCESS; } else { cout << _("Error saving modified config file.\n"); } } else { cout << _("Error creating key\n"); } volumeKey.reset(); return result; }