changed simplepack to an external library

This commit is contained in:
Kevin Froman 2020-05-28 17:14:45 -05:00
parent 27db4aec17
commit d904d0fb87
No known key found for this signature in database
GPG Key ID: BF1CE85F428B8CE3
19 changed files with 151 additions and 410 deletions

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.8.0" /> <PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="NicewareSecure" Version="0.0.1" /> <PackageReference Include="NicewareSecure" Version="0.0.1" />
<PackageReference Include="SimplePack-base58" Version="1.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -11,12 +11,13 @@ namespace treasurechestCLI {
stringInst.EXIT = "Salir de la aplicación"; stringInst.EXIT = "Salir de la aplicación";
stringInst.MAIN_MENU_ENCRYPT = "Encriptar"; stringInst.MAIN_MENU_ENCRYPT = "Encriptar";
stringInst.MAIN_MENU_DECRYPT = "Desencriptar"; stringInst.MAIN_MENU_DECRYPT = "Desencriptar";
stringInst.MAIN_MENU_KEYRING = "Gestionar contactos";
stringInst.INVALID_OPTION = "Opción inválida"; stringInst.INVALID_OPTION = "Opción inválida";
stringInst.MAIN_MENU_SELECT_INTEGER = "Ingrese un número entero desde el menú"; stringInst.MAIN_MENU_SELECT_INTEGER = "Ingrese un número entero desde el menú";
stringInst.RETURN_TO_PREVIOUS_MENU = "Menú anterior"; stringInst.RETURN_TO_PREVIOUS_MENU = "Menú anterior";
stringInst.ENCRYPT_MENU_ENCRYPT_MESSAGE = "Cifrar texto"; stringInst.ENCRYPT_MENU_ENCRYPT_MESSAGE = "Cifrar texto";
stringInst.ENCRYPT_MENU_ENCRYPT_FILE = "Cifrar archivo"; stringInst.ENCRYPT_MENU_ENCRYPT_FILE = "Cifrar archivo";
stringInst.ENCRYPT_MENU_USE_PASSPHRASE = "Usar frase de contraseña"; stringInst.ENCRYPT_MENU_USE_PASSPHRASE = "Use mnemotécnico";
stringInst.ENCRYPT_MENU_USE_PUBKEY = "Usar clave pública"; stringInst.ENCRYPT_MENU_USE_PUBKEY = "Usar clave pública";
stringInst.ENTER_MESSAGE_UNTIL_DONE = "Ingrese su mensaje y termine con -q en una nueva línea."; stringInst.ENTER_MESSAGE_UNTIL_DONE = "Ingrese su mensaje y termine con -q en una nueva línea.";
stringInst.PASSPHRASE = "Frase de contraseña"; stringInst.PASSPHRASE = "Frase de contraseña";

View File

@ -13,6 +13,7 @@ namespace treasurechestCLI {
public string EXIT; public string EXIT;
public string MAIN_MENU_ENCRYPT; public string MAIN_MENU_ENCRYPT;
public string MAIN_MENU_DECRYPT; public string MAIN_MENU_DECRYPT;
public string MAIN_MENU_KEYRING;
public string INVALID_OPTION; public string INVALID_OPTION;
public string MAIN_MENU_SELECT_INTEGER; public string MAIN_MENU_SELECT_INTEGER;
public string RETURN_TO_PREVIOUS_MENU; public string RETURN_TO_PREVIOUS_MENU;
@ -37,12 +38,13 @@ namespace treasurechestCLI {
EXIT = "Exit application"; EXIT = "Exit application";
MAIN_MENU_ENCRYPT = "Encrypt"; MAIN_MENU_ENCRYPT = "Encrypt";
MAIN_MENU_DECRYPT = "Decrypt"; MAIN_MENU_DECRYPT = "Decrypt";
MAIN_MENU_KEYRING = "Manage contacts";
INVALID_OPTION = "Invalid option"; INVALID_OPTION = "Invalid option";
MAIN_MENU_SELECT_INTEGER = "Enter an integer from the menu"; MAIN_MENU_SELECT_INTEGER = "Enter an integer from the menu";
RETURN_TO_PREVIOUS_MENU = "Previous menu"; RETURN_TO_PREVIOUS_MENU = "Previous menu";
ENCRYPT_MENU_ENCRYPT_MESSAGE = "Encrypt text"; ENCRYPT_MENU_ENCRYPT_MESSAGE = "Encrypt text";
ENCRYPT_MENU_ENCRYPT_FILE = "Encrypt file"; ENCRYPT_MENU_ENCRYPT_FILE = "Encrypt file";
ENCRYPT_MENU_USE_PASSPHRASE = "Use passphrase"; ENCRYPT_MENU_USE_PASSPHRASE = "Use mnemonic";
ENCRYPT_MENU_USE_PUBKEY = "Use public key"; ENCRYPT_MENU_USE_PUBKEY = "Use public key";
ENTER_MESSAGE_UNTIL_DONE = "Enter your message and finish with -q on a new line."; ENTER_MESSAGE_UNTIL_DONE = "Enter your message and finish with -q on a new line.";
PASSPHRASE = "Passphrase"; PASSPHRASE = "Passphrase";

View File

@ -4,7 +4,7 @@ using System.Text;
using Sodium; using Sodium;
using niceware; using niceware;
using chestcrypto.simplepack; using simplepack;
using chestcrypto.symmetric; using chestcrypto.symmetric;
using treasurechest.STDIOWrapper; using treasurechest.STDIOWrapper;
@ -12,12 +12,30 @@ using treasurechest.STDIOWrapper;
namespace treasurechestCLI{ namespace treasurechestCLI{
internal class EncryptMessageInterface{ internal class EncryptMessageInterface{
private static void EncryptWithMnemonic(){
byte[] key = new byte[32]; // Key has to be 32 bytes in size
byte[] message; // Plaintext
string encrypted; // Ciphertext will be encoded with SimplePack.
try {
message = UTF8Encoding.UTF8.GetBytes(GetMessage.getTypedMessage());
}
catch(System.NullReferenceException){
return;
}
SimplePack packer = new SimplePack("treasure chest-message ", " end treasure chest message.");
key = SecretBox.GenerateKey();
encrypted = packer.encode(Symmetric.encrypt(message, key));
STDIO.O(encrypted);
foreach (string word in Niceware.ToPassphrase(key)){
Console.Write(word + " ");
}
STDIO.O("");
}
public static void EncryptMessage(){ public static void EncryptMessage(){
int choice = 0; int choice = 0;
int counter = 1; int counter = 1;
byte[] key = new byte[32];
byte[] message;
string encrypted;
translations.Strings strings = new translations.Strings(); translations.Strings strings = new translations.Strings();
@ -52,23 +70,12 @@ namespace treasurechestCLI{
choice = encryptMenuOptions.Length; choice = encryptMenuOptions.Length;
} }
if (choice == 1){ if (choice == 1){
try { EncryptWithMnemonic();
message = UTF8Encoding.UTF8.GetBytes(GetMessage.getTypedMessage()); }
} else if (choice == 2){
catch(System.NullReferenceException){
continue;
}
key = SecretBox.GenerateKey();
encrypted = SimplePack.pack(Symmetric.encrypt(message, key));
STDIO.O(encrypted);
foreach (string word in Niceware.ToPassphrase(key)){
Console.Write(word + " ");
}
STDIO.O("");
} }
else if (choice == encryptMenuOptions.Length){ else if (choice == 3){
break; break;
} }

View File

@ -0,0 +1,5 @@
namespace treasurechestCLI{
}

View File

View File

@ -15,7 +15,7 @@ namespace treasurechestCLI
internal void showMenu(){ internal void showMenu(){
translations.Strings strings = new translations.Strings(); translations.Strings strings = new translations.Strings();
string[] mainMenuOptions = {strings.MAIN_MENU_ENCRYPT, strings.MAIN_MENU_DECRYPT, strings.EXIT}; string[] mainMenuOptions = {strings.MAIN_MENU_ENCRYPT, strings.MAIN_MENU_DECRYPT, strings.MAIN_MENU_KEYRING, strings.EXIT};
STDIO.O(strings.WELCOME); STDIO.O(strings.WELCOME);
int counter = 1; int counter = 1;
int choice = 0; int choice = 0;

View File

@ -0,0 +1,63 @@
using NUnit.Framework;
using chestcrypto.identity;
using chestcrypto;
using System;
using System.Linq;
using Sodium;
namespace PrivateIndentityTest
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void TestPrivateIdentityGetDoublePrivateKey(){
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);
PrivateIdentity iden = new PrivateIdentity(combinedLoad, "Picard");
Assert.IsTrue(Enumerable.SequenceEqual(iden.getPrivateKey().getRawDouble(), combinedLoad.getRawDouble()));
}
[Test]
public void TestPrivateIdentityConstructor()
{
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);
PrivateIdentity iden = new PrivateIdentity(combinedLoad, "Picard");
Assert.AreEqual(iden.getName(), "Picard");
Assert.AreEqual(iden.getNote(), "");
PrivateIdentity iden2 = new PrivateIdentity(combinedLoad, "Picard2", "test");
Assert.AreEqual(iden2.getName(), "Picard2");
Assert.AreEqual(iden2.getNote(), "test");
}
[Test]
public void TestPrivateIdenToPublic()
{
}
}
}

View File

@ -1,83 +0,0 @@
using NUnit.Framework;
using System;
using System.IO;
using Sodium;
using System.Collections.Generic;
using keyring;
using chestcrypto;
using chestcrypto.exceptions;
namespace KeyRingTests
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void TestKeyRingStoreNoDupe(){
string tempFile = Path.GetTempFileName();
DoublePublicKey getKey(){
KeyRing keyRing = new KeyRing();
byte[] signingKey = PublicKeyAuth.GenerateKeyPair().PublicKey;
byte[] encryptionKey = PublicKeyBox.GenerateKeyPair().PublicKey;
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);
DoublePublicKey combo = new DoublePublicKey(signingKey, encryptionKey);
return combo;
}
DoublePublicKey combo = getKey();
KeyRing keyRing = new KeyRing();
keyRing.addPublicKey(combo);
try{
keyRing.addPublicKey(combo);
Assert.Fail();
}
catch(DuplicateIdentityException){
}
List<byte[]> storedKeys = keyRing.getIdentityPublicKeys();
if (storedKeys.Count != 1){
Assert.Fail();
}
}
[Test]
public void TestKeyRingStore()
{
string tempFile = Path.GetTempFileName();
KeyRing keyRing = new KeyRing();
byte[] signingKey = PublicKeyAuth.GenerateKeyPair().PublicKey;
byte[] encryptionKey = PublicKeyBox.GenerateKeyPair().PublicKey;
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);
DoublePublicKey combo = new DoublePublicKey(signingKey, encryptionKey);
keyRing.addPublicKey(combo);
List<byte[]> storedKeys = keyRing.getIdentityPublicKeys();
bool success = false;
storedKeys.ForEach(delegate(byte[] key)
{
for (int x = 0; x < combinedKey.Length; x++){
if (combinedKey[x] == key[x]){
success = true;
continue;
}
success = false;
}
});
if (! success){
Assert.Fail();
}
}
}
}

View File

@ -1,45 +0,0 @@
using NUnit.Framework;
using System;
using System.IO;
using Sodium;
using System.Collections.Generic;
using keyring;
using chestcrypto;
using chestcrypto.exceptions;
namespace KeyRingDeletePublicTests
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void TestDeleteIdentityByPublicKey(){
string tempFile = Path.GetTempFileName();
DoublePublicKey getKey(){
KeyRing keyRing = new KeyRing();
byte[] signingKey = PublicKeyAuth.GenerateKeyPair().PublicKey;
byte[] encryptionKey = PublicKeyBox.GenerateKeyPair().PublicKey;
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);
DoublePublicKey combo = new DoublePublicKey(signingKey, encryptionKey);
return combo;
}
DoublePublicKey combo = getKey();
KeyRing keyRing = new KeyRing();
keyRing.addPublicKey(combo);
Assert.IsTrue(keyRing.getIdentityCount() == 1);
keyRing.removeIdentityByPubkey(combo);
Assert.IsTrue(keyRing.getIdentityCount() == 0);
}
}
}

View File

@ -1,49 +0,0 @@
using NUnit.Framework;
using chestcrypto;
using System;
namespace simplepackTests
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void TestPackUnpackString()
{
string message = "hello world";
string packed;
packed = chestcrypto.simplepack.SimplePack.pack(message);
Assert.AreEqual(message, chestcrypto.simplepack.SimplePack.unpack(packed));
}
[Test]
public void TestPackUnpackBytes()
{
byte[] message = System.Text.Encoding.UTF8.GetBytes("hello world");
string packed;
packed = chestcrypto.simplepack.SimplePack.pack(message);
Assert.AreEqual(message, chestcrypto.simplepack.SimplePack.unpack(packed));
}
[Test]
public void TestPackUnpackInvalid(){
byte[] message = System.Text.Encoding.UTF8.GetBytes("hello world");
string packed;
packed = chestcrypto.simplepack.SimplePack.pack(message).Remove(1);
bool success = false;
try{
chestcrypto.simplepack.SimplePack.unpack(packed);
}
catch(chestcrypto.exceptions.InvalidSimplePackMessage){
success = true;
}
if (! success){
Assert.Fail();
}
}
}
}

View File

@ -1,20 +0,0 @@
namespace chestcrypto{
namespace identity{
internal class EphemeralKey{
private int epochTime;
private int secondsToExpire;
private byte[] key = new byte[32];
private bool isPrivate;
private Identity identity;
public EphemeralKey(Identity identity, byte[] key, int secondsToExpire){
}
}
}
}

View File

@ -1,23 +0,0 @@
using System;
namespace chestcrypto{
namespace exceptions{
public class NoIdentityException : Exception
{
public NoIdentityException()
{
}
public NoIdentityException(string message)
: base(message)
{
}
public NoIdentityException(string message, Exception inner)
: base(message, inner)
{
}
}
}
}

View File

@ -1,38 +0,0 @@
using System.Collections.Generic;
namespace chestcrypto{
namespace identity {
internal class Identity {
private DoublePrivateKey privateKey;
private DoublePublicKey publicKey;
private bool hasPrivate = false;
private List<EphemeralKey> ephemeralKeys = new List<EphemeralKey>();
public DoublePublicKey getDoublePublicKey(){return publicKey;}
public DoublePrivateKey getDoublePrivateKey(){return privateKey;}
public Identity(){}
public Identity (List<EphemeralKey> ephemeralKeys){
}
public Identity(DoublePublicKey publicKey){
this.publicKey = publicKey;
}
public Identity(DoublePrivateKey privateKey){
this.privateKey = privateKey;
}
public Identity(DoublePrivateKey privateKey, List<EphemeralKey> ephemeralKeys){
}
public Identity(DoublePublicKey publicKey, List<EphemeralKey> ephemeralKeys){
}
}
}
}

View File

@ -0,0 +1,34 @@
using chestcrypto;
namespace chestcrypto.identity
{
public class PrivateIdentity{
/*
PrivateIdentity is a wrapper around a DoublePrivateKey providing associated metadata such as alias and note
*/
private DoublePrivateKey key;
private string name;
private string comment; // human's note
public PrivateIdentity(DoublePrivateKey doublePrivateKey, string alias){
key = doublePrivateKey;
name = alias;
comment = "";
}
public PrivateIdentity(DoublePrivateKey doublePrivateKey, string alias, string note){
key = doublePrivateKey;
name = alias;
comment = note;
}
public DoublePrivateKey getPrivateKey(){return key;}
public string getName(){return name;}
public string getNote(){return comment;}
}
}

View File

@ -1,72 +1,18 @@
using chestcrypto; using chestcrypto;
using chestcrypto.identity;
using chestcrypto.exceptions; using chestcrypto.exceptions;
using chestcrypto.identity;
using System.Collections.Generic; using System.Collections.Generic;
namespace keyring{ namespace keyring{
public class KeyRing public class KeyRing
{ {
private string storageFile = null; private List<PublicIdentity> publicIdentities;
private List<Identity> identities = new List<Identity>(); private List<PrivateIdentity> privateIdentities;
private bool identityExists(Identity iden){ public KeyRing(){
bool success = false; //publicIdentities = new List<PublicIdentity>();
identities.ForEach(delegate(Identity ident) privateIdentities = new List<PrivateIdentity>();
{
if (ident.getDoublePublicKey().Equals(iden.getDoublePublicKey())){
success = true;
return;
}
});
return success;
}
internal void removeIdentity(Identity iden){identities.Remove(iden);}
internal Identity getIdentityInstance(DoublePublicKey key){
foreach (Identity iden in identities){
if (iden.getDoublePublicKey().Equals(key)){
return iden;
}
}
throw new NoIdentityException();
}
public KeyRing(string storageFile){
}
public KeyRing(){}
public int getIdentityCount(){return identities.Count;}
public List<byte[]> getIdentityPublicKeys(){
List<byte[]> pubKeys = new List<byte[]>();
identities.ForEach(delegate(Identity identity){
pubKeys.Add(identity.getDoublePublicKey().getRawDouble());
});
return pubKeys;
}
public void addPublicKey(DoublePublicKey key){
// Create an Identity with a public key if it does not exist already
Identity newIdentity = new Identity(key);
if (identityExists(newIdentity)){
throw new DuplicateIdentityException("An identity with that public key already exists");
}
identities.Add(newIdentity);
}
public void addPrivateKey(){
}
public void removeIdentityByPubkey(DoublePublicKey key){
removeIdentity(getIdentityInstance(key));
} }
} }

View File

@ -1,23 +0,0 @@
using System;
namespace chestcrypto{
namespace exceptions{
public class InvalidSimplePackMessage : Exception
{
public InvalidSimplePackMessage()
{
}
public InvalidSimplePackMessage(string message)
: base(message)
{
}
public InvalidSimplePackMessage(string message, Exception inner)
: base(message, inner)
{
}
}
}
}

View File

@ -1,37 +0,0 @@
using Base58Check;
namespace chestcrypto{
namespace simplepack{
public class SimplePack{
private const string header = "CHEST-MESSAGE ";
private const string footer = " END-CHEST-MESSAGE.";
// Test simplepackTest.TestPackUnpackBytes
public static string pack(byte[] data){
return header + Base58CheckEncoding.Encode(data) + footer;
}
// Test simplepackTest.TestPackUnpackString
public static string pack(string data){
return pack(System.Text.Encoding.UTF8.GetBytes(data));
}
// Test simplepackTest.TestPackUnpackBytes
public static byte[] unpack(string checkedBase58String){
if (! checkedBase58String.Contains(header) | ! checkedBase58String.Contains(footer)){
throw new exceptions.InvalidSimplePackMessage("Message does not have valid header and footer");
}
string encodedMessage = "";
for (int i = header.Length; i < checkedBase58String.Length - footer.Length; i++){
encodedMessage += checkedBase58String[i];
}
return Base58CheckEncoding.Decode(encodedMessage);
}
}
}
}

View File

@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Base58Check" Version="0.2.0" />
<PackageReference Include="MessagePack" Version="2.1.115" /> <PackageReference Include="MessagePack" Version="2.1.115" />
<PackageReference Include="SimpleBase" Version="3.0.1" />
<PackageReference Include="Sodium.Core" Version="1.2.3" /> <PackageReference Include="Sodium.Core" Version="1.2.3" />
</ItemGroup> </ItemGroup>