t_tls.ml 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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_lwt.initialize (module Mirage_crypto_rng.Fortuna);
  31. Unix.chdir "../../../test/"
  32. )
  33. let tc_digest_sha256 = "tc_digest_sha256", `Quick, (fun () ->
  34. let `Hex h = ""
  35. |> Cstruct.of_string
  36. |> Mirage_crypto.Hash.SHA256.digest
  37. |> Hex.of_cstruct in
  38. (* https://de.wikipedia.org/wiki/SHA-2 *)
  39. h |> check string __LOC__ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
  40. ""
  41. |> Cstruct.of_string
  42. |> Mirage_crypto.Hash.SHA256.digest
  43. |> Cstruct.to_string
  44. |> Base64.encode_exn
  45. (* printf "%s" "" | openssl dgst -sha256 -binary | base64 *)
  46. |> check string __LOC__ "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
  47. )
  48. (*
  49. https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/
  50. openssl genrsa -out private.pem 2048
  51. openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  52. *)
  53. (*
  54. * https://discuss.ocaml.org/t/tls-signature-with-opam-tls/9399/3?u=mro
  55. *)
  56. let tc_sign_sha256 = "tc_sign_sha256", `Quick, (fun () ->
  57. let data = "to-be-signed-data" |> Cstruct.of_string in
  58. Lwt.bind
  59. (*
  60. $ openssl genrsa -out private.pem 2048
  61. $ openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  62. *)
  63. (* https://mirleft.github.io/ocaml-tls/doc/tls/X509_lwt/#val-private_of_pems *)
  64. (X509_lwt.private_of_pems ~cert:"data/tls.pub.pem" ~priv_key:"data/tls.priv.pem")
  65. (fun (_, priv) ->
  66. (*
  67. https://mirleft.github.io/ocaml-x509/doc/x509/X509/Private_key/#cryptographic-sign-operation
  68. *)
  69. X509.Private_key.sign `SHA256 ~scheme:`RSA_PKCS1 priv
  70. (`Message data)
  71. |> Result.get_ok
  72. |> Lwt.return)
  73. |>
  74. Lwt_main.run
  75. |> Cstruct.to_string
  76. |> Base64.encode_exn
  77. |> check string __LOC__
  78. "TVMQvS8OZ94BFvMn8ToL0jG01L1T3Dww4o7R6NwcJd7KsOmZtUKzzCezbnY5gjSECj/cfXxs2mrZlk9xGntTKqhJ6YIZmM3BBdXuPl8IyWms/qtqZ4d+NVfMVDhYeGm43+j2HTegpcH2px9auXSThd2WcJmc7J98g9hx5+pEr6hA2UjawzOPYxIyyhNHzX9L1hTu6Xyjq6OkPWgqK9aHnAnGG1f3LgH+YTR0T/l5ODPCyKboFMfvmnQ2PDNRPgsz82j9YuMVF2sE/TCdpTg+T6dX99Hmp35lomXnf1GSTrVAWBcx6mFEOABMrFSRRcMzGo9zCWPb/y8V3xWaSpjroQ==";
  79. let pk = match "data/tls.priv.pem"
  80. |> Seppo_lib.File.to_bytes
  81. |> Cstruct.of_bytes
  82. |> X509.Private_key.decode_pem with
  83. | Ok ((`RSA _) as pk) -> pk
  84. | Ok _ -> failwith "wrong key type, must be RSA for now"
  85. | Error (`Msg s) -> failwith s in
  86. let (al,si) = data |> Seppo_lib.Ap.PubKeyPem.sign pk in
  87. al |> check string __LOC__ "rsa-sha256";
  88. si |> Cstruct.to_string |> Base64.encode_exn |> check string __LOC__
  89. "TVMQvS8OZ94BFvMn8ToL0jG01L1T3Dww4o7R6NwcJd7KsOmZtUKzzCezbnY5gjSECj/cfXxs2mrZlk9xGntTKqhJ6YIZmM3BBdXuPl8IyWms/qtqZ4d+NVfMVDhYeGm43+j2HTegpcH2px9auXSThd2WcJmc7J98g9hx5+pEr6hA2UjawzOPYxIyyhNHzX9L1hTu6Xyjq6OkPWgqK9aHnAnGG1f3LgH+YTR0T/l5ODPCyKboFMfvmnQ2PDNRPgsz82j9YuMVF2sE/TCdpTg+T6dX99Hmp35lomXnf1GSTrVAWBcx6mFEOABMrFSRRcMzGo9zCWPb/y8V3xWaSpjroQ=="
  90. )
  91. let tc_sign_sha512 = "tc_sign_sha512", `Quick, (fun () ->
  92. let module PSS_SHA512 = Mirage_crypto_pk.Rsa.PSS (Mirage_crypto.Hash.SHA512) in
  93. let priv = Mirage_crypto_pk.Rsa.generate ~bits:2048 () in
  94. X509.Private_key.encode_pem (`RSA priv)
  95. |> Cstruct.to_bytes
  96. |> Bytes.length
  97. |> check int __LOC__ 1704;
  98. let data = "to-be-signed-data" in
  99. let signature =
  100. PSS_SHA512.sign ~key:priv (`Message (Cstruct.of_string data))
  101. in
  102. signature |> Cstruct.to_bytes |> Bytes.length
  103. |> check int __LOC__ 256
  104. )
  105. let tc_cstruct = "tc_cstruct", `Quick, (fun () ->
  106. let nonce = Cstruct.of_string "012345678901"
  107. and ciph = Cstruct.of_string "some more length foo bar" in
  108. let c' = Cstruct.append nonce ciph in
  109. let nonce' = Cstruct.to_string ~len:12 c'
  110. and ciph' = Cstruct.to_string ~off:12 c' in
  111. nonce' |> check string __LOC__ "012345678901";
  112. ciph' |> check string __LOC__ "some more length foo bar";
  113. ()
  114. )
  115. let tc_crypt = "tc_crypt", `Quick, (fun () ->
  116. let key' = "My key secret 123456789012345678" |> Cstruct.of_string in
  117. let key = key' |> Mirage_crypto.Chacha20.of_secret
  118. and nonce = "My nonce 123" |> Cstruct.of_string
  119. and pay = "My payload may be arbitrary long and winded or just some bytes" |> Cstruct.of_string
  120. in
  121. key' |> Cstruct.length |> check int __LOC__ 32;
  122. nonce |> Cstruct.length |> check int __LOC__ 12;
  123. let ct = "9xRgUgzAoYRSW8JU8ggA8d+nH5cVj3XB86bwAvagZAkjbMTOrqWxIEJDEaLhdQ7VX0UHoASNzjyVj84iBPt6/vFospvJ1u+qIhiOJVci" in
  124. Mirage_crypto.Chacha20.authenticate_encrypt ~key ~nonce pay
  125. |> Cstruct.to_string
  126. |> Base64.encode_string
  127. |> check string __LOC__ ct;
  128. ct
  129. |> Base64.decode_exn
  130. |> Cstruct.of_string
  131. |> Mirage_crypto.Chacha20.authenticate_decrypt ~key ~nonce
  132. |> Option.get
  133. |> Cstruct.to_string
  134. |> check string __LOC__ "My payload may be arbitrary long and winded or just some bytes";
  135. ()
  136. )
  137. let tc_pem = "tc_pem", `Quick, (fun () ->
  138. match "data/tls.priv.pem" |> Seppo_lib.Ap.PubKeyPem.private_of_pem with
  139. | Ok (`RSA _) -> ()
  140. | Ok _ -> "wrong key type, must be RSA for now" |> check string __LOC__ ""
  141. | Error s -> s |> check string __LOC__ "."
  142. )
  143. let tc_fingerprint = "tc_fingerprint", `Quick, (fun () ->
  144. "data/cavage.priv.pem"
  145. |> Seppo_lib.File.to_bytes
  146. |> Cstruct.of_bytes
  147. |> X509.Private_key.decode_pem
  148. |> Result.get_ok
  149. |> X509.Private_key.public
  150. |> X509.Public_key.fingerprint
  151. |> Cstruct.to_hex_string
  152. |> check string __LOC__ "6abc29c310d9c042fd93e21828b8178161400a3b78adf0f09d62ac13712eb5fe";
  153. "data/cavage.pub.pem"
  154. |> Seppo_lib.File.to_bytes
  155. |> Cstruct.of_bytes
  156. |> X509.Public_key.decode_pem
  157. |> Result.get_ok
  158. |> X509.Public_key.fingerprint
  159. |> Cstruct.to_hex_string
  160. |> check string __LOC__ "6abc29c310d9c042fd93e21828b8178161400a3b78adf0f09d62ac13712eb5fe"
  161. )
  162. let tc_id = "tc_id", `Quick, (fun () ->
  163. "data/cavage.priv.pem"
  164. |> Seppo_lib.File.to_bytes
  165. |> Cstruct.of_bytes
  166. |> X509.Private_key.decode_pem
  167. |> Result.get_ok
  168. |> X509.Private_key.public
  169. |> X509.Public_key.id
  170. |> Cstruct.to_hex_string
  171. |> check string __LOC__ "24dce701a655bcb523595c43ef65b72358a869e4";
  172. "data/cavage.pub.pem"
  173. |> Seppo_lib.File.to_bytes
  174. |> Cstruct.of_bytes
  175. |> X509.Public_key.decode_pem
  176. |> Result.get_ok
  177. |> X509.Public_key.id
  178. |> Cstruct.to_hex_string
  179. |> check string __LOC__ "24dce701a655bcb523595c43ef65b72358a869e4"
  180. )
  181. let () =
  182. run
  183. "seppo_suite" [
  184. __FILE__ , [
  185. set_up;
  186. tc_digest_sha256;
  187. tc_sign_sha256;
  188. tc_sign_sha512;
  189. tc_cstruct;
  190. tc_crypt;
  191. tc_pem;
  192. tc_fingerprint;
  193. tc_id;
  194. ]
  195. ]