SecureMem *passwordFromPrompts() { SecureMem *buf = new SecureMem(MaxPassBuf); SecureMem *buf2 = new SecureMem(MaxPassBuf); do { // xgroup(common) char *res1 = readpassphrase(_("New Encfs Password: "******"Verify Encfs Password: "******"Passwords did not match, please try again\n"); } } while(1); delete buf2; return buf; }
// Doesn't use SecureMem, since we don't know how much will be read. // Besides, password is being produced by another program. std::string readPassword( int FD ) { SecureMem *buf = new SecureMem(1024); string result; while(1) { ssize_t rdSize = recv(FD, buf->data(), buf->size(), 0); if(rdSize > 0) { result.append( (char*)buf->data(), rdSize ); } else break; } // chop off trailing "\n" if present.. // This is done so that we can use standard programs like ssh-askpass // without modification, as it returns trailing newline.. if(!result.empty() && result[ result.length()-1 ] == '\n' ) result.resize( result.length() -1 ); delete buf; return result; }
CipherKey getUserKey(const EncfsConfig &config, const std::string &passProg, const std::string &rootDir) { CipherKey result; SecureMem *password = passwordFromProgram(passProg, rootDir); if (password) { result = decryptKey(config, (char *)password->data(), strlen((char *)password->data())); delete password; } return result; }
string CryptoBackend::encryptBlob(SecureMem<unsigned char> toEncrypt, SecureMem<unsigned char> passphrase, string iv, string salt) { byte *encrypted = NULL; SecureMem<unsigned char> key; key = keyDerivation(passphrase, reinterpret_cast<byte*> (const_cast<char*>(salt.c_str()))); CFB_Mode<AES>::Encryption cfbEncryption(key.getPointer(), key.getLen(), reinterpret_cast<const byte*> (iv.c_str())); cfbEncryption.ProcessData(encrypted, toEncrypt.getPointer(), toEncrypt.getLen()); return string(const_cast<const char*> (reinterpret_cast<char*> (encrypted))); }
SecureMem *passwordFromPrompt() { SecureMem *buf = new SecureMem(MaxPassBuf); // xgroup(common) char *res = readpassphrase(_("EncFS Password: "), (char *)buf->data(), buf->size() - 1, RPP_ECHO_OFF); if (!res) { delete buf; buf = NULL; } return buf; }
CipherKey getUserKey(const EncfsConfig &config, bool useStdin) { CipherKey userKey; SecureMem *password; if (useStdin) password = passwordFromStdin(); else password = passwordFromPrompt(); if (password) { userKey = decryptKey(config, (char *)password->data(), strlen((char *)password->data())); delete password; } return userKey; }
AuthenticationProtocol::AuthenticationProtocol ( Volume volume ) { SecureMem<char> dummy; CryptSetup tool; vector<unsigned> pcrs; for ( int i = 0; i < 24; i++ ) { pcrs.push_back(i); } /// Unseal Monce SecureMem<char> decrypted = TpmBackend().unseal(volume.getMonce(), dummy); /// Show Monce cout << decrypted.getPointer() << endl; /// Get Password SecureMem<char> password = CryptoBackend().getPassword("Enter password: "******"keyfile.vol"); file.del(volume.getName()); file.add(Volume(volume.getName(), volume.getDev(), volume.getKey(), volume.getTool(), encrypted)); }
SecureMem<unsigned char> CryptoBackend::decryptBlob(string toDecrypt, SecureMem<unsigned char> passphrase, string iv, string salt) { byte *decrypted = NULL; SecureMem<unsigned char> key; decrypted = (byte*)malloc(sizeof(byte)*toDecrypt.length()); key = keyDerivation(passphrase, reinterpret_cast<byte*> (const_cast<char*>(salt.c_str()))); CFB_Mode<AES>::Decryption cfbDecryption(key.getPointer(), key.getLen(), reinterpret_cast<byte*> (const_cast<char*>(iv.c_str()))); cfbDecryption.ProcessData(decrypted, reinterpret_cast<const byte*> (toDecrypt.c_str()), toDecrypt.length()); SecureMem<unsigned char> blob(decrypted, toDecrypt.length()); free(decrypted); return blob; }
CipherKey getNewUserKey(EncfsConfig &config, bool useStdin, const std::string &passProg, const std::string &rootDir) { CipherKey result; SecureMem *password; if (useStdin) password = passwordFromStdin(); else if (!passProg.empty()) password = passwordFromProgram(passProg, rootDir); else password = passwordFromPrompts(); if (password) { result = makeNewKey(config, (char *)password->data(), strlen((char *)password->data())); delete password; } return result; }
vector<string> CryptoBackend::initBlob(SecureMem<unsigned char> toEncrypt, SecureMem<unsigned char> passphrase) { byte *iv = NULL, *salt = NULL, *encrypted = NULL; vector<string> cryptoParams; SecureMem<unsigned char> key; encrypted = (byte*) malloc(sizeof(byte)*toEncrypt.getLen()); iv = generateIV(); salt = generateSalt(); key = keyDerivation(passphrase, salt); CFB_Mode<AES>::Encryption cfbEncryption(key.getPointer(), key.getLen(), iv); cfbEncryption.ProcessData(encrypted, toEncrypt.getPointer(), toEncrypt.getLen()); cryptoParams.push_back(string(const_cast<const char*> (reinterpret_cast<char*> (encrypted)))); cryptoParams.push_back(string(const_cast<const char*> (reinterpret_cast<char*> (iv)))); cryptoParams.push_back(string(const_cast<const char*> (reinterpret_cast<char*> (salt)))); free(encrypted); return cryptoParams; }
int main ( int argc, char** argv ) { CommandLine cmdParser; cmdParser.registerOptionClass<VolumeManagement>("help", 'h', CommandLine::NONE); cmdParser.registerOptionFunction(foo, "foo"); cmdParser.run(argc, argv); /* CryptSetup tool; KeyFile file("keyfile.vol"); vector<unsigned> pcrs; string pw = CryptoBackend().generateRandomString(64, false); string monce = CryptoBackend().generateRandomString(64, false); SecureMem<char> secpw(const_cast < char* > (pw.c_str()), pw.length()); SecureMem<char> secmonce(const_cast < char* > (monce.c_str()), monce.length()); SecureMem<char> dummy; for ( int i = 0; i < 24; i++ ) { pcrs.push_back(i); } SecureMem<char> password = CryptoBackend().getPassword("Enter password: "******"foo", "/dev/loop0", encrypted1, CryptSetup::TAG, encrypted2); file.add(vol); tool.createVolume("/dev/loop0", secpw, true, AES, CBC, SHA1, S256, RANDOM); AuthenticationProtocol foo(vol); */ SecureMem<char> foo = CryptoBackend().generateRandomString(64, false); cout << foo.getAsUnsecureString() << endl; //TpmStateMachine(); return 0; }
SecureMem *passwordFromStdin() { SecureMem *buf = new SecureMem(MaxPassBuf); char *res = fgets((char *)buf->data(), buf->size(), stdin); if (res) { // Kill the trailing newline. int last = strnlen((char *)buf->data(), buf->size()); if (last > 0 && buf->data()[last - 1] == '\n') buf->data()[last - 1] = '\0'; } return buf; }
SecureMem<unsigned char> CryptoBackend::keyDerivation(SecureMem<unsigned char> passphrase, byte *salt) { PKCS5_PBKDF2_HMAC<SHA256> pbkdf2; byte key[AES::DEFAULT_KEYLENGTH]; unsigned result = 0; result = pbkdf2.DeriveKey(key, AES::DEFAULT_KEYLENGTH, 0, passphrase.getPointer(), passphrase.getLen(), salt, DEFAULT_SALT_LEN, DEFAULT_ITERATIONS_LEN, 0); if (result < 0) { } return SecureMem<unsigned char>(key, AES::DEFAULT_KEYLENGTH); }
string CryptSetup::openVolume ( string dev, SecureMem<char> password ) { int ret = 1; list<string> args; list<SecureMem<char> > stdout; string stdin; try { if ( !this->isAvailable() ) { throw 1; } if ( !this->isTool(dev) ) { throw 1; } if ( access(dev.c_str(), F_OK) != 0 ) { throw 1; } if ( password.isEmpty() ) { throw 1; } args.push_back("luksOpen"); args.push_back(dev); args.push_back(genUniqueName(dev)); stdout.push_back(password); call(ToolIdentifier, args, stdout, stdin, &ret); if ( ret ) { throw 1; } } catch ( exception &e ) { } return genUniqueName(dev); }
SecureMem *passwordFromProgram(const std::string &passProg, const std::string &rootDir) { // have a child process run the command and get the result back to us. int fds[2], pid; int res; res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds); if(res == -1) { perror(_("Internal error: socketpair() failed")); return NULL; } VLOG(1) << "getUserKey: fds = " << fds[0] << ", " << fds[1]; pid = fork(); if(pid == -1) { perror(_("Internal error: fork() failed")); close(fds[0]); close(fds[1]); return NULL; } if(pid == 0) { const char *argv[4]; argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = passProg.c_str(); argv[3] = 0; // child process.. run the command and send output to fds[0] close(fds[1]); // we don't use the other half.. // make a copy of stdout and stderr descriptors, and set an environment // variable telling where to find them, in case a child wants it.. int stdOutCopy = dup( STDOUT_FILENO ); int stdErrCopy = dup( STDERR_FILENO ); // replace STDOUT with our socket, which we'll used to receive the // password.. dup2( fds[0], STDOUT_FILENO ); // ensure that STDOUT_FILENO and stdout/stderr are not closed on exec.. fcntl(STDOUT_FILENO, F_SETFD, 0); // don't close on exec.. fcntl(stdOutCopy, F_SETFD, 0); fcntl(stdErrCopy, F_SETFD, 0); char tmpBuf[8]; setenv(ENCFS_ENV_ROOTDIR, rootDir.c_str(), 1); snprintf(tmpBuf, sizeof(tmpBuf)-1, "%i", stdOutCopy); setenv(ENCFS_ENV_STDOUT, tmpBuf, 1); snprintf(tmpBuf, sizeof(tmpBuf)-1, "%i", stdErrCopy); setenv(ENCFS_ENV_STDERR, tmpBuf, 1); execvp( argv[0], (char * const *)argv ); // returns only on error.. perror(_("Internal error: failed to exec program")); exit(1); } close(fds[0]); string password = readPassword(fds[1]); close(fds[1]); waitpid(pid, NULL, 0); SecureMem *result = new SecureMem(password.length()+1); if (result) strncpy((char *)result->data(), password.c_str(), result->size()); password.assign(password.length(), '\0'); return result; }