Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server certificate validation #4015

Merged

Conversation

psafont
Copy link
Member

@psafont psafont commented Jan 14, 2020

Add private key and certificate sanity checking checking, this is not meant to replace online certificate chain checking.

I also took the opportunity to make the existing interface clearer.

This will help adapt some of the existing functions to server
certificates as well as the current trusted ones.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
The function returns the private key for further validation against
certificates.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
This includes both the leaf server certificate as well as the chain
certificate.
This validation is meant to be used offline and does _not_ do a proper, full
validation of the certificate chain.
This is meant to be used as a check before installing a certificate in dom0.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
X509.Private_key.decode_pem raw_pem
|> R.reword_error
(fun (`Msg err_msg) ->
if Astring.String.is_infix ~affix:"multi-prime RSA" err_msg then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there some more specific error variants available? I'd avoid matching on error strings if possible as these might change between versions (although you have a unit test so we'd catch it)

Copy link
Member Author

@psafont psafont Jan 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are all defined as parse_error "message", unfortunately

let ensure_keys_match private_key certificate =
let public_key = X509.Certificate.public_key certificate in
match public_key, private_key with
| `RSA pub, `RSA priv when pub = Nocrypto.Rsa.pub_of_priv priv ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is polymorphic equality the only way to compare these, or would the library provide a comparison function?

Copy link
Member Author

@psafont psafont Jan 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The certificate module provides

val supports_keytype : t -> key_type -> bool

    supports_keytype certificate key_type is result, whether public key of the certificate matches the given key_type.

But I don't see a function to extract keytype from a private or public key. I don't think I can avoid polymorphic equality.

(on the x509 tests it's done the same way)

in

let ensure_validity ~time certificate =
let to_string = Ptime.to_rfc3339 in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also include some grace period here?
i.e. if someone tries to install a certificate that expires the next day we should probably warn them in that case too?
i.e. have a minimum validity period of lets say 30 days?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are alerts planned to warn users about expiring server certificates, I'm not sure if it's worth doing the check here as well. I'll take note and see if it's easy to reuse those checks here as well.

@psafont
Copy link
Member Author

psafont commented Jan 15, 2020

I want the DCO check to fail with the travis commit on the feature branch as it needs to be removed when merging to master.

let stat = Unix.stat (library_path kind) in
let mask = 0o666 in
let perm = stat.Unix.st_perm land mask in
debug "%d %d" perm stat.Unix.st_perm;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this log line enough context to be useful? These are just two numbers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, I'm partial to removing the logline.

I changed this function because it's most probably going to be reused for the new certificates, which need different permissions.

Previously hostname could be empty if there were no hostnames available
in the certificate. Now the hostname from xapi's database is picked
instead, xapi_vdi was adapted.

Signing certificates needs the usage of result as it verifies before
actually signing the certificate, test code was adapted.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
@psafont
Copy link
Member Author

psafont commented Jan 24, 2020

Merging this now that the code compatible with X509 0.9.0.

I'll keep the comments in mind for doing further cleanups in certificates.ml

@psafont psafont merged commit 0b8b0a5 into xapi-project:feature/REQ-453/master Jan 24, 2020
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.

5 participants