Skip to content

Merge feature/trusted-certs#7026

Open
minglumlu wants to merge 41 commits intomasterfrom
feature/trusted-certs
Open

Merge feature/trusted-certs#7026
minglumlu wants to merge 41 commits intomasterfrom
feature/trusted-certs

Conversation

@minglumlu
Copy link
Copy Markdown
Member

After merge, once a new tag is ready, the following need to be done:

  1. update the datamodel_lifecycle (changed in ca2f0d6)
  2. update the doc status (introduced in fe0ae6e)
  3. add deprecation for Pool.install_ca_certificate and pool.uninstall_ca_certificate.

minglumlu and others added 30 commits January 19, 2026 16:50
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Signed-off-by: Ming Lu <ming.lu@cloud.com>
The design is
https://github.com/xapi-project/xen-api/blob/master/doc/content/design/trusted-certificates.md
(It's a little bit out-of-date. Will update it later. And remaining
changes will be raised in following PRs)

Manual tests are done with a new purpose `testing` (change is not
included in this PR) like:
```
xe pool-install-trusted-certificate filename=root.pem ca=true purpose=licensing,testing
xe pool-install-trusted-certificate filename=root.pem ca=true purpose=licensing,testing # will report error
xe pool-install-trusted-certificate filename=root.pem ca=true
xe pool-install-trusted-certificate filename=leaf.pem ca=false purpose=licensing,testing
xe pool-install-trusted-certificate filename=leaf.pem ca=false # will report error
xe certificate-list
xe pool-uninstall-trusted-certificate certificate-uuid=<UUID>
xe pool-certificate-sync
xe pool-crl-install filename=crl01.pem
xe pool-crl-uninstall name=crl01.pem
```
And `pool.join` and `pool.eject` for exchanging trusted certificates and
CRLs.

The certificate stores under `/etc/trusted-certs/` on coordinator and
supporter hosts' dom0 filesystem.
Add a module UnixSocketProxy in stunnel lib to provide a unix socket
path that can proxy TLS. This can offer a unified mechanism for
differnt users.
Stunnel listens on the unix socket path, accepts the connection
from local request then forwards to remote host and port with TLS.
The certificate checking in TLS connection can be done by stunnel
with the new trusted-certs implementation.
Two set of APIs are provided:
1. long-running stunnel proxy for that the user want to use it
   multi-times and handle the proxy lifecycle itself.
```OCaml
let stunnel_proxy =
  Stunnel.UnixSocketProxy.start ~verify_cert ~remote_host ~remote_port ()
in
match stunnel_proxy with
| Error e -> (* handle error *)
| Ok proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle |> function
    | Ok () -> (* all good *)
    | Error err -> (* handle connection errors *)
    ...
    Stunnel.UnixSocketProxy.stop proxy_handle (* clean up when done *)
```
2. short-lived stunnel proxy for that the user just want to use
   one-shot with auto cleanup.
```OCaml
Stunnel.UnixSocketProxy.with_proxy ~verify_cert ~remote_host ~remote_port
  (fun proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle)
    ...
  )
```

Signed-off-by: Changlei Li <changlei.li@cloud.com>
Currently, the verify_error relies on "certificate verify failed"
and "No certificate or private key specified" in the stunnel log
file.
In fact, "No certificate or private key specified" is a normal
log for stunnel_proxy. It happens on stunnel configuration
fail with verbose log enabled. We can remove it and it is covered
by "Configuration failed".
For "certificate verify failed", it is a indicator for certificate
verify fail, but the detail reasons is in previous lines like
"CERT: Pre-verification error: unable to get local issuer certificate"
"CERT: Subject checks failed". So the "CERT: " line is collected,
if "certificate verify failed" is found, the details can be raised
out as reason.

Signed-off-by: Changlei Li <changlei.li@cloud.com>
In long time running proxy, every time to call diagnose
need to read entire the stunnel log. It is inficient.
Store the input channel of log file in the proxy t, then
the diagnose can read the log from position after the last
it is called.

Signed-off-by: Changlei Li <changlei.li@cloud.com>
Signed-off-by: Changlei Li <changlei.li@cloud.com>
Add a module UnixSocketProxy in stunnel lib to provide a unix socket
path that can proxy TLS. This can offer a unified mechanism for
differnt users.
Stunnel listens on the unix socket path, accepts the connection
from local request then forwards to remote host and port with TLS.
The certificate checking in TLS connection can be done by stunnel
with the new trusted-certs implementation.
Two set of APIs are provided:
1. long-running stunnel proxy for that the user want to use it
    multi-times and handle the proxy lifecycle itself.
```OCaml
let stunnel_proxy =
  Stunnel.UnixSocketProxy.start ~verify_cert ~remote_host ~remote_port ()
in
match stunnel_proxy with
| Error e -> (* handle error *)
| Ok proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle |> function
    | Ok () -> (* all good *)
    | Error err -> (* handle connection errors *)
    ...
    Stunnel.UnixSocketProxy.stop proxy_handle (* clean up when done *)
```
2. short-lived stunnel proxy for that the user just want to use
    one-shot with auto cleanup.
```OCaml
Stunnel.UnixSocketProxy.with_proxy ~verify_cert ~remote_host ~remote_port
  (fun proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle)
    ...
  )
```
changlei-li and others added 9 commits February 27, 2026 14:49
A new LICENSE_SERVER_CERT_CHECK_FAILED is added in LICENSE_CHECKOUT_ERROR
with second string of <The unknown leaf server certificate in PEM format>.
Now the xe command only prints the second string in this case, it is
hard to understand and distinguish with the existing CERTIFICATE_INVALID.
So concact the two strings and print.

Signed-off-by: Changlei Li <changlei.li@cloud.com>
A new LICENSE_SERVER_CERT_CHECK_FAILED is added in
LICENSE_CHECKOUT_ERROR with second string of `<The unknown leaf server
certificate in PEM format>`. Now the xe command only prints the second
string in this case, it is hard to understand and distinguish with the
existing CERTIFICATE_INVALID. So concact the two strings and print.
```diff
commit 4da9ef6
Merge: 1c49383 043e6bd
Author: Ming Lu <ming.lu@cloud.com>
Date:   Wed Apr 15 09:56:22 2026 +0800

    Merge branch 'master' into private/mingl/feature/trusted-certs

diff --cc ocaml/idl/datamodel_common.ml
index 93a3fbc,0fe08b11c..25e689f
--- a/ocaml/idl/datamodel_common.ml
+++ b/ocaml/idl/datamodel_common.ml
@@@ -3,21 -3,21 +3,21 @@@
  open Datamodel_types
  open Lifecycle
  open Datamodel_roles
  
  (* IMPORTANT: Please bump schema vsn if you change/add/remove a _field_.
                You do not have to bump vsn if you change/add/remove a message
                When introducing a new release, bump the schema minor version to the next hundred
                to leave a gap for potential hotfixes needing to increment the schema version.*)
  let schema_major_vsn = 5
  
- let schema_minor_vsn = 794
 -let schema_minor_vsn = 901
++let schema_minor_vsn = 902
  
  (* Historical schema versions just in case this is useful later *)
  let rio_schema_major_vsn = 5
  
  let rio_schema_minor_vsn = 19
  
  let miami_release_schema_major_vsn = 5
  
  let miami_release_schema_minor_vsn = 35
  
diff --cc ocaml/idl/schematest.ml
index e92f9e9,c963c8f11..a7fc9bd
--- a/ocaml/idl/schematest.ml
+++ b/ocaml/idl/schematest.ml
@@@ -1,16 -1,16 +1,16 @@@
  let hash x = Digest.string x |> Digest.to_hex
  
  (* BEWARE: if this changes, check that schema has been bumped accordingly in
     ocaml/idl/datamodel_common.ml, usually schema_minor_vsn *)
  
- let last_known_schema_hash = "ce90c659723cbcd5265e4dd856802b74"
 -let last_known_schema_hash = "32bbba07579ca8844fa6162164530268"
++let last_known_schema_hash = "a64e7e1133a10add1b39d22cd6bbc352"
  
  let current_schema_hash : string =
    let open Datamodel_types in
    let hash_of_obj x =
      List.map rpc_of_content x.contents
      |> List.map Jsonrpc.to_string
      |> String.concat ""
      |> hash
    in
    Datamodel.all_system |> List.map hash_of_obj |> String.concat ":" |> hash
Signed-off-by: Ming Lu <ming.lu@cloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants