t_tls.ml 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. (*
  2. * _ _ ____ _
  3. * _| || |_/ ___| ___ _ __ _ __ ___ | |
  4. * |_ .. _\___ \ / _ \ '_ \| '_ \ / _ \| |
  5. * |_ _|___) | __/ |_) | |_) | (_) |_|
  6. * |_||_| |____/ \___| .__/| .__/ \___/(_)
  7. * |_| |_|
  8. *
  9. * Personal Social Web.
  10. *
  11. * t_tls.ml
  12. *
  13. * Copyright (C) The #Seppo contributors. All rights reserved.
  14. *
  15. * This program is free software: you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation, either version 3 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  27. *)
  28. open Alcotest
  29. let set_up = "setup", `Quick, (fun () ->
  30. Mirage_crypto_rng_unix.use_default ();
  31. Unix.chdir "../../../test/"
  32. )
  33. let tc_digest_sha256 = "tc_digest_sha256", `Quick, (fun () ->
  34. let h = ""
  35. |> Digestif.SHA256.digest_string
  36. |> Digestif.SHA256.to_hex in
  37. (* https://de.wikipedia.org/wiki/SHA-2 *)
  38. h |> check string __LOC__ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
  39. ""
  40. |> Digestif.SHA256.digest_string
  41. |> Digestif.SHA256.to_raw_string
  42. |> Base64.encode_exn
  43. (* printf "%s" "" | openssl dgst -sha256 -binary | base64 *)
  44. |> check string __LOC__ "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
  45. )
  46. (*
  47. https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/
  48. openssl genrsa -out private.pem 2048
  49. openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  50. *)
  51. (*
  52. * https://discuss.ocaml.org/t/tls-signature-with-opam-tls/9399/3?u=mro
  53. *)
  54. let tc_sign_sha256 = "tc_sign_sha256", `Quick, (fun () ->
  55. let data = "to-be-signed-data" in
  56. Lwt.bind
  57. (*
  58. $ openssl genrsa -out private.pem 2048
  59. $ openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  60. *)
  61. (* https://mirleft.github.io/ocaml-tls/doc/tls/X509_lwt/#val-private_of_pems *)
  62. (X509_lwt.private_of_pems ~cert:"data/tls.pub.pem" ~priv_key:"data/tls.priv.pem")
  63. (fun (_, priv) ->
  64. (*
  65. https://mirleft.github.io/ocaml-x509/doc/x509/X509/Private_key/#cryptographic-sign-operation
  66. *)
  67. X509.Private_key.sign `SHA256 ~scheme:`RSA_PKCS1 priv
  68. (`Message data)
  69. |> Result.get_ok
  70. |> Lwt.return)
  71. |>
  72. Lwt_main.run
  73. |> Base64.encode_exn
  74. |> check string __LOC__
  75. "TVMQvS8OZ94BFvMn8ToL0jG01L1T3Dww4o7R6NwcJd7KsOmZtUKzzCezbnY5gjSECj/cfXxs2mrZlk9xGntTKqhJ6YIZmM3BBdXuPl8IyWms/qtqZ4d+NVfMVDhYeGm43+j2HTegpcH2px9auXSThd2WcJmc7J98g9hx5+pEr6hA2UjawzOPYxIyyhNHzX9L1hTu6Xyjq6OkPWgqK9aHnAnGG1f3LgH+YTR0T/l5ODPCyKboFMfvmnQ2PDNRPgsz82j9YuMVF2sE/TCdpTg+T6dX99Hmp35lomXnf1GSTrVAWBcx6mFEOABMrFSRRcMzGo9zCWPb/y8V3xWaSpjroQ==";
  76. let pk = match "data/tls.priv.pem"
  77. |> Seppo_lib.File.to_string
  78. |> X509.Private_key.decode_pem with
  79. | Ok ((`RSA _) as pk) -> pk
  80. | Ok _ -> failwith "wrong key type, must be RSA for now"
  81. | Error (`Msg s) -> failwith s in
  82. let (al,si) = data |> Seppo_lib.Ap.PubKeyPem.sign pk in
  83. al |> check string __LOC__ "rsa-sha256";
  84. si |> Base64.encode_exn |> check string __LOC__
  85. "TVMQvS8OZ94BFvMn8ToL0jG01L1T3Dww4o7R6NwcJd7KsOmZtUKzzCezbnY5gjSECj/cfXxs2mrZlk9xGntTKqhJ6YIZmM3BBdXuPl8IyWms/qtqZ4d+NVfMVDhYeGm43+j2HTegpcH2px9auXSThd2WcJmc7J98g9hx5+pEr6hA2UjawzOPYxIyyhNHzX9L1hTu6Xyjq6OkPWgqK9aHnAnGG1f3LgH+YTR0T/l5ODPCyKboFMfvmnQ2PDNRPgsz82j9YuMVF2sE/TCdpTg+T6dX99Hmp35lomXnf1GSTrVAWBcx6mFEOABMrFSRRcMzGo9zCWPb/y8V3xWaSpjroQ=="
  86. )
  87. let tc_sign_sha512 = "tc_sign_sha512", `Quick, (fun () ->
  88. let module PSS_SHA512 = Mirage_crypto_pk.Rsa.PSS (Digestif.SHA512) in
  89. let priv = Mirage_crypto_pk.Rsa.generate ~bits:2048 () in
  90. X509.Private_key.encode_pem (`RSA priv)
  91. |> Astring.String.length
  92. |> check int __LOC__ 1704;
  93. let data = "to-be-signed-data" in
  94. let signature =
  95. PSS_SHA512.sign ~key:priv (`Message (data))
  96. in
  97. signature |> Astring.String.length
  98. |> check int __LOC__ 256
  99. )
  100. let tc_cstruct = "tc_cstruct", `Quick, (fun () ->
  101. let nonce = Cstruct.of_string "012345678901"
  102. and ciph = Cstruct.of_string "some more length foo bar" in
  103. let c' = Cstruct.append nonce ciph in
  104. let nonce' = Cstruct.to_string ~len:12 c'
  105. and ciph' = Cstruct.to_string ~off:12 c' in
  106. nonce' |> check string __LOC__ "012345678901";
  107. ciph' |> check string __LOC__ "some more length foo bar";
  108. ()
  109. )
  110. let tc_crypt = "tc_crypt", `Quick, (fun () ->
  111. let key' = "My key secret 123456789012345678" in
  112. let key = key' |> Mirage_crypto.Chacha20.of_secret
  113. and nonce = "My nonce 123"
  114. and pay = "My payload may be arbitrary long and winded or just some bytes"
  115. in
  116. key' |> Astring.String.length |> check int __LOC__ 32;
  117. nonce |> Astring.String.length |> check int __LOC__ 12;
  118. let ct = "9xRgUgzAoYRSW8JU8ggA8d+nH5cVj3XB86bwAvagZAkjbMTOrqWxIEJDEaLhdQ7VX0UHoASNzjyVj84iBPt6/vFospvJ1u+qIhiOJVci" in
  119. Mirage_crypto.Chacha20.authenticate_encrypt ~key ~nonce pay
  120. |> Base64.encode_string
  121. |> check string __LOC__ ct;
  122. ct
  123. |> Base64.decode_exn
  124. |> Mirage_crypto.Chacha20.authenticate_decrypt ~key ~nonce
  125. |> Option.get
  126. |> check string __LOC__ "My payload may be arbitrary long and winded or just some bytes";
  127. ()
  128. )
  129. let tc_pem = "tc_pem", `Quick, (fun () ->
  130. match "data/tls.priv.pem" |> Seppo_lib.Ap.PubKeyPem.private_of_pem with
  131. | Ok (`RSA _) -> ()
  132. | Ok _ -> "wrong key type, must be RSA for now" |> check string __LOC__ ""
  133. | Error s -> s |> check string __LOC__ "."
  134. )
  135. let tc_fingerprint = "tc_fingerprint", `Quick, (fun () ->
  136. "data/cavage.priv.pem"
  137. |> Seppo_lib.File.to_string
  138. |> X509.Private_key.decode_pem
  139. |> Result.get_ok
  140. |> X509.Private_key.public
  141. |> X509.Public_key.fingerprint
  142. |> Ohex.encode
  143. |> check string __LOC__ "6abc29c310d9c042fd93e21828b8178161400a3b78adf0f09d62ac13712eb5fe";
  144. "data/cavage.pub.pem"
  145. |> Seppo_lib.File.to_string
  146. |> X509.Public_key.decode_pem
  147. |> Result.get_ok
  148. |> X509.Public_key.fingerprint
  149. |> Ohex.encode
  150. |> check string __LOC__ "6abc29c310d9c042fd93e21828b8178161400a3b78adf0f09d62ac13712eb5fe"
  151. )
  152. let tc_id = "tc_id", `Quick, (fun () ->
  153. "data/cavage.priv.pem"
  154. |> Seppo_lib.File.to_string
  155. |> X509.Private_key.decode_pem
  156. |> Result.get_ok
  157. |> X509.Private_key.public
  158. |> X509.Public_key.id
  159. |> Ohex.encode
  160. |> check string __LOC__ "24dce701a655bcb523595c43ef65b72358a869e4";
  161. "data/cavage.pub.pem"
  162. |> Seppo_lib.File.to_string
  163. |> X509.Public_key.decode_pem
  164. |> Result.get_ok
  165. |> X509.Public_key.id
  166. |> Ohex.encode
  167. |> check string __LOC__ "24dce701a655bcb523595c43ef65b72358a869e4"
  168. )
  169. let () =
  170. run
  171. "seppo_suite" [
  172. __FILE__ , [
  173. set_up;
  174. tc_digest_sha256;
  175. tc_sign_sha256;
  176. tc_sign_sha512;
  177. tc_cstruct;
  178. tc_crypt;
  179. tc_pem;
  180. tc_fingerprint;
  181. tc_id;
  182. ]
  183. ]