1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
module V = struct type nc_pub = | RSA_pub of Nocrypto.Rsa.pub let good_rsa p = Nocrypto.Rsa.pub_bits p >= 2048 let encode_key = function | RSA_pub pub -> String.trim (Cstruct.to_string (X509.Encoding.Pem.Public_key.to_pem_cstruct1 (`RSA pub))) let decode_key data = match X509.Encoding.Pem.Public_key.of_pem_cstruct (Cstruct.of_string data) with | [ `RSA pub ] -> Some (RSA_pub pub) | _ -> None module Pss_sha256 = Nocrypto.Rsa.PSS (Nocrypto.Hash.SHA256) let verify_rsa_pss ~key ~data ~signature = match Nocrypto.Base64.decode (Cstruct.of_string signature) with | None -> Error `InvalidBase64Encoding | Some signature -> let cs_data = Cstruct.of_string data in match decode_key key with | Some (RSA_pub key) when good_rsa key -> if Pss_sha256.verify ~key ~signature cs_data then Ok () else Error `InvalidSignature | _ -> Error `InvalidPublicKey let b64sha256 data = let cs = Cstruct.of_string data in let check = Nocrypto.Hash.digest `SHA256 cs in let b64 = Nocrypto.Base64.encode check in Cstruct.to_string b64 end module C = struct type nc_priv = | RSA_priv of Nocrypto.Rsa.priv let decode_priv data = match X509.Encoding.Pem.Private_key.of_pem_cstruct (Cstruct.of_string data) with | [ `RSA priv ] -> Some (RSA_priv priv) | _ -> None let encode_priv = function | RSA_priv priv -> let pem = X509.Encoding.Pem.Private_key.to_pem_cstruct1 (`RSA priv) in Cstruct.to_string pem let generate_rsa ?(bits = 4096) () = let key = RSA_priv (Nocrypto.Rsa.generate bits) in encode_priv key let bits_rsa k = match V.decode_key k with | None -> Error "couldn't decode key" | Some (V.RSA_pub pub) -> Ok (Nocrypto.Rsa.pub_bits pub) let pub_of_priv_rsa k = match decode_priv k with | Some (RSA_priv k) -> let pub = Nocrypto.Rsa.pub_of_priv k in let pem = V.encode_key (V.RSA_pub pub) in Ok pem | None -> Error "couldn't decode private key" let primitive_sign priv data = let cs = Cstruct.of_string data in let signature = match priv with | RSA_priv key -> V.Pss_sha256.sign ~key cs in let b64 = Nocrypto.Base64.encode signature in Cstruct.to_string b64 let sign_rsa_pss ~key data = match decode_priv key with | Some key -> Ok (primitive_sign key data) | None -> Error "couldn't decode private key" end module NC_S = Conex_crypto.Make_sign (C) module NC_V = Conex_crypto.Make_verify (V)