diff --git a/src/binary_formats.ml b/src/binary_formats.ml index 2eb61c6b..84836609 100644 --- a/src/binary_formats.ml +++ b/src/binary_formats.ml @@ -22,6 +22,61 @@ exchange and gana master branch are not in sync and we should use a specific git tag instead *) +(* -- Crypto keys -- *) + +module RsaPublicKey = struct + (* libgnuutil format: + https://docs.gnunet.org/doxygen/d9/dbe/structGNUNET__CRYPTO__RsaPublicKeyHeaderP.html + https://docs.gnunet.org/doxygen/d6/d70/group__libgnunetutil.html#ga9c99a81e8cd649c1c925d23211a0738f + https://www.gnupg.org/documentation/manuals/gcrypt/MPI-formats.html + + format: + - rsa header + - modulus + - public_exponent + + integer in big-endian format (MSB first). + Leading zeroes are stripped unless they are required to keep a value positive. + *) + type header = { + n_len: int; + e_len: int; + } + + type t = { + header: header; + n: Z.t; + e: Z.t; + } + + (* need to strip leading zeros or something? *) + let z_to_bigendian_bits v = + let s = Z.to_bits v in + let len = String.length s in + let s = String.init len (fun i -> s.[len - 1 - i]) in + s + + let header_bin = + let open Bin in + record (fun n_len e_len -> { n_len; e_len }) + |+ field beint16 (fun t -> t.n_len) + |+ field beint16 (fun t -> t.e_len) + |> sealr + + let bin = + let open Bin in + record (fun header n e -> + let n = Z.of_bits n in + let e = Z.of_bits e in + { header; n; e }) + |+ field header_bin (fun t -> t.header) + (* TODO + Z.to_bits is in little endian but we need it in big endian *) + |+ field cstring (fun t -> z_to_bigendian_bits t.n) + |+ field cstring (fun t -> z_to_bigendian_bits t.e) + |> sealr +end + open Include let int32_size = 4 diff --git a/src/types.ml b/src/types.ml index 415b6dcb..7ecb2c13 100644 --- a/src/types.ml +++ b/src/types.ml @@ -111,13 +111,11 @@ module Amount = struct fun s -> parse_string ~consume:Consume.All parse_t s |> Result.join end +(* TODO key format *) module Eddsa = struct - (* TODO test *) (* EdDSA and ECDHE public keys always point on Curve25519 and represented using the standard 256 bits Ed25519 compact format, converted to Crockford Base32. *) - (* EdDSA signatures are transmitted as 64-bytes `base32` - binary-encoded objects with just the R and S values (base32_ binary-only). *) type pub = Mirage_crypto_ec.Ed25519.pub let pub_of_string s = @@ -132,6 +130,9 @@ module Eddsa = struct let pub_to_string pub = pub |> Mirage_crypto_ec.Ed25519.pub_to_octets |> Base_32.encode + (* TODO is it exactly like in Mirage_crypto_ec.sign: + "The result is the concatenation of r and s, as specified in RFC 8032." + endianess issue? *) (* EdDSA signatures are transmitted as 64-bytes base32 binary-encoded objects with just the R and S values (base32_ binary-only). @@ -140,13 +141,24 @@ module Eddsa = struct end module Rsa = struct - (* TODO - GNUNET_CRYPTO custom encode/decode *) (* RSA public key converted to Crockford Base32. *) type pub = Mirage_crypto_pk.Rsa.pub - let pub_of_string _s = assert false - let pub_to_string _pub = assert false + let pub_of_string s = + (* TODO bin + - no [Bin.of_string] ? + - what to do with the int ref? *) + let off = ref 0 in + let v = Bin.decode Binary_formats.RsaPublicKey.bin s off in + let res = Mirage_crypto_pk.Rsa.pub ~n:v.n ~e:v.e in + match res with Error (`Msg e) -> Error e | Ok pub -> Ok pub + + let pub_to_string ({ n; e } : Mirage_crypto_pk.Rsa.pub) = + let open Binary_formats.RsaPublicKey in + let header = { n_len= Z.size n; e_len= Z.size e } in + let v = { header; n; e } in + let s = Bin.to_string bin v in + s end module HashCode = struct