This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,83 @@
let ( let* ) = Result.bind
type t = ?ip:Ipaddr.t -> host:[`host] Domain_name.t option ->
Certificate.t list -> Validation.r
(* XXX
* Authenticator just hands off a list of certs. Should be indexed.
* *)
let chain_of_trust ~time ?crls ?(allowed_hashes = Validation.sha2) cas =
let revoked = match crls with
| None -> None
| Some crls -> Some (Crl.is_revoked crls ~allowed_hashes)
in
fun ?ip ~host certificates ->
Validation.verify_chain_of_trust ?ip ~host ~time ?revoked ~allowed_hashes
~anchors:cas certificates
let key_fingerprint ~time ~hash ~fingerprint =
fun ?ip ~host certificates ->
Validation.trust_key_fingerprint ?ip ~host ~time ~hash ~fingerprint certificates
let cert_fingerprint ~time ~hash ~fingerprint =
fun ?ip ~host certificates ->
Validation.trust_cert_fingerprint ?ip ~host ~time ~hash ~fingerprint certificates
let hash_of_string = function
| "sha224" -> Ok `SHA224
| "sha256" -> Ok `SHA256
| "sha384" -> Ok `SHA384
| "sha512" -> Ok `SHA512
| hash -> Error (`Msg (Fmt.str "Unknown hash algorithm %S" hash))
let fingerprint_of_string s =
let* d =
Result.map_error
(function `Msg m ->
`Msg (Fmt.str "Invalid base64 encoding in fingerprint (%s): %S" m s))
(Base64.decode ~pad:false s)
in
Ok d
let format =
{|
The format of an authenticator is:
- [none]: no authentication
- [key-fp(:<hash>?):<base64-encoded fingerprint>]: to authenticate a peer via
its key fingerprintf (hash is optional and defaults to SHA256)
- [cert-fp(:<hash>?):<base64-encoded fingerprint>]: to authenticate a peer via
its certificate fingerprint (hash is optional and defaults to SHA256)
- [trust-anchor(:<base64-encoded DER certificate>)+] to authenticate a peer from
a list of certificates (certificate must be in PEM format witthout header and
footer (----BEGIN CERTIFICATE----) and without newlines).
|}
let of_string str =
begin match String.split_on_char ':' str with
| [ "key-fp" ; hash ; tls_key_fingerprint ] ->
let* hash = hash_of_string (String.lowercase_ascii hash) in
let* fingerprint = fingerprint_of_string tls_key_fingerprint in
Ok (fun time -> key_fingerprint ~time ~hash ~fingerprint)
| [ "key-fp" ; tls_key_fingerprint ] ->
let* fingerprint = fingerprint_of_string tls_key_fingerprint in
Ok (fun time -> key_fingerprint ~time ~hash:`SHA256 ~fingerprint)
| [ "cert-fp" ; hash ; tls_cert_fingerprint ] ->
let* hash = hash_of_string (String.lowercase_ascii hash) in
let* fingerprint = fingerprint_of_string tls_cert_fingerprint in
Ok (fun time -> cert_fingerprint ~time ~hash ~fingerprint)
| [ "cert-fp" ; tls_cert_fingerprint ] ->
let* fingerprint = fingerprint_of_string tls_cert_fingerprint in
Ok (fun time -> cert_fingerprint ~time ~hash:`SHA256 ~fingerprint)
| "trust-anchor" :: certs ->
let* anchors =
List.fold_left (fun acc s ->
let* acc = acc in
let* der = Base64.decode ~pad:false s in
let* cert = Certificate.decode_der der in
Ok (cert :: acc))
(Ok []) certs
in
Ok (fun time -> chain_of_trust ~time (List.rev anchors))
| [ "none" ] -> Ok (fun _ ?ip:_ ~host:_ _ -> Ok None)
| _ -> Error (`Msg (Fmt.str "Invalid TLS authenticator: %S" str))
end |> Result.map_error (function `Msg e -> `Msg (e ^ format))