[Libvir] Certificate management APIs ?

Mark McLoughlin markmc at redhat.com
Mon Jan 15 20:44:22 UTC 2007


Hi Dan,

On Wed, 2007-01-10 at 23:59 +0000, Daniel P. Berrange wrote:
> I now have the QEMU backend working with full wire encryption using the
> TLS protocol, and so ready to start thinking about various authentication
> related issues. 

	If only we had decent SSH infrastructure. I'd love if apps could easily
use a library to request an SSH connection to a host, authenticate and
then apps could request tunnels over that shared per-user connection.

>  - The client needs to have the certificate of the CA in order to
>    validate the signature on the remote server's certificate
>    (aka, just like web browsers need a set of CA certificates)
> 
>    Currently I just have it loading 'cert.pem' out of the current
>    working directory of the app using libvirt. Obviously this is not
>    a real solution.

	Personally, I'd start with the assumption that essentially no-one will
install a CA signed cert for the libvirt server. So, first and foremost,
the client needs to be present self-signed certs to the user.

	As for the CA certs, we should use /etc/pki/tls/cert.pem by default,
right? And perhaps allow users and admins to install other CA certs just
for libvirt.

>  - The server end can optionally require the client to present a 
>    certificate too, as its means of authenticating the client.
> 
>    This obviously requires a way of specifying the client certificate
>    and secret key in libvirt when opening the connection.

	For the networks stuff, I think the server will also need to be able to
connect to (and authenticate and be authenticated by) other servers.

	Also, as much as it sucks, I think we'll want password based
authentication as well as certificate based authentication. Very few
people will copy the client cert over to the server, I think.

> As a rough stab at an API my thoughts are:
> 
>   typedef enum {
>     VIR_CERT_CA_CERT,
>     VIR_CERT_CA_CRL,
>     VIR_CERT_CLIENT_KEY,
>     VIR_CERT_CLIENT_CERT,
>   } virConnectCertDataType;
> 
>   /**
>    * dataType: one of the virConnectCertDataType constants
>    * data: base64, PEM encoded  certificate/key data
>    */
>   int virConnectAddCertData(int dataType, const char *data);
> 
>   /**
>    * dataType: one of the virConnectCertDataType constants
>    * dataFile: file containing base64, PEM encoded  certificate/key data
>    */
>   int virConnectAddCertDataFile(int dataType, const char *dataFile);

	Seems reasonable, I can't think of anything better.

> Virt-manager would use the latter API to load in its client certificate,
> CA certs, etc to libvirt prior to opening a connection to a TLS enabled
> server. This means libvirt doesn't have to make the policy on where to
> store its client cert data. On the otherhand, we probably want the
> files to be in a common location for virsh & virt-manager so both can
> use the same data. On yet another hand, virt-manager will also likely
> end up using TLS to connect to VNC, so needs access to the files 
> independant on libvirt / virsh for that.  So we should probably have
> these flexible APIs, but recommend that all apps use a pre-defined
> directory unless they have a particular need not to, eg
>     
>     $HOME/.libvirt/tls/
>       |
>       +- ca
>       |  |
>       |  +- cert.pem
>       |  +- ca-crl.pem
>       |
>       +- client
>       |  |
>       |  +- cert.pem
>       |  +- key.pem
>       |
>       +- server
>           |
>           +- trusted.pem

	Not entirely unreasonable, but I think I'd expect it to be in
~/.virt-manager and have a ~/.virshrc which you could point at it.

	If it was ~/.libvirt, then I'd expect virt-manager to access the certs
through e.g. virConnectGetCertData() rather than making the directory
structure part of the API.

	One final point on all that - "uggh".

>   /**
>    * hostname: canonical name of remote host providing certiifcate
>    * cert: base64, PEM encoded certificate data
>    *
>    * Invoked to let client application decide whether to accept a
>    * server certificate. The certificate wil already have been
>    * validated against the CA cert, and its expiration date, etc
>    * checked. This callback is intended to allow the end user to
>    * accept/reject the certificate. The trusted flag indicates
>    * whether the server is present in the list of known servers.
>    */
>    typedef int (*virConnectCertificateValidator)(const char *hostname, const char *cert); 
> 
>    int virConnectSetCertificateValidator(virConnectCertificateValidator cb)
> 
> The applications like virt-manager would probably want to present the
> certificate details to the user for validation, also optionally maintaining
> a list of previously trusted server certs.

	The callback approach seems fine. I'd think about adding a
virConnectCertificate structure whose contents are only available
through accessor functions and passing that to the callback, though. For
future expansion.

Cheers,
Mark.




More information about the libvir-list mailing list