Billy Barrow hace 2 años
padre
commit
bd90b2da0a

+ 70 - 70
src/lib/IdentityRiddle.vala

@@ -1,82 +1,82 @@
-namespace Riddle {
+//  namespace Riddle {
 
-    public class IdentityRiddle : Riddle {
+//      public class IdentityRiddle : Riddle {
 
 
-        private uint8[]? private_key { get; set; }
-        private uint8[] public_key { get; set; }
+//          private uint8[]? private_key { get; set; }
+//          private uint8[] public_key { get; set; }
 
-        public IdentityRiddle.from_identity(string identiy) {
-            var parts = identiy.split(":", 2);
-            public_key = Base64.decode (parts[0]);
-            private_key = Base64.decode (parts[1]);
-        }
+//          public IdentityRiddle.from_identity(string identiy) {
+//              var parts = identiy.split(":", 2);
+//              public_key = Base64.decode (parts[0]);
+//              private_key = Base64.decode (parts[1]);
+//          }
 
-        public IdentityRiddle(string public_key) {
-            this.public_key = Base64.decode (public_key);
-        }
+//          public IdentityRiddle(string public_key) {
+//              this.public_key = Base64.decode (public_key);
+//          }
 
-        public static string generate_identity() {
-            var pk = new uint8[Sodium.Asymmetric.Signing.PUBLIC_KEY_BYTES];
-            var sk = new uint8[Sodium.Asymmetric.Signing.SECRET_KEY_BYTES];
-            Sodium.Asymmetric.Signing.generate_keypair (pk, sk);
+//          public static string generate_identity() {
+//              var pk = new uint8[Sodium.Asymmetric.Signing.PUBLIC_KEY_BYTES];
+//              var sk = new uint8[Sodium.Asymmetric.Signing.SECRET_KEY_BYTES];
+//              Sodium.Asymmetric.Signing.generate_keypair (pk, sk);
             
-            var pk_enc = Base64.encode (pk);
-            var sk_enc = Base64.encode (sk);
-
-            return @"$pk_enc:$sk_enc";
-        }
-
-        public static string get_public_key_from_identity(string identity) {
-            var parts = identity.split(":", 2);
-            return parts[0];
-        }
-
-        public override Challenge create_challenge () {
-            var salt = new uint8[5120];
-            Sodium.Random.random_bytes(salt);
-
-            var challenge = new Challenge();
-            challenge.identifier = "riddle-identity-" + Base64.encode (public_key);
-            challenge.data = salt;
-            return challenge;
-        }
-        public override Answer? answer_challenge (Challenge challenge) {
-            if(private_key == null) {
-                warning ("Attempted to answer challenge for an identiy riddle with no private key");
-                return null;
-            }
-            if(!challenge.identifier.has_prefix ("riddle-identity-")) {
-                return null;
-            }
-            if(challenge.identifier[16:] != Base64.encode (public_key)) {
-                return null;
-            }
-
-            var answer = new Answer ();
-            answer.identifier = challenge.identifier;
-
-            var data = join_data(challenge.data, serialise_address());
-            answer.data = Sodium.Asymmetric.Signing.sign (data, private_key);
-
-            return answer;        
-        }
-        public override GLib.InetSocketAddress? verify_answer (Challenge challenge, Answer answer) {
+//              var pk_enc = Base64.encode (pk);
+//              var sk_enc = Base64.encode (sk);
+
+//              return @"$pk_enc:$sk_enc";
+//          }
+
+//          public static string get_public_key_from_identity(string identity) {
+//              var parts = identity.split(":", 2);
+//              return parts[0];
+//          }
+
+//          public override Challenge create_challenge () {
+//              var salt = new uint8[5120];
+//              Sodium.Random.random_bytes(salt);
+
+//              var challenge = new Challenge();
+//              challenge.identifier = "riddle-identity-" + Base64.encode (public_key);
+//              challenge.data = salt;
+//              return challenge;
+//          }
+//          public override Answer? answer_challenge (Challenge challenge) {
+//              if(private_key == null) {
+//                  warning ("Attempted to answer challenge for an identiy riddle with no private key");
+//                  return null;
+//              }
+//              if(!challenge.identifier.has_prefix ("riddle-identity-")) {
+//                  return null;
+//              }
+//              if(challenge.identifier[16:] != Base64.encode (public_key)) {
+//                  return null;
+//              }
+
+//              var answer = new Answer ();
+//              answer.identifier = challenge.identifier;
+
+//              var data = join_data(challenge.data, serialise_address());
+//              answer.data = Sodium.Asymmetric.Signing.sign (data, private_key);
+
+//              return answer;        
+//          }
+//          public override GLib.InetSocketAddress? verify_answer (Challenge challenge, Answer answer) {
             
-            var verified = Sodium.Asymmetric.Signing.verify (answer.data, public_key);
-            if(verified == null) {
-                return null;
-            }
+//              var verified = Sodium.Asymmetric.Signing.verify (answer.data, public_key);
+//              if(verified == null) {
+//                  return null;
+//              }
 
-            for(var i = 0; i < challenge.data.length; i++) {
-                if(challenge.data[i] != verified[i]) {
-                    return null;
-                }
-            }
+//              for(var i = 0; i < challenge.data.length; i++) {
+//                  if(challenge.data[i] != verified[i]) {
+//                      return null;
+//                  }
+//              }
 
-            return deserialise_address (verified[challenge.data.length:]);
-        }
+//              return deserialise_address (verified[challenge.data.length:]);
+//          }
 
-    }
+//      }
 
-}
+//  }

+ 29 - 5
src/lib/Riddle.vala

@@ -1,8 +1,7 @@
 namespace Riddle {
 
-    public abstract class Riddle {
+    public abstract class Riddle : Object {
 
-        public InetSocketAddress application_address { get; set; }
         public string group { get; protected set; }
         public int max_hops { get; protected set; }
         public int expiry_seconds { get; protected set; }
@@ -16,6 +15,21 @@ namespace Riddle {
         private uint8[] author_signing_secret;
         private uint8[] author_verification_key;
 
+        construct {
+            riddle_verification_secret = new uint8[Sodium.Asymmetric.Signing.SECRET_KEY_BYTES];
+            riddle_verification_key = new uint8[Sodium.Asymmetric.Signing.PUBLIC_KEY_BYTES];
+
+            riddle_encryption_secret = new uint8[Sodium.Asymmetric.Sealing.SECRET_KEY_BYTES];
+            riddle_encryption_key = new uint8[Sodium.Asymmetric.Sealing.PUBLIC_KEY_BYTES];
+
+            author_signing_secret = new uint8[Sodium.Asymmetric.Signing.SECRET_KEY_BYTES];
+            author_verification_key = new uint8[Sodium.Asymmetric.Signing.PUBLIC_KEY_BYTES];
+
+            Sodium.Asymmetric.Signing.generate_keypair(riddle_verification_key, riddle_verification_secret);
+            Sodium.Asymmetric.Sealing.generate_keypair(riddle_encryption_key, riddle_encryption_secret);
+            Sodium.Asymmetric.Signing.generate_keypair(author_verification_key, author_signing_secret);
+        }
+
         public RiddleEnvelope seal(uint reply_port) {
             var data = generate(riddle_verification_secret);
             var envelope = new RiddleEnvelope() {
@@ -45,7 +59,7 @@ namespace Riddle {
 
             var contact_info = validate(solution.data);
             if(contact_info == null) {
-                return new Message(MessageType.NOT_ACCEPTED, new string[] { "100", "validation-failed" }, new string[0]);
+                return new Message(MessageType.NOT_ACCEPTED, new string[] { "103", "validation-failed" }, new string[0]);
             }
 
             var encrypted_contact_info = solution.encrypt_connection_details(contact_info);
@@ -53,9 +67,19 @@ namespace Riddle {
             return new Message(MessageType.SOLVED, new string[0], new string[] { Base64.encode(signed_contact_info) });
         }
 
+        public SolutionEnvelope? attempt(RiddleEnvelope envelope, uint8[] reply_public_key) {
+            var solution = solve(envelope.data);
+            if(solution == null){
+                return null;
+            }
+
+            solution.reply_key = reply_public_key;
+            return solution.seal(envelope.identifier, envelope.solution_encryption_key);
+        }
+
         protected abstract uint8[] generate(uint8[] secret);
         protected abstract InetSocketAddress? validate(uint8[] solution);
-        public abstract uint8[]? solve(uint8[] riddle);
+        protected abstract Solution? solve(uint8[] riddle);
 
         protected uint8[] join_data(uint8[] payload, uint8[] to_add) {
             var new_payload = new uint8[payload.length + to_add.length];
@@ -84,7 +108,7 @@ namespace Riddle {
                 return null;
             }
 
-            return new Solution(data, reply_key);
+            return new Solution(riddle_verification_secret, data) { reply_key = reply_key };
         }
 
     }

+ 44 - 14
src/lib/Server.vala

@@ -7,7 +7,7 @@ namespace Riddle {
         public const int REGISTRATION_TIMEOUT_US = 600000000;
         private SocketService service;
         private Gee.HashMap<string, Invercargill.Sequence<Registration>> registrations = new Gee.HashMap<string, Invercargill.Sequence<Registration>>();
-        private Gee.HashMap<string, Invercargill.Sequence<RiddleEnvelope>> riddles = new Gee.HashMap<string, Invercargill.Sequence<RiddleEnvelope>>();
+        private Gee.HashMap<string, RiddleEnvelope> riddles = new Gee.HashMap<string, RiddleEnvelope>();
         private Gee.HashMap<string, NameInfo> names = new Gee.HashMap<string, NameInfo>();
         
         
@@ -61,7 +61,9 @@ namespace Riddle {
                 case MessageType.WHO_IS:
                     return handle_who_is(msg);
                 case MessageType.RIDDLE:
-                    return handle_riddle(msg);
+                    return handle_riddle(msg, origin);
+                case MessageType.CALLBACK:
+                    return handle_callback(msg);
                 default:
                     return new Message(MessageType.ERROR, new string[] { "unknown-command" }, new string[0]);
             }
@@ -137,24 +139,43 @@ namespace Riddle {
             return new Message(MessageType.ANSWER, new string[0], new string[] { name.get_encoded() });
         }
 
-        private Message handle_riddle(Message msg) throws Error {
-            var group_id = msg.arguments[0];
-            var riddles_to_try = Invercargill.empty<Riddle>();
+        private Message handle_riddle(Message msg, InetSocketAddress origin) throws Error {
+            var riddle_envelope = new RiddleEnvelope.from_message(msg, origin.address);
+            if(!riddle_envelope.validate_identifier()) {
+                return new Message(MessageType.NOT_ACCEPTED, new string[] { "100", "invalid-identifier" }, new string[0]);
+            }
+
             lock(riddles) {
-                if(!riddles.has_key(group_id)) {
-                    return new Message(MessageType.UNKNOWN, new string[0], new string[0]);
+                if(riddles.has_key(riddle_envelope.identifier)) {
+                    return new Message(MessageType.NOT_ACCEPTED, new string[] { "104", "already-received" }, new string[0]);
                 }
-                riddles_to_try = riddles[group_id].to_sequence();
+                riddles.set(riddle_envelope.identifier, riddle_envelope);
+            }
+            
+            // Forward riddle on here
+            // Pass to application to solve then compact when done.
+            
+            return new Message(MessageType.OK, new string[0], new string[0]);
+        }
+
+        private Message handle_callback(Message msg) throws Error {
+            var solution_envelope = new SolutionEnvelope.from_message(msg);
+            var riddle_metadata = get_riddle_metadata(solution_envelope.identifier);
+            if(riddle_metadata == null) {
+                return new Message(MessageType.NOT_ACCEPTED, new string[] { "105", "riddle-not-found" }, new string[0]);
             }
 
-            var challenges = ate(msg.items).select<Challenge>(item => new Challenge.from_string(item));
-            var answers = challenges.select<Answer?>(c => riddles_to_try.select<Answer?>(r => r.answer_challenge(c)).first_or_default(a => a != null));
+            if(!solution_envelope.verify(riddle_metadata.solution_verification_key)) {
+                return new Message(MessageType.NOT_ACCEPTED, new string[] { "101", "verification-failed" }, new string[0]);
+            }
 
-            var answer = answers.first_or_default();
-            if(answer == null) {
-                return new Message(MessageType.UNKNOWN, new string[0], new string[0]);
+            if(riddle_metadata.reply_address == null) {
+                // TODO Verify with Riddle Object
+                return new Message(MessageType.ERROR, new string[] { "not-implemented" }, new string[0]);
             }
-            return new Message(MessageType.ANSWER, answer.to_arguments(), new string[0]);
+
+            // TODO Forward to reply address
+            return new Message(MessageType.ERROR, new string[] { "not-implemented" }, new string[0]);
         }
 
         private void cleanup_registrations() {
@@ -222,6 +243,15 @@ namespace Riddle {
             return null;
         }
 
+        private RiddleEnvelope? get_riddle_metadata(string identifier) {
+            lock(riddles) {
+                if(riddles.has_key(identifier)) {
+                    return riddles[identifier];
+                }
+            }
+            return null;
+        }
+
     }
 
     private class Registration {

+ 0 - 69
src/lib/SharedKeyPairRiddle.vala

@@ -1,69 +0,0 @@
-namespace Riddle {
-
-    public class SharedKeyPairRiddle : Riddle {
-
-
-        private uint8[] private_key { get; set; }
-        private uint8[] public_key { get; set; }
-
-        public SharedKeyPairRiddle(string keypair) {
-            var parts = keypair.split(":", 2);
-            public_key = Base64.decode (parts[0]);
-            private_key = Base64.decode (parts[1]);
-        }
-
-        public static string generate_keypair() {
-            var pk = new uint8[Sodium.Asymmetric.Signing.PUBLIC_KEY_BYTES];
-            var sk = new uint8[Sodium.Asymmetric.Signing.SECRET_KEY_BYTES];
-            Sodium.Asymmetric.Signing.generate_keypair (pk, sk);
-            
-            var pk_enc = Base64.encode (pk);
-            var sk_enc = Base64.encode (sk);
-
-            return @"$pk_enc:$sk_enc";
-        }
-
-        public override Challenge create_challenge () {
-            var salt = new uint8[5120];
-            Sodium.Random.random_bytes(salt);
-
-            var challenge = new Challenge();
-            challenge.identifier = "riddle-skp-" + Base64.encode (public_key);
-            challenge.data = salt;
-            return challenge;
-        }
-        public override Answer? answer_challenge (Challenge challenge) {
-            if(!challenge.identifier.has_prefix ("riddle-skp-")) {
-                return null;
-            }
-            if(challenge.identifier[11:] != Base64.encode (public_key)) {
-                return null;
-            }
-
-            var answer = new Answer ();
-            answer.identifier = challenge.identifier;
-
-            var data = join_data(challenge.data, serialise_address());
-            answer.data = Sodium.Asymmetric.Signing.sign (data, private_key);
-
-            return answer;        
-        }
-        public override GLib.InetSocketAddress? verify_answer (Challenge challenge, Answer answer) {
-            
-            var verified = Sodium.Asymmetric.Signing.verify (answer.data, public_key);
-            if(verified == null) {
-                return null;
-            }
-
-            for(var i = 0; i < challenge.data.length; i++) {
-                if(challenge.data[i] != verified[i]) {
-                    return null;
-                }
-            }
-
-            return deserialise_address (verified[challenge.data.length:]);
-        }
-
-    }
-
-}

+ 58 - 0
src/lib/SharedKeyRiddle.vala

@@ -0,0 +1,58 @@
+namespace Riddle {
+
+    public class SharedKeyRiddle : Riddle {
+
+        private uint8[] shared_key { get; set; }
+        private uint8[] token { get; set; }
+        private const int TOKEN_SIZE = 5120;
+
+        public InetSocketAddress app_socket_address { get; set; }
+
+        public SharedKeyRiddle(uint8[] shared_key) {
+            this.shared_key = shared_key;
+            
+            token = new uint8[TOKEN_SIZE];
+            Sodium.Random.random_bytes (token);
+        }
+
+        public static uint8[] generate_key() {
+            return Sodium.Symmetric.generate_key();
+        }
+
+        protected override uint8[] generate (uint8[] secret) {
+            var nonce = new uint8[Sodium.Symmetric.NONCE_BYTES];
+            Sodium.Random.random_bytes (nonce);
+
+            var message = join_data (token, secret);
+            var cyphertext = Sodium.Symmetric.encrypt (message, shared_key, nonce);
+
+            return join_data (nonce, cyphertext);
+        }
+
+        protected override GLib.InetSocketAddress? validate (uint8[] solution) {
+            for(int i = 0; i < solution.length && i < TOKEN_SIZE; i++) {
+                if(token[i] != solution[i]) {
+                    print(@"Not-Validated ($(token[i]) != $(solution[i])) index=$i\n");
+                    return null;
+                }
+            }
+            return app_socket_address;
+        }
+
+        public override Solution? solve (uint8[] riddle) {
+            var nonce = riddle[0:Sodium.Symmetric.NONCE_BYTES];
+            var cyphertext = riddle[Sodium.Symmetric.NONCE_BYTES:];
+
+            var message = Sodium.Symmetric.decrypt (cyphertext, shared_key, nonce);
+            var token = message[0:TOKEN_SIZE];
+            var secret = message[TOKEN_SIZE:];
+            print(@"Token starts with $(token[0])\n");
+
+            return new Solution (secret, token);
+        }
+
+
+
+    }
+
+}

+ 22 - 6
src/lib/Solution.vala

@@ -4,31 +4,47 @@ namespace Riddle {
     public sealed class Solution {
 
         public uint8[] data { get; private set; }
-        public uint8[] reply_key { get; private set; }
+        private uint8[] secret { get; private set; }
+        internal uint8[] reply_key { get; set; }
 
-        public Solution(uint8[] data, uint8[] reply_public_key) {
+        public Solution(uint8[] secret, uint8[] data) {
             this.data = data;
-            reply_key = reply_public_key;
+            this.secret = secret;
         }
 
         public uint8[] encrypt_connection_details(InetSocketAddress address) {
+            print(@"Addy: $(address.address.to_string())\n");
             var serialised = serialise_address(address);
             return Sodium.Asymmetric.Sealing.seal(serialised, reply_key);
         }
 
+        public static uint8[]? verify_solved_response(Message response, uint8[] author_signing_key) {
+            return Sodium.Asymmetric.Signing.verify(Base64.decode(response.items[0]), author_signing_key);
+        }
+
+        public static InetSocketAddress? decrypt_connection_details(uint8[] verified_response, uint8[] reply_public_key, uint8[] reply_secret_key) {
+            var data = Sodium.Asymmetric.Sealing.unseal(verified_response, reply_public_key, reply_secret_key);
+            if(data == null) {
+                return null;
+            }
+
+            var parts = ((string)data).split(" ", 2);
+            return new InetSocketAddress.from_string(parts[0], uint.parse(parts[1]));
+        }
+
         private uint8[] serialise_address(InetSocketAddress address) {
             var s = @"$(address.address) $(address.port)";
             return s.data;
         }
 
-        public SolutionEnvelope seal(string riddle_id, uint8[] riddle_secret, uint8[] riddle_encryption_key) {
+        public SolutionEnvelope seal(string riddle_id, uint8[] riddle_encryption_key) {
             var encrypted_data = Sodium.Asymmetric.Sealing.seal(data, riddle_encryption_key);
             var encrypted_reply_key = Sodium.Asymmetric.Sealing.seal(reply_key, riddle_encryption_key);
 
             return new SolutionEnvelope() {
                 identifier = riddle_id,
-                signed_data = Sodium.Asymmetric.Signing.sign(encrypted_data, riddle_secret),
-                signed_reply_key = Sodium.Asymmetric.Signing.sign(encrypted_reply_key, riddle_secret)
+                signed_data = Sodium.Asymmetric.Signing.sign(encrypted_data, secret),
+                signed_reply_key = Sodium.Asymmetric.Signing.sign(encrypted_reply_key, secret)
             };
         }
 

+ 0 - 1
src/lib/SolutionEnvelope.vala

@@ -27,7 +27,6 @@ namespace Riddle {
                     identifier
                 },
                 new string[] {
-                    identifier,
                     Base64.encode(signed_data),
                     Base64.encode(signed_reply_key)
                 }

+ 1 - 1
src/lib/meson.build

@@ -17,7 +17,7 @@ dependencies = [
 
 sources = files('Riddle.vala')
 sources += files('RiddleEnvelope.vala')
-sources += files('SharedKeyPairRiddle.vala')
+sources += files('SharedKeyRiddle.vala')
 sources += files('IdentityRiddle.vala')
 sources += files('Message.vala')
 sources += files('Solution.vala')

+ 39 - 39
src/tests/IdentityRiddleTests.vala

@@ -2,55 +2,55 @@ using Riddle;
 
 void identity_riddle_tests() {
 
-    Test.add_func("/riddle/identity_riddle/can_validate", () => {
-        var identity = IdentityRiddle.generate_identity();
-        var public_key = IdentityRiddle.get_public_key_from_identity(identity);
+    //  Test.add_func("/riddle/identity_riddle/can_validate", () => {
+    //      var identity = IdentityRiddle.generate_identity();
+    //      var public_key = IdentityRiddle.get_public_key_from_identity(identity);
 
-        var riddle1 = new IdentityRiddle(public_key);
-        var riddle2 = new IdentityRiddle.from_identity(identity);
-        riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+    //      var riddle1 = new IdentityRiddle(public_key);
+    //      var riddle2 = new IdentityRiddle.from_identity(identity);
+    //      riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
 
-        var challenge = riddle1.create_challenge();
-        var answer = riddle2.answer_challenge(challenge);
+    //      var challenge = riddle1.create_challenge();
+    //      var answer = riddle2.answer_challenge(challenge);
 
-        var address = riddle1.verify_answer(challenge, answer);
-        assert_nonnull(address);
-        assert_cmpstr("127.0.0.1", CompareOperator.EQ, address.address.to_string());
-        assert_cmpuint(5050, CompareOperator.EQ, address.port);
-    });
+    //      var address = riddle1.verify_answer(challenge, answer);
+    //      assert_nonnull(address);
+    //      assert_cmpstr("127.0.0.1", CompareOperator.EQ, address.address.to_string());
+    //      assert_cmpuint(5050, CompareOperator.EQ, address.port);
+    //  });
 
-    Test.add_func("/riddle/identity_riddle/will_not_answer", () => {
-        var identity1 = IdentityRiddle.generate_identity();
-        var identity2 = IdentityRiddle.generate_identity();
-        var public_key = IdentityRiddle.get_public_key_from_identity(identity1);
+    //  Test.add_func("/riddle/identity_riddle/will_not_answer", () => {
+    //      var identity1 = IdentityRiddle.generate_identity();
+    //      var identity2 = IdentityRiddle.generate_identity();
+    //      var public_key = IdentityRiddle.get_public_key_from_identity(identity1);
 
-        var riddle1 = new IdentityRiddle(public_key);
-        var riddle2 = new IdentityRiddle.from_identity(identity2);
-        riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+    //      var riddle1 = new IdentityRiddle(public_key);
+    //      var riddle2 = new IdentityRiddle.from_identity(identity2);
+    //      riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
 
-        var challenge = riddle1.create_challenge();
-        var answer = riddle2.answer_challenge(challenge);
-        assert_null(answer);
-    });
+    //      var challenge = riddle1.create_challenge();
+    //      var answer = riddle2.answer_challenge(challenge);
+    //      assert_null(answer);
+    //  });
 
-    Test.add_func("/riddle/identity_riddle/will_not_validate", () => {
-        var identity1 = IdentityRiddle.generate_identity();
-        var identity2 = IdentityRiddle.generate_identity();
+    //  Test.add_func("/riddle/identity_riddle/will_not_validate", () => {
+    //      var identity1 = IdentityRiddle.generate_identity();
+    //      var identity2 = IdentityRiddle.generate_identity();
 
-        var riddle1 = new IdentityRiddle.from_identity(identity1);
-        var riddle2 = new IdentityRiddle.from_identity(identity2);
-        riddle1.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
-        riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+    //      var riddle1 = new IdentityRiddle.from_identity(identity1);
+    //      var riddle2 = new IdentityRiddle.from_identity(identity2);
+    //      riddle1.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+    //      riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
 
-        var challenge1 = riddle1.create_challenge();
-        var challenge2 = riddle2.create_challenge();
+    //      var challenge1 = riddle1.create_challenge();
+    //      var challenge2 = riddle2.create_challenge();
 
-        var answer1 = riddle1.answer_challenge(challenge1);
-        var answer2 = riddle2.answer_challenge(challenge2);
+    //      var answer1 = riddle1.answer_challenge(challenge1);
+    //      var answer2 = riddle2.answer_challenge(challenge2);
 
-        answer1.data = answer2.data;
+    //      answer1.data = answer2.data;
 
-        var address = riddle1.verify_answer(challenge1, answer1);
-        assert_null(address);
-    });
+    //      var address = riddle1.verify_answer(challenge1, answer1);
+    //      assert_null(address);
+    //  });
 }

+ 0 - 54
src/tests/SharedKeyPairRiddleTests.vala

@@ -1,54 +0,0 @@
-using Riddle;
-
-void shared_key_pair_riddle_tests() {
-
-    Test.add_func("/riddle/shared_key_pair_riddle/can_validate", () => {
-        var keypair = SharedKeyPairRiddle.generate_keypair();
-
-        var riddle1 = new SharedKeyPairRiddle(keypair);
-        var riddle2 = new SharedKeyPairRiddle(keypair);
-        riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
-
-        var challenge = riddle1.create_challenge();
-        var answer = riddle2.answer_challenge(challenge);
-
-        var address = riddle1.verify_answer(challenge, answer);
-        assert_nonnull(address);
-        assert_cmpstr("127.0.0.1", CompareOperator.EQ, address.address.to_string());
-        assert_cmpuint(5050, CompareOperator.EQ, address.port);
-    });
-
-    Test.add_func("/riddle/shared_key_pair_riddle/will_not_answer", () => {
-        var keypair1 = SharedKeyPairRiddle.generate_keypair();
-        var keypair2 = SharedKeyPairRiddle.generate_keypair();
-
-        var riddle1 = new SharedKeyPairRiddle(keypair1);
-        var riddle2 = new SharedKeyPairRiddle(keypair2);
-        riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
-
-        var challenge = riddle1.create_challenge();
-        var answer = riddle2.answer_challenge(challenge);
-        assert_null(answer);
-    });
-
-    Test.add_func("/riddle/shared_key_pair_riddle/will_not_validate", () => {
-        var keypair1 = SharedKeyPairRiddle.generate_keypair();
-        var keypair2 = SharedKeyPairRiddle.generate_keypair();
-
-        var riddle1 = new SharedKeyPairRiddle(keypair1);
-        var riddle2 = new SharedKeyPairRiddle(keypair2);
-        riddle1.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
-        riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
-
-        var challenge1 = riddle1.create_challenge();
-        var challenge2 = riddle2.create_challenge();
-
-        var answer1 = riddle1.answer_challenge(challenge1);
-        var answer2 = riddle2.answer_challenge(challenge2);
-
-        answer1.data = answer2.data;
-
-        var address = riddle1.verify_answer(challenge1, answer1);
-        assert_null(address);
-    });
-}

+ 69 - 0
src/tests/SharedKeyRiddleTests.vala

@@ -0,0 +1,69 @@
+using Riddle;
+
+void shared_key_riddle_tests() {
+
+    Test.add_func("/riddle/shared_key_riddle/can_validate", () => {
+        var key = SharedKeyRiddle.generate_key();
+
+        var riddle1 = new SharedKeyRiddle(key);
+        var riddle2 = new SharedKeyRiddle(key);
+        riddle1.app_socket_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+        
+        var challenge = new RiddleEnvelope.from_message(riddle1.seal(8080).to_message(), new InetAddress.from_string("127.0.0.1"));
+
+        var reply_secret_key = new uint8[Sodium.Asymmetric.Sealing.SECRET_KEY_BYTES];
+        var reply_public_key = new uint8[Sodium.Asymmetric.Sealing.PUBLIC_KEY_BYTES];
+        Sodium.Asymmetric.Sealing.generate_keypair(reply_public_key, reply_secret_key);
+
+        var answer = new SolutionEnvelope.from_message(riddle2.attempt(challenge, reply_public_key).to_message());
+        
+        var result = riddle1.mark_solution(answer);
+        if(result.message_type == MessageType.NOT_ACCEPTED) {
+            print(@"Marking returned NOT-ACCEPTED message: $(result.arguments[0]) $(result.arguments[1])\n");
+        }
+        assert_true(result.message_type == MessageType.SOLVED);
+
+        var solved_response = Solution.verify_solved_response(result, challenge.author_signing_key);
+        assert_nonnull(solved_response);
+
+        var address = Solution.decrypt_connection_details(solved_response, reply_public_key, reply_secret_key);
+
+        assert_nonnull(address);
+        assert_cmpstr("127.0.0.1", CompareOperator.EQ, address.address.to_string());
+        assert_cmpuint(5050, CompareOperator.EQ, address.port);
+    });
+
+    //  Test.add_func("/riddle/shared_key_pair_riddle/will_not_answer", () => {
+    //      var keypair1 = SharedKeyPairRiddle.generate_keypair();
+    //      var keypair2 = SharedKeyPairRiddle.generate_keypair();
+
+    //      var riddle1 = new SharedKeyPairRiddle(keypair1);
+    //      var riddle2 = new SharedKeyPairRiddle(keypair2);
+    //      riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+
+    //      var challenge = riddle1.create_challenge();
+    //      var answer = riddle2.answer_challenge(challenge);
+    //      assert_null(answer);
+    //  });
+
+    //  Test.add_func("/riddle/shared_key_pair_riddle/will_not_validate", () => {
+    //      var keypair1 = SharedKeyPairRiddle.generate_keypair();
+    //      var keypair2 = SharedKeyPairRiddle.generate_keypair();
+
+    //      var riddle1 = new SharedKeyPairRiddle(keypair1);
+    //      var riddle2 = new SharedKeyPairRiddle(keypair2);
+    //      riddle1.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+    //      riddle2.application_address = new InetSocketAddress.from_string("127.0.0.1", 5050);
+
+    //      var challenge1 = riddle1.create_challenge();
+    //      var challenge2 = riddle2.create_challenge();
+
+    //      var answer1 = riddle1.answer_challenge(challenge1);
+    //      var answer2 = riddle2.answer_challenge(challenge2);
+
+    //      answer1.data = answer2.data;
+
+    //      var address = riddle1.verify_answer(challenge1, answer1);
+    //      assert_null(address);
+    //  });
+}

+ 1 - 1
src/tests/TestRunner.vala

@@ -3,7 +3,7 @@ public static int main(string[] args) {
 
     Test.init(ref args);
 
-    shared_key_pair_riddle_tests();
+    shared_key_riddle_tests();
     identity_riddle_tests();
     decentralised_name_info_tests();
     certified_name_info_tests();

+ 1 - 1
src/tests/meson.build

@@ -1,6 +1,6 @@
 
 sources = files('TestRunner.vala')
-sources += files('SharedKeyPairRiddleTests.vala')
+sources += files('SharedKeyRiddleTests.vala')
 sources += files('IdentityRiddleTests.vala')
 sources += files('DecentralisedNameInfoTests.vala')
 sources += files('CertifiedNameInfoTests.vala')