Commit 06a21e05 authored by Ryo33's avatar Ryo33

Add Signature

parent 935f7649
......@@ -16,7 +16,7 @@ type t = {
let format {
version; layer; previous_hash; hash_algorithm; fingerprint_algorithm;
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"
Format.sprintf "YAYAKA %s\n%d\n%s\n%s\n%s\n%d\n%s\n%d\n%s\n%d\n%s\n"
version
layer
(Option.value_map previous_hash ~f:YayakaHash.format ~default:"\n")
......
......@@ -5,11 +5,12 @@ open Bos
type t = { algorithm : HashAlgorithm.t; hash : string }
let hash algorithm text =
let unwrap = function
| Ok result ->
let hex = String.chop_prefix_exn ~prefix:"(stdin)= " result in
Hex.to_string (`Hex hex) |> Base64.encode_exn
| _ -> raise (Failure "") in
let unwrap result =
result
|> Result.map ~f:(String.chop_prefix_exn ~prefix:"(stdin)= ")
|> Result.map ~f:(fun hex -> Hex.to_string (`Hex hex) |> Base64.encode_exn)
|> Result.map_error ~f:(fun _ -> Failure "")
|> Result.ok_exn in
match algorithm with
| Sha1 ->
let cmd = Cmd.(v "openssl" % "dgst" % "-sha1" % "-hex") in
......
type t = {
algorithm : PublicKeyAlgorithm.t;
key : string;
fingerprint_algorithm : HashAlgorithm.t;
power : Power.t }
let fingerprint { fingerprint_algorithm; key; _ } =
let Hash.{ hash; _ } = Hash.hash fingerprint_algorithm key in
let fingerprint ~alg { key; _ } =
let Hash.{ hash; _ } = Hash.hash alg key in
hash
type t = {
algorithm : PublicKeyAlgorithm.t;
key : string;
fingerprint_algorithm : HashAlgorithm.t;
power : Power.t }
val fingerprint : t -> string
val fingerprint : alg:HashAlgorithm.t -> t -> string
open Core
open Bos
type t = {
hash_algorithm : HashAlgorithm.t;
signature_algorithm : string;
fingerprint : string;
key : PublicKey.t;
body : string }
let sign_rsa ~hash ~priv body =
let body = BlockBody.format body in
let out = Filename.temp_file "" "" in
let cmd = match hash with
| HashAlgorithm.Sha1 ->
Cmd.(v "openssl" % "dgst" % "-sha1" % "-sign" % priv % "-out" % out)
| HashAlgorithm.Sha256 ->
Cmd.(v "openssl" % "dgst" % "-sha256" % "-sign" % priv % "-out" % out) in
ignore OS.Cmd.(run_in cmd (in_string body));
In_channel.read_all out
|> Base64.encode_exn
let sign ~hash ~public ~priv body =
match public.PublicKey.algorithm with
| RSA -> {
hash_algorithm = hash;
key = public;
body = sign_rsa ~hash ~priv body
}
let verify_rsa ~hash_algorithm ~key:PublicKey.{ key; _ } ~sign body =
let unwrap result =
result
|> OS.Cmd.success
|> Result.is_ok in
let (key_file, oc) = Filename.open_temp_file "" "" in
Printf.fprintf oc "%s" key;
Out_channel.close oc;
let (signature_file, oc) = Filename.open_temp_file "" "" in
Printf.fprintf oc "%s" (Base64.decode_exn sign);
Out_channel.close oc;
let body = BlockBody.format body in
let cmd = match hash_algorithm with
| HashAlgorithm.Sha1 ->
Cmd.(v
"openssl" % "dgst" % "-sha1" % "-verify" % key_file % "-signature" % signature_file)
| HashAlgorithm.Sha256 ->
Cmd.(v
"openssl" % "dgst" % "-sha256" % "-verify" % key_file % "-signature" % signature_file) in
let result = OS.Cmd.(run_io cmd (in_string body) |> out_null) in
unwrap result
let verify ~sign:{ hash_algorithm; key; body } block =
match key.PublicKey.algorithm with
| RSA -> verify_rsa ~hash_algorithm ~key ~sign:body block
type t
type t = {
hash_algorithm : HashAlgorithm.t;
key : PublicKey.t;
body : string }
val sign :
hash:HashAlgorithm.t -> public:PublicKey.t -> priv:string -> BlockBody.t -> t
val verify :
sign:t -> BlockBody.t -> bool
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"
let format { fingerprint; hash_algorithm } =
Format.sprintf "%s\n%s"
fingerprint
(HashAlgorithm.to_string hash_algorithm)
(PublicKeyAlgorithm.to_string signature_algorithm)
let parse ( fingerprint, hash_algorithm, signature_algorithm ) =
let parse ( fingerprint, hash_algorithm ) =
let fingerprint = if String.is_empty fingerprint
then Error "fingerprint is blank"
else Ok fingerprint in
......@@ -21,13 +18,9 @@ let parse ( fingerprint, hash_algorithm, signature_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 })
Result.combine fingerprint hash_algorithm
~ok:(fun fingerprint hash_algorithm -> {
fingerprint; hash_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
val parse : (string * string) -> (t, string) result
......@@ -32,10 +32,8 @@ let test_format () =
2\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha1\n\
rsa\n\
+gf0YWKHMzO0/mCFlB9AivKRlD0=\n\
sha256\n\
rsa"
sha256\n"
(BlockBody.format BlockBody.{
version = "0.1";
layer = 1;
......@@ -64,12 +62,10 @@ let test_format () =
SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
signature_algorithm = PublicKeyAlgorithm.RSA;
};
SignatureDeclaration.{
fingerprint = "+gf0YWKHMzO0/mCFlB9AivKRlD0=";
hash_algorithm = HashAlgorithm.Sha256;
signature_algorithm = PublicKeyAlgorithm.RSA;
};
]
});
......@@ -86,7 +82,8 @@ let test_format () =
sha1\n\
0\n\
\n\
0\n"
0\n\
\n"
(BlockBody.format BlockBody.{
version = "0.1";
layer = 0;
......
......@@ -9,5 +9,6 @@
command_test
blockBody_test
util_test
signatureDeclaration_test)
signatureDeclaration_test
signature_test)
(libraries alcotest yayakaChain))
......@@ -5,18 +5,17 @@ open Support
let test_fingerprint () =
Test.(check string) "public key 1"
"+gf0YWKHMzO0/mCFlB9AivKRlD0="
(PublicKey.fingerprint {
(PublicKey.fingerprint ~alg:HashAlgorithm.Sha1 {
algorithm = PublicKeyAlgorithm.RSA;
fingerprint_algorithm = HashAlgorithm.Sha1;
power = to_power 1;
key = "-----BEGIN PUBLIC KEY-----\n\
MB4wDQYJKoZIhvcNAQEBBQADDQAwCgIDAOCHAgMBAAE=\n\
-----END PUBLIC KEY-----\n" });
Test.(check string) "public key 2"
"s71Ok1G01SONnQB8hirmj/ZDgb8="
(PublicKey.fingerprint {
(PublicKey.fingerprint ~alg:HashAlgorithm.Sha1 {
algorithm = PublicKeyAlgorithm.RSA;
fingerprint_algorithm = HashAlgorithm.Sha1;
power = to_power 1;
key = "-----BEGIN PUBLIC KEY-----\n\
MB4wDQYJKoZIhvcNAQEBBQADDQAwCgIDALy/AgMBAAE=\n\
......
......@@ -4,22 +4,18 @@ module Test = Alcotest
let test_format () =
Test.(check string) "sha1 rsa" "\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha1\n\
rsa"
sha1"
(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"
sha256"
(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)
......@@ -31,30 +27,25 @@ let test_parse () =
(Ok SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
signature_algorithm = PublicKeyAlgorithm.RSA
})
(SignatureDeclaration.parse
("qZk+NkcGgWq6PiVxeFDCbJzQ2J0=",
"sha1",
"rsa"));
"sha1"));
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"));
"sha256"));
Test.(check (result signature_declaration string)) "failed to parse"
(Error "fingerprint is blank\nfailed to parse signature_algorithm")
(Error "fingerprint is blank\nfailed to parse hash_algorithm")
(SignatureDeclaration.parse
("",
"sha256",
"RSA"))
"Sha256"))
let signature_declaration_tests = [
"format", `Quick, test_format;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment