|
@@ -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:]);
|
|
|
-// }
|
|
|
|
|
|
-// }
|
|
|
+ }
|
|
|
|
|
|
-// }
|
|
|
+}
|