package capnp-rpc-net
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Cap'n Proto is a capability-based RPC system with bindings for many languages
Install
dune-project
Dependency
Authors
Maintainers
Sources
capnp-rpc-2.1.1.tbz
sha256=6e9675034c8eac5873ed511f9b968db5223278145bb02ac4a970053a53970a48
sha512=2e2eb8389071bdad3ceef1d15200bf28987f13319f754f4d1603828d0d79202b4de90a6eb294f12ee088c7e3b73755286fbe7076b8fd3d0b29644221e0e7e080
doc/src/capnp-rpc-net/auth.ml.html
Source file auth.ml
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159module Log = Capnp_rpc.Debug.Log let default_rsa_key_bits = 2048 let default_hash = `SHA256 type hash = [`SHA256] (* Note: if we add more hashes here, we need to modify [Vat] to store *all* hashes of peer's public keys when they connect. Otherwise, we might record a client as "sha-256:abc" but it later refers to itself in a sturdy ref as "sha-512:def". We need to detect it's the same peer. *) let error fmt = fmt |> Fmt.kstr @@ fun msg -> Error (`Msg msg) let ( >>= ) x f = match x with | Ok y -> f y | Error _ as e -> e module Digest = struct type t = [`Insecure | `Fingerprint of hash * string] let equal = ( = ) let insecure = `Insecure let alphabet = Base64.uri_safe_alphabet let string_of_hash = function | `SHA256 -> "sha-256" let parse_hash = function | "sha-256" -> Ok `SHA256 | x -> error "Unknown hash type %S" x let parse_digest s = B64.decode ~alphabet ~pad:false s let parse hash digest = parse_hash hash >>= fun hash -> parse_digest digest >>= fun digest -> Ok (hash, digest) let of_certificate cert : t = let hash = default_hash in let digest = X509.Public_key.fingerprint ~hash (X509.Certificate.public_key cert) in `Fingerprint (hash, digest) let add_to_uri t uri = match t with | `Insecure -> Uri.with_userinfo uri (Some "insecure") | `Fingerprint (hash, digest) -> let hash = string_of_hash hash in let digest = B64.encode ~alphabet ~pad:false digest in let uri = Uri.with_userinfo uri (Some hash) in Uri.with_password uri (Some digest) let pp f = function | `Insecure -> Fmt.string f "insecure" | `Fingerprint (hash, digest) -> Fmt.pf f "%s@%s" (string_of_hash hash) (B64.encode ~alphabet ~pad:false digest) let from_uri uri = let hash_type = Uri.user uri in let digest = Uri.password uri in match hash_type, digest with | Some "insecure", None -> Ok `Insecure | Some hash, Some digest -> parse hash digest >>= fun digest -> Ok (`Fingerprint digest) | None, _ -> Error (`Msg "Missing digest hash type (e.g. '...://sha256:...')") | Some _, None -> Error (`Msg "Missing digest value (e.g. '...://sha256:DIGEST@...' or '...://insecure@...')") let authenticator = function | `Insecure -> None | `Fingerprint (hash, digest) -> let hash = (hash :> Digestif.hash') in Some (X509.Authenticator.key_fingerprint ~hash ~fingerprint:digest ~time:(fun _ -> None)) module Map = Map.Make(struct type nonrec t = t let compare = compare end) end module Secret_key = struct type t = { priv : X509.Private_key.t; certificates : Tls.Config.own_cert; tls_server_config : Tls.Config.server; } let equal a b = a.priv = b.priv let tls_server_config t = t.tls_server_config let tls_client_config t ~authenticator = match Tls.Config.client ~certificates:t.certificates ~authenticator () with | Ok x -> x | Error (`Msg msg) -> Fmt.failwith "tls_client_config: %s" msg let digest ?(hash=default_hash) t = let nc_hash = (hash :> Digestif.hash') in let pub = X509.Private_key.public t.priv in let value = X509.Public_key.fingerprint ~hash:nc_hash pub in `Fingerprint (hash, value) let pp_fingerprint hash f t = Digest.pp f (digest ~hash t) let date_time ~date ~time = let tz_offset_s = 0 in match Ptime.of_date_time (date, (time, tz_offset_s)) with | Some dt -> dt | None -> failwith "Invalid date_time!" let x509 t = let dn = [ X509.Distinguished_name.(Relative_distinguished_name.singleton (CN "capnp")) ] in match X509.Signing_request.create dn t with | Error (`Msg m) -> Fmt.failwith "x509 certificate signing request creation failed %s" m | Ok csr -> let valid_from = date_time ~date:(1970, 1, 1) ~time:(1, 1, 1) in (* RFC 5280 says expiration date should be GeneralizedTime value 99991231235959Z *) let valid_until = date_time ~date:(9999, 12, 31) ~time:(23, 59, 59) in X509.Signing_request.sign csr ~valid_from ~valid_until t dn |> function | Ok v -> v | Error err -> Fmt.failwith "x509 signing failed: %a" X509.Validation.pp_signature_error err let of_priv priv = let cert = x509 priv in let certificates = `Single ([cert], priv) in (* We require a client cert to get the client's public key, although we allow any client to connect. We just want to know they key so that if we later need to resolve a sturdy ref hosted at the client, we can reuse this connection. *) let authenticator ?ip:_ ~host:_ _ = Ok None in match Tls.Config.server ~certificates ~authenticator () with | Ok tls_server_config -> { priv; certificates; tls_server_config } | Error (`Msg m) -> Fmt.failwith "Invalid TLS configuration: %s" m let generate () = Log.info (fun f -> f "Generating new private key..."); let priv = Mirage_crypto_pk.Rsa.generate ~bits:default_rsa_key_bits () in let t = of_priv (`RSA priv) in Log.info (fun f -> f "Generated key with hash %a" (pp_fingerprint `SHA256) t); t let of_pem_data data = match X509.Private_key.decode_pem data with | Ok priv -> of_priv priv | Error (`Msg msg) -> Fmt.failwith "Failed to parse secret key!@ %s" msg let to_pem_data t = X509.Private_key.encode_pem t.priv end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>