Selaa lähdekoodia

Implement identity riddle

Billy Barrow 2 vuotta sitten
vanhempi
sitoutus
ccb23eeea7
3 muutettua tiedostoa jossa 92 lisäystä ja 85 poistoa
  1. 64 71
      src/lib/IdentityRiddle.vala
  2. 0 1
      src/lib/SharedKeyRiddle.vala
  3. 28 13
      src/tests/IdentityRiddleTests.vala

+ 64 - 71
src/lib/IdentityRiddle.vala

@@ -1,82 +1,75 @@
-//  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]);
-//          }
+        private uint8[] token { get; set; }
+        private const int TOKEN_SIZE = 5120;
 
-//          public IdentityRiddle(string public_key) {
-//              this.public_key = Base64.decode (public_key);
-//          }
+        public InetSocketAddress app_socket_address { get; set; }
 
-//          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) {
+        public IdentityRiddle.from_identity(string identiy) {
+            var parts = identiy.split(":", 2);
+            public_key = Base64.decode (parts[0]);
+            private_key = Base64.decode (parts[1]);
+
+            token = new uint8[TOKEN_SIZE];
+            Sodium.Random.random_bytes (token);
+        }
+
+        public IdentityRiddle(string public_key) {
+            this.public_key = Base64.decode (public_key);
+
+            token = new uint8[TOKEN_SIZE];
+            Sodium.Random.random_bytes (token);
+        }
+
+        public static string generate_identity() {
+            var pk = new uint8[Sodium.Asymmetric.Sealing.PUBLIC_KEY_BYTES];
+            var sk = new uint8[Sodium.Asymmetric.Sealing.SECRET_KEY_BYTES];
+            Sodium.Asymmetric.Sealing.generate_keypair (pk, sk);
             
-//              var verified = Sodium.Asymmetric.Signing.verify (answer.data, public_key);
-//              if(verified == null) {
-//                  return null;
-//              }
+            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];
+        }
+
+        protected override uint8[] generate(uint8[] secret) {
+            var message = join_data(token, secret);
+            return Sodium.Asymmetric.Sealing.seal(message, public_key);
+        }
+
+        protected override GLib.InetSocketAddress? validate(uint8[] solution) {
+            for(int i = 0; i < solution.length && i < TOKEN_SIZE; i++) {
+                if(token[i] != solution[i]) {
+                    return null;
+                }
+            }
+            return app_socket_address;
+        }
+
+        protected override Solution? solve(uint8[] riddle) {
+            var message = Sodium.Asymmetric.Sealing.unseal(riddle, public_key, private_key);
+            if(message == null) {
+                return null;
+            }
+
+            var token = message[0:TOKEN_SIZE];
+            var secret = message[TOKEN_SIZE:];
 
-//              for(var i = 0; i < challenge.data.length; i++) {
-//                  if(challenge.data[i] != verified[i]) {
-//                      return null;
-//                  }
-//              }
+            return new Solution(secret, token);
+        }
 
-//              return deserialise_address (verified[challenge.data.length:]);
-//          }
 
-//      }
+    }
 
-//  }
+}

+ 0 - 1
src/lib/SharedKeyRiddle.vala

@@ -32,7 +32,6 @@ namespace Riddle {
         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;
                 }
             }

+ 28 - 13
src/tests/IdentityRiddleTests.vala

@@ -2,22 +2,37 @@ 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);
+        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 challenge = riddle1.create_challenge();
-    //      var answer = riddle2.answer_challenge(challenge);
+        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 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 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/identity_riddle/will_not_answer", () => {
     //      var identity1 = IdentityRiddle.generate_identity();