...
 
Commits (2)
......@@ -10,12 +10,13 @@ type t = {
fingerprint_algorithm : HashAlgorithm.t;
expires_at : ExpirationDateTime.t;
minimum_required_power : Power.t;
commands : YayakaCommand.t list; }
commands : YayakaCommand.t list;
signature_declarations : SignatureDeclaration.t list }
let format {
version; layer; previous_hash; hash_algorithm; fingerprint_algorithm;
expires_at; minimum_required_power; commands } =
Format.sprintf "YAYAKA %s\n%d\n%s\n%s\n%s\n%d\n%s\n%d\n%s"
expires_at; minimum_required_power; commands; signature_declarations } =
Format.sprintf "YAYAKA %s\n%d\n%s\n%s\n%s\n%d\n%s\n%d\n%s\n%d\n%s"
version
layer
(Option.value_map previous_hash ~f:YayakaHash.format ~default:"\n")
......@@ -24,4 +25,10 @@ let format {
(Power.to_int minimum_required_power)
(HashAlgorithm.to_string fingerprint_algorithm)
(List.length commands)
(commands |> List.map ~f:YayakaCommand.format |> String.concat ~sep:"\n")
(commands
|> List.map ~f:YayakaCommand.format
|> String.concat ~sep:"\n")
(List.length signature_declarations)
(signature_declarations
|> List.map ~f:SignatureDeclaration.format
|> String.concat ~sep:"\n")
......@@ -6,6 +6,7 @@ type t = {
fingerprint_algorithm : HashAlgorithm.t;
expires_at : ExpirationDateTime.t;
minimum_required_power : Power.t;
commands : Command.t list; }
commands : Command.t list;
signature_declarations : SignatureDeclaration.t list }
val format : t -> string
open Core
open Util
type t =
| AddPublicKey of {
......@@ -49,11 +50,6 @@ let format = function
%s"
(3 + String.count body ~f:(( = ) '\n')) protocol body
let combine3 r1 r2 r3 ~ok ~err =
Result.combine
(Result.combine r1 r2 ~ok:(fun r1 r2 -> r1, r2) ~err)
r3 ~ok:(fun (r1, r2) r3 -> ok r1 r2 r3) ~err
let parse_power str =
Power.parse str
|> Result.of_option ~error:"failed to parse power"
......@@ -67,7 +63,7 @@ let parse_add = function
let algorithm = PublicKeyAlgorithm.of_string(algorithm) in
let power = parse_power power in
let key = String.concat ~sep:"\n" key in
combine3
combine3results
(Result.of_option algorithm ~error:"failed to parse algorithm")
power
(if String.is_empty key then Error "key is blank" else Ok key)
......
open Core
open Util
type t = {
fingerprint : string;
hash_algorithm : HashAlgorithm.t;
signature_algorithm : PublicKeyAlgorithm.t;
}
let format { fingerprint; hash_algorithm; signature_algorithm } =
Format.sprintf "%s\n%s\n%s"
fingerprint
(HashAlgorithm.to_string hash_algorithm)
(PublicKeyAlgorithm.to_string signature_algorithm)
let parse ( fingerprint, hash_algorithm, signature_algorithm ) =
let fingerprint = if String.is_empty fingerprint
then Error "fingerprint is blank"
else Ok fingerprint in
let hash_algorithm =
Result.of_option
(HashAlgorithm.of_string hash_algorithm)
~error:"failed to parse hash_algorithm" in
let signature_algorithm =
Result.of_option
(PublicKeyAlgorithm.of_string signature_algorithm)
~error:"failed to parse signature_algorithm" in
combine3results fingerprint hash_algorithm signature_algorithm
~ok:(fun fingerprint hash_algorithm signature_algorithm -> {
fingerprint; hash_algorithm; signature_algorithm })
~err:(fun a b -> a ^ "\n" ^ b)
type t = {
fingerprint : string;
hash_algorithm : HashAlgorithm.t;
signature_algorithm : PublicKeyAlgorithm.t;
}
val format : t -> string
val parse : (string * string * string) -> (t, string) result
open Core
let combine3results r1 r2 r3 ~ok ~err =
Result.combine
(Result.combine r1 r2 ~ok:(fun r1 r2 -> r1, r2) ~err)
r3 ~ok:(fun (r1, r2) r3 -> ok r1 r2 r3) ~err
open Core
open YayakaChain
module Test = Alcotest
open Support
let a = Power.of_int 1
let expiration_date_time_of_string str =
str
|> ExpirationDateTime.of_string
|> Result.map_error ~f:(fun a -> Failure a)
|> Result.ok_exn
let test_format () =
Test.(check string) "with commands"
"\
......@@ -33,7 +28,14 @@ let test_format () =
3\n\
update\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
3"
3\n\
2\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha1\n\
rsa\n\
+gf0YWKHMzO0/mCFlB9AivKRlD0=\n\
sha256\n\
rsa"
(BlockBody.format BlockBody.{
version = "0.1";
layer = 1;
......@@ -57,7 +59,44 @@ let test_format () =
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
power = Option.value_exn (Power.of_int 3)
};
];
signature_declarations = [
SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
signature_algorithm = PublicKeyAlgorithm.RSA;
};
SignatureDeclaration.{
fingerprint = "+gf0YWKHMzO0/mCFlB9AivKRlD0=";
hash_algorithm = HashAlgorithm.Sha256;
signature_algorithm = PublicKeyAlgorithm.RSA;
};
]
});
Test.(check string) "minimum"
"\
YAYAKA 0.1\n\
0\n\
\n\
\n\
sha256\n\
20190207120915\n\
3\n\
sha1\n\
0\n\
\n\
0\n"
(BlockBody.format BlockBody.{
version = "0.1";
layer = 0;
previous_hash = None;
hash_algorithm = HashAlgorithm.Sha256;
fingerprint_algorithm = HashAlgorithm.Sha1;
expires_at = expiration_date_time_of_string "20190207120915";
minimum_required_power = Option.value_exn (Power.of_int 3);
commands = [];
signature_declarations = []
})
let block_body_tests = [
......
......@@ -7,5 +7,7 @@
publicKeyAlgorithm_test
expirationDateTime_test
command_test
blockBody_test)
blockBody_test
util_test
signatureDeclaration_test)
(libraries alcotest yayakaChain))
open YayakaChain
module Test = Alcotest
let test_format () =
Test.(check string) "sha1 rsa" "\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha1\n\
rsa"
(SignatureDeclaration.format SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
signature_algorithm = PublicKeyAlgorithm.RSA
});
Test.(check string) "sha2 rsa" "\
QZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha256\n\
rsa"
(SignatureDeclaration.format SignatureDeclaration.{
fingerprint = "QZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha256;
signature_algorithm = PublicKeyAlgorithm.RSA
})
let pp ppf t = Fmt.pf ppf "%s" (SignatureDeclaration.format t)
let signature_declaration = Test.testable pp ( = )
let test_parse () =
Test.(check (result signature_declaration string)) "sha1 rsa"
(Ok SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
signature_algorithm = PublicKeyAlgorithm.RSA
})
(SignatureDeclaration.parse
("qZk+NkcGgWq6PiVxeFDCbJzQ2J0=",
"sha1",
"rsa"));
Test.(check (result signature_declaration string)) "sha256 rsa"
(Ok SignatureDeclaration.{
fingerprint = "QZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha256;
signature_algorithm = PublicKeyAlgorithm.RSA
})
(SignatureDeclaration.parse
("QZk+NkcGgWq6PiVxeFDCbJzQ2J0=",
"sha256",
"rsa"));
Test.(check (result signature_declaration string)) "failed to parse"
(Error "fingerprint is blank\nfailed to parse signature_algorithm")
(SignatureDeclaration.parse
("",
"sha256",
"RSA"))
let signature_declaration_tests = [
"format", `Quick, test_format;
"parse", `Quick, test_parse;
]
let () =
Test.run "SignatureDeclarations" [
"SignatureDeclarations", signature_declaration_tests;
]
......@@ -2,3 +2,9 @@ open Core
open YayakaChain
let to_power value = Option.value_exn (Power.of_int value)
let expiration_date_time_of_string str =
str
|> ExpirationDateTime.of_string
|> Result.map_error ~f:(fun a -> Failure a)
|> Result.ok_exn
open YayakaChain
module Test = Alcotest
open Util
let test_combine3results () =
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "ok ok ok"
(Ok "abc")
(combine3results (Ok "a") (Ok "b") (Ok "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "err ok ok"
(Error "a")
(combine3results (Error "a") (Ok "b") (Ok "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "ok err ok"
(Error "b")
(combine3results (Ok "a") (Error "b") (Ok "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "ok ok err"
(Error "c")
(combine3results (Ok "a") (Ok "b") (Error "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "err err ok"
(Error "ab")
(combine3results (Error "a") (Error "b") (Ok "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "ok err err"
(Error "bc")
(combine3results (Ok "a") (Error "b") (Error "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "err ok err"
(Error "ac")
(combine3results (Error "a") (Ok "b") (Error "c") ~ok ~err);
let ok = fun a b c -> a ^ b ^ c in
let err = ( ^ ) in
Test.(check (result string string)) "err err err"
(Error "abc")
(combine3results (Error "a") (Error "b") (Error "c") ~ok ~err)
let util_tests = [
"combine3results", `Quick, test_combine3results;
]
let () =
Test.run "Util" [
"Util", util_tests;
]