module actions; import std.stdio; import std.base64: Base64; import std.random : Random, uniform; import std.algorithm : joiner; import cipher; public: enum chunkSize = 4096; enum string randomDeviceName = "/dev/random"; void encrypt(string keyFileName, Cipher cipher, bool armor) { auto key = loadKey(keyFileName, armor); ubyte[8] nonce; if(armor) { ubyte[] buf; foreach(b; stdin.byChunk(chunkSize).joiner.cipherFunction(key, nonce, cipher)) { buf ~= [b]; if(buf.length == 57) { stdout.writeln(Base64.encode(buf)); buf = []; } } if(buf !is null) stdout.writeln(Base64.encode(buf)); } else { foreach(b; stdin.byChunk(chunkSize).joiner.cipherFunction(key, nonce, cipher)) stdout.rawWrite([b]); } } void decrypt(string keyFileName, Cipher cipher, bool armor) { auto key = loadKey(keyFileName, armor); ubyte[8] nonce; if(armor) { ubyte[] buf; foreach(b; Base64.decoder(stdin.byLine).joiner.cipherFunction(key, nonce, cipher)) { stdout.rawWrite([b]); } } else { foreach(b; stdin.byChunk(chunkSize).joiner.cipherFunction(key, nonce, cipher)) stdout.rawWrite([b]); } } void generateKey(bool armor) { auto rng = Random(); auto randomDevice = File(randomDeviceName, "r"); scope(exit) randomDevice.close(); uint[1] seed; randomDevice.rawRead(seed); rng.seed(seed[0]); ubyte[32] key; foreach (ref b; key) b = uniform!ubyte(rng); if(armor) { writeln(Base64.encode(key)); } else { stdout.rawWrite(key); } } private: ubyte[32] loadKey(string filename, bool armor) { auto keyFile = File(filename, "r"); ubyte[32] key; if(armor) { ubyte[] tempKey; foreach(line; keyFile.byLine) tempKey ~= Base64.decode(line); key = tempKey; } else { keyFile.rawRead(key); } return key; }