learncrypto/source/actions.d
2016-02-14 11:00:28 +01:00

102 lines
2.1 KiB
D

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;
}