tls_test.ml 7.8 KB

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