diff --git a/tests/session/testSession.cs b/tests/session/testSession.cs index c885e4c..99517ed 100644 --- a/tests/session/testSession.cs +++ b/tests/session/testSession.cs @@ -28,6 +28,35 @@ namespace sessionTests Assert.IsTrue(Enumerable.SequenceEqual(newK, session.getLatestPublicKey())); } + [Test] + public void TestSessionNoPublicDupes(){ + byte[] publicK = PublicKeyBox.GenerateKeyPair().PublicKey; + byte[] privateK = PublicKeyBox.GenerateKeyPair().PrivateKey; + byte[] newK = PublicKeyBox.GenerateKeyPair().PublicKey; + Session session = new Session(privateK, publicK, true); + session.addPublic(newK, getFutureTime(61)); + try{ + session.addPublic(newK, getFutureTime(61)); + } + catch(DuplicatePublicKey){return;} + Assert.Fail(); + } + + [Test] + public void TestSessionAddPublicInvalidKey(){ + byte[] publicK = PublicKeyBox.GenerateKeyPair().PublicKey; + byte[] privateK = PublicKeyBox.GenerateKeyPair().PrivateKey; + byte[] newK = {3, 5}; + Session session = new Session(privateK, publicK, true); + try{ + session.addPublic(newK, getFutureTime(61)); + } + catch(InvalidKeyLength){ + return; + } + Assert.Fail(); + } + [Test] public void TestSessionAddPublicInvalidTime(){ byte[] publicK = PublicKeyBox.GenerateKeyPair().PublicKey; diff --git a/treasurechest/chestcrypto/session/exceptions.cs b/treasurechest/chestcrypto/session/exceptions.cs new file mode 100644 index 0000000..1016897 --- /dev/null +++ b/treasurechest/chestcrypto/session/exceptions.cs @@ -0,0 +1,23 @@ +using System; +namespace chestcrypto{ + + namespace exceptions{ + public class DuplicatePublicKey : Exception + { + public DuplicatePublicKey() + { + } + + public DuplicatePublicKey(string message) + : base(message) + { + } + + public DuplicatePublicKey(string message, Exception inner) + : base(message, inner) + { + } + } + } + +} \ No newline at end of file diff --git a/treasurechest/chestcrypto/session/session.cs b/treasurechest/chestcrypto/session/session.cs index 607a76a..1587d10 100644 --- a/treasurechest/chestcrypto/session/session.cs +++ b/treasurechest/chestcrypto/session/session.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System; using chestcrypto.exceptions; @@ -18,8 +19,24 @@ namespace chestcrypto{ private bool strictMode; private const int minimumKeyExpireSeconds = 60; + private void validateKey(byte[] key){ + if (key.Length != 32){ + throw new InvalidKeyLength(); + } + } + + private bool publicKeyExists(byte[] key){ + foreach( (int, byte[]) k in theirPublicKeys){ + if (Enumerable.SequenceEqual(k.Item2, key)){ + return true; + } + } + return false; + } + public Session(byte[] masterPrivate, byte[] masterPublic, bool strictMode){ - if(masterPrivate.Length != 32 | masterPublic.Length != 32){throw new InvalidKeyLength();} + validateKey(masterPrivate); + validateKey(masterPublic); ourMasterPrivateKey = masterPrivate; theirMasterPublicKey = masterPublic; this.strictMode = strictMode; @@ -29,6 +46,8 @@ namespace chestcrypto{ } public void addPublic(byte[] publicKey, long timestamp){ + validateKey(publicKey); + if (publicKeyExists(publicKey)){throw new DuplicatePublicKey();} if (timestamp < DateTimeOffset.UtcNow.ToUnixTimeSeconds() + minimumKeyExpireSeconds){ throw new ArgumentOutOfRangeException(); }