work on keyring and CLI menu driven GUI

This commit is contained in:
Kevin Froman 2020-05-21 04:05:32 -05:00
parent 4aab4420a7
commit b5f8278903
9 changed files with 169 additions and 29 deletions

View File

@ -1,8 +1,9 @@
using System; using System;
using CommandLine; using CommandLine;
using treasurechest.STDIOWrapper; using treasurechest.STDIOWrapper;
using treasurechest;
namespace treasurechest namespace treasurechestCLI
{ {
class Program class Program
{ {
@ -17,15 +18,18 @@ namespace treasurechest
bool command = true; bool command = true;
if (opts.Version){ if (opts.Version){
STDIO.O(Version.NAME + " - " + Version.VERSION); STDIO.O(treasurechest.Version.NAME + " - " + treasurechest.Version.VERSION);
}
else if (opts.Menu){
new TreasureChestMenu().showMenu();
} }
else{ else{
command = false; command = false;
} }
if (! command){ if (! command){
STDIO.O(Version.NAME + " - " + Version.VERSION); STDIO.O(treasurechest.Version.NAME + " - " + treasurechest.Version.VERSION);
STDIO.O("Run with help for more options"); STDIO.O(new translations.Strings().HELP_TEXT);
} }
} }
@ -36,6 +40,8 @@ namespace treasurechest
public bool Interactive { get; set; } public bool Interactive { get; set; }
[Option('v', "version", Required = false, HelpText="Show current version")] [Option('v', "version", Required = false, HelpText="Show current version")]
public bool Version {get; set;} public bool Version {get; set;}
[Option('m', "menu", Required = false, HelpText="Interactive CLI menu")]
public bool Menu {get;set;}
} }
} }

60
cli/Menu.cs Normal file
View File

@ -0,0 +1,60 @@
using System;
using CommandLine;
using treasurechest.STDIOWrapper;
using treasurechest;
namespace treasurechestCLI
{
internal class TreasureChestMenu{
private string language;
public TreasureChestMenu(){
language = translations.GetLanguage.language;
}
internal void showMenu(){
translations.Strings strings = new translations.Strings();
string[] mainMenuOptions = {strings.MAIN_MENU_ENCRYPT, strings.MAIN_MENU_DECRYPT, strings.EXIT};
STDIO.O(strings.WELCOME);
int counter = 1;
int choice = 0;
int mainMenuOptionsSize = mainMenuOptions.Length;
while (choice != mainMenuOptions.Length){
foreach (string option in mainMenuOptions){
STDIO.O(counter.ToString() + ". " + option);
counter += 1;
}
try{
choice = Int32.Parse(System.Console.ReadLine());
}
catch (System.OverflowException){
// User being silly with input
STDIO.O(strings.MAIN_MENU_SELECT_INTEGER);
counter = 1;
}
catch(System.FormatException){
// Too lazy to check strings, force them to use int from menu which is faster anyway
STDIO.O(strings.MAIN_MENU_SELECT_INTEGER);
counter = 1;
}
catch(System.ArgumentNullException){
// Can happen when stream closes (e.g. ctrl-d)
// since menu is intended to be directly human interfaced, user probably wants to exit
choice = mainMenuOptionsSize;
}
if (choice == mainMenuOptionsSize){
break;
}
else{
STDIO.O(strings.INVALID_OPTION);
}
counter = 1;
}
}
}
}

50
cli/translations/text.cs Normal file
View File

@ -0,0 +1,50 @@
using System.Globalization;
using treasurechest;
namespace treasurechestCLI {
namespace translations {
internal class GetLanguage{
internal static string language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
}
public class Strings{
public string WELCOME;
public string HELP_TEXT;
public string EXIT;
public string MAIN_MENU_ENCRYPT;
public string MAIN_MENU_DECRYPT;
public string INVALID_OPTION;
public string MAIN_MENU_SELECT_INTEGER;
public Strings(){
switch (GetLanguage.language){
case "es":
WELCOME = treasurechest.Version.NAME + " - Protege tu valiosa información";
HELP_TEXT = "Ejecuta help para más opciones";
EXIT = "Salida";
MAIN_MENU_ENCRYPT = "Encriptar";
MAIN_MENU_DECRYPT = "Desencriptar";
INVALID_OPTION = "Opción inválida";
MAIN_MENU_SELECT_INTEGER = "Ingrese un número entero desde el menú";
break;
case "en":
default:
WELCOME = treasurechest.Version.NAME + " - Protect your treasured information";
HELP_TEXT = "Run with help for more options";
EXIT = "Exit";
MAIN_MENU_ENCRYPT = "Encrypt";
MAIN_MENU_DECRYPT = "Decrypt";
INVALID_OPTION = "Invalid option";
MAIN_MENU_SELECT_INTEGER = "Enter an integer from the menu";
break;
}
}
}
}
}

View File

@ -12,6 +12,23 @@ namespace DoubleKeyPrivateTests
{ {
} }
[Test]
public void TestDoublePrivateKeyGetters()
{
byte[] signingKey = PublicKeyAuth.GenerateKeyPair().PrivateKey;
byte[] encryptionKey = PublicKeyBox.GenerateKeyPair().PrivateKey;
byte[] combinedKey = new byte[signingKey.Length + encryptionKey.Length];
Buffer.BlockCopy(signingKey, 0, combinedKey, 0, signingKey.Length);
Buffer.BlockCopy(encryptionKey, 0, combinedKey, signingKey.Length, encryptionKey.Length);
DoublePrivateKey combinedLoad = new chestcrypto.DoublePrivateKey(combinedKey);
Assert.AreEqual(combinedLoad.getEd25519PrivateKey(), signingKey);
Assert.AreEqual(combinedLoad.getCurve25519PrivateKey(), encryptionKey);
}
[Test] [Test]
public void TestDoublePrivateKeyThrowsOnBadLoad() public void TestDoublePrivateKeyThrowsOnBadLoad()
{ {

View File

@ -7,7 +7,7 @@ using keyring;
using chestcrypto; using chestcrypto;
using chestcrypto.exceptions; using chestcrypto.exceptions;
namespace KeyRingTests namespace KeyRingDeletePublicTests
{ {
public class Tests public class Tests
{ {

View File

@ -9,10 +9,6 @@ namespace chestcrypto{
private bool isPrivate; private bool isPrivate;
private Identity identity; private Identity identity;
public EphemeralKey(Identity user){
identity = user;
}
public EphemeralKey(Identity identity, byte[] key, int secondsToExpire){ public EphemeralKey(Identity identity, byte[] key, int secondsToExpire){
} }

View File

@ -6,10 +6,12 @@ namespace chestcrypto{
internal class Identity { internal class Identity {
private DoublePrivateKey privateKey; private DoublePrivateKey privateKey;
private DoublePublicKey publicKey; private DoublePublicKey publicKey;
private bool hasPrivate = false;
private List<EphemeralKey> ephemeralKeys = new List<EphemeralKey>(); private List<EphemeralKey> ephemeralKeys = new List<EphemeralKey>();
public DoublePublicKey getDoublePublicKey(){return publicKey;} public DoublePublicKey getDoublePublicKey(){return publicKey;}
public DoublePrivateKey getDoublePrivateKey(){return privateKey;}
public Identity(){} public Identity(){}
@ -20,7 +22,7 @@ namespace chestcrypto{
this.publicKey = publicKey; this.publicKey = publicKey;
} }
public Identity(DoublePrivateKey privateKey){ public Identity(DoublePrivateKey privateKey){
this.privateKey = privateKey;
} }
public Identity(DoublePrivateKey privateKey, List<EphemeralKey> ephemeralKeys){ public Identity(DoublePrivateKey privateKey, List<EphemeralKey> ephemeralKeys){

View File

@ -1,3 +1,5 @@
using Sodium;
namespace chestcrypto{ namespace chestcrypto{
public class DoublePrivateKey{ public class DoublePrivateKey{
@ -8,10 +10,23 @@ namespace chestcrypto{
private string signingPrivateKeyString; private string signingPrivateKeyString;
private string encryptPrivateKeyString; private string encryptPrivateKeyString;
// Test DoubleKeyPrivateTests.Tests.TestDoublePrivateKeyGetters
public byte[] getCurve25519PrivateKey(){return encryptPrivateKey;}
// Test DoubleKeyPrivateTests.Tests.TestDoublePrivateKeyGetters
public byte[] getEd25519PrivateKey(){return signingPrivateKey;}
public byte[] getCurve25519PublicKey(){
return PublicKeyBox.GenerateKeyPair(getCurve25519PrivateKey()).PublicKey;
}
public byte[] getEd25519PublicKey(){
return PublicKeyAuth.GenerateKeyPair(getEd25519PrivateKey()).PublicKey;
}
// Test DoubleKeyPrivateTests.TestDoubleKeyLoad
public byte[] getRawDouble(){ public byte[] getRawDouble(){
return ByteCombiner.Combine(signingPrivateKey, encryptPrivateKey); return ByteCombiner.Combine(signingPrivateKey, encryptPrivateKey);
} }
// Test DoubleKeyPrivateTests.TestDoubleKeyLoad
public DoublePrivateKey(byte[] sign, byte[] encrypt){ public DoublePrivateKey(byte[] sign, byte[] encrypt){
if (sign.Length != 64){ if (sign.Length != 64){
throw new exceptions.InvalidDoubleKeyException("Signing private key must be 64 bytes in length."); throw new exceptions.InvalidDoubleKeyException("Signing private key must be 64 bytes in length.");
@ -22,7 +37,7 @@ namespace chestcrypto{
signingPrivateKey = sign; signingPrivateKey = sign;
encryptPrivateKey = encrypt; encryptPrivateKey = encrypt;
} }
// Test DoubleKeyPrivateTests.TestDoubleKeyLoad
public DoublePrivateKey(byte[] combinedKey){ public DoublePrivateKey(byte[] combinedKey){
if (combinedKey.Length != 96){ if (combinedKey.Length != 96){
throw new exceptions.InvalidDoubleKeyException("Invalid key length, must be 96 bytes in length"); throw new exceptions.InvalidDoubleKeyException("Invalid key length, must be 96 bytes in length");

View File

@ -22,19 +22,13 @@ namespace keyring{
return success; return success;
} }
private int getIdentityListPosition(Identity iden){ internal void removeIdentity(Identity iden){identities.Remove(iden);}
int counter = 0;
bool success = false; internal Identity getIdentityInstance(DoublePublicKey key){
identities.ForEach(delegate(Identity ident) foreach (Identity iden in identities){
{ if (iden.getDoublePublicKey().Equals(key)){
if (ident.getDoublePublicKey().Equals(iden.getDoublePublicKey())){ return iden;
success = true;
return;
} }
counter += 1;
});
if (success){
return counter;
} }
throw new NoIdentityException(); throw new NoIdentityException();
} }
@ -46,9 +40,6 @@ namespace keyring{
public int getIdentityCount(){return identities.Count;} public int getIdentityCount(){return identities.Count;}
public int getIdentityInstance(DoublePublicKey){
}
public List<byte[]> getIdentityPublicKeys(){ public List<byte[]> getIdentityPublicKeys(){
List<byte[]> pubKeys = new List<byte[]>(); List<byte[]> pubKeys = new List<byte[]>();
@ -61,7 +52,6 @@ namespace keyring{
public void addPublicKey(DoublePublicKey key){ public void addPublicKey(DoublePublicKey key){
// Create an Identity with a public key if it does not exist already // Create an Identity with a public key if it does not exist already
Identity newIdentity = new Identity(key); Identity newIdentity = new Identity(key);
if (identityExists(newIdentity)){ if (identityExists(newIdentity)){
throw new DuplicateIdentityException("An identity with that public key already exists"); throw new DuplicateIdentityException("An identity with that public key already exists");
@ -71,8 +61,12 @@ namespace keyring{
} }
public void addPrivateKey(){
}
public void removeIdentityByPubkey(DoublePublicKey key){ public void removeIdentityByPubkey(DoublePublicKey key){
removeIdentity(getIdentityInstance(key));
} }
} }