implemented commands

This commit is contained in:
Kevin Froman 2020-12-20 09:07:19 +00:00
parent 481567138f
commit 0d2fa7e380
3 changed files with 143 additions and 13 deletions

View File

@ -20,6 +20,15 @@ namespace rinseoff
return combined.ToArray(); return combined.ToArray();
} }
public static byte[] decrypt_secret_bytes(byte[] ciphertext, byte[] key){
var ciphertextList = new List<byte>();
ciphertextList.AddRange(ciphertext);
return Sodium.SecretBox.Open(
ciphertextList.GetRange(24, ciphertextList.Count - 24).ToArray(),
ciphertextList.GetRange(0, 24).ToArray(),
key);
}
} }
} }

View File

@ -1,21 +1,119 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
using System.Collections.Generic;
using rinseoff;
namespace rinseoffcli namespace rinseoffcli
{ {
class Program class Program
{ {
static void showHelp(int exitCode = 1){ static void showHelp(int exitCode = 1){
Console.WriteLine("Must specify store or load, then a file name followed by a key file.\nFormat: <verb> <data file> <key file>"); Console.WriteLine("Must specify keygen <key path> or store/load, then a file name followed by a key file.\nFormat: <verb> <data file> <key file>");
System.Environment.Exit(exitCode); Environment.Exit(exitCode);
} }
static void storeData(string filepath, string keypath){ static void validateArgCount(string[] args, int count){
Stream inputStream = Console.OpenStandardInput(); if (args.Length != count){
if (! File.Exists(keypath)){ stderrWrite("Invalid number of arguments");
Console.WriteLine("Key file " + keypath + " does not exist"); showHelp(2);
System.Environment.Exit(3);
} }
}
static void stderrWrite(string msg){
var stderrStream = Console.Error;
stderrStream.WriteLine(msg);
stderrStream.Flush();
}
static void loadData(string filepath, string keypath){
byte[] plaintext = {};
byte[] readBytes(string file){
byte[] bytesToRead = {};
try{
bytesToRead = File.ReadAllBytes(file);
}
catch(FileNotFoundException){
stderrWrite(file + " is not found");
Environment.Exit(9);
}
catch(UnauthorizedAccessException){
stderrWrite("No permssion to read " + file);
Environment.Exit(10);
}
catch(IOException){
stderrWrite("Failed to read " + file);
Environment.Exit(11);
}
return bytesToRead;
}
var stdout = Console.OpenStandardOutput();
try{
plaintext = RinseOff.decrypt_secret_bytes(
readBytes(filepath),
readBytes(keypath)
);
}
catch(Sodium.Exceptions.KeyOutOfRangeException){
stderrWrite("Keyfile is not appropriate size for key");
Environment.Exit(4);
}
catch(System.Security.Cryptography.CryptographicException){
stderrWrite("Could not decrypt " + filepath + " with " + keypath);
Environment.Exit(12);
}
foreach(byte b in plaintext){
stdout.WriteByte(b);
}
stdout.Flush();
}
static void storeData(string filepath, string keypath){
byte[] encryptedInput = new byte[0];
byte[] readUntilClose(){
// Read binary from STDIN until close
var readData = new List<byte>();
Stream inputStream = Console.OpenStandardInput();
int inp;
while(true){
inp = inputStream.ReadByte();
if (inp != -1){
readData.Add((byte) inp);
}
else{
return readData.ToArray();
}
}
}
// Encrypt stdin with keyfile data then write out to output file
try{
encryptedInput = RinseOff.encrypt_secret_bytes(readUntilClose(), File.ReadAllBytes(keypath));
}
catch(FileNotFoundException){
stderrWrite("Key file " + keypath + " does not exist");
Environment.Exit(3);
}
catch(Sodium.Exceptions.KeyOutOfRangeException){
stderrWrite("Keyfile is not appropriate size for key");
Environment.Exit(4);
}
catch(IOException){
stderrWrite("Failed to read key file " + keypath);
Environment.Exit(5);
}
try{
File.WriteAllBytes(filepath, encryptedInput);
}
catch(ArgumentNullException)
{
Environment.Exit(0);
}
catch(DirectoryNotFoundException){
stderrWrite("Output path " + filepath + " not found");
Environment.Exit(7);
}
catch(IOException){
stderrWrite("Could not write to " + filepath);
Environment.Exit(8);
}
} }
static void Main(string[] args) static void Main(string[] args)
{ {
@ -24,15 +122,34 @@ namespace rinseoffcli
} }
var cmd = args[0].ToLower(); var cmd = args[0].ToLower();
switch(cmd){ switch(cmd){
case "store": case "keygen":
if (args.Length != 3){ validateArgCount(args, 2);
Console.WriteLine("Invalid number of arguments"); try{
showHelp(2); RinseOff.generateKeyFile(args[1]);
} }
catch(UnauthorizedAccessException){
stderrWrite("Cannot write to key file due to lack of perms " + args[1]);
Environment.Exit(6);
}
catch(DirectoryNotFoundException){
stderrWrite("Path not found " + args[1]);
Environment.Exit(6);
}
catch(IOException){
stderrWrite("Path not found " + args[1]);
Environment.Exit(6);
}
break;
case "store":
validateArgCount(args, 3);
storeData(args[1], args[2]); storeData(args[1], args[2]);
break; break;
case "load":
validateArgCount(args, 3);
loadData(args[1], args[2]);
break;
default: default:
Console.WriteLine("Invalid command"); stderrWrite("Invalid command");
showHelp(); showHelp();
break; break;
case "help": case "help":

View File

@ -1,5 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\rinseoff\rinseoff.csproj" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>