
On 07/15/2011 05:57 AM, Daniel P. Berrange wrote:
Gnutls requires that certificates have basic constraints present to be used as a CA certificate. OpenSSL doesn't add this data by default, so add a sanity check to catch this situation. Also validate that the key usage and key purpose constraints contain correct data
* src/rpc/virnettlscontext.c: Add sanity checking of certificate constraints --- src/rpc/virnettlscontext.c | 130 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 126 insertions(+), 4 deletions(-)
Seems like a reasonable thing to do.
@@ -145,6 +154,117 @@ static gnutls_x509_crt_t virNetTLSContextSanityCheckCert(bool isServer, goto cleanup; }
+ status = gnutls_x509_crt_get_basic_constraints(cert, NULL, NULL, NULL); + VIR_DEBUG("Cert %s basic constraints %d", certFile, status); + + if (status > 0) { /* It is a CA cert */ + if (!isCA) { + virNetError(VIR_ERR_SYSTEM_ERROR, + _("The certificate %s basic constraints show a CA, but we need one for a %s"), + certFile, isServer ? "server" : "client");
That won't translate well. It needs to be: isServer ? _("The certificate %s basic constraints show a CA, but we need one for a server") : _("The certificate %s basic constraints show a CA, but we need one for a client") , certFile
+ + if (usage & GNUTLS_KEY_KEY_CERT_SIGN) { + if (!isCA) { + virNetError(VIR_ERR_SYSTEM_ERROR, + _("Certificate %s usage is for certificate signing, but wanted a %s certificate"), + certFile, isServer ? "server" : "client");
Another one.
+ + VIR_DEBUG("Key purpose %d %s", status, buffer); + if (STREQ(buffer, GNUTLS_KP_TLS_WWW_SERVER)) { + if (isCA || !isServer) { + virNetError(VIR_ERR_SYSTEM_ERROR, + _("Certificate %s purpose is TLS server, but wanted a %s certificate"), + certFile, isCA ? "CA" : "TLS client");
Another one.
+ goto cleanup; + } + } else if (STREQ(buffer, GNUTLS_KP_TLS_WWW_CLIENT)) { + if (isCA || isServer) { + virNetError(VIR_ERR_SYSTEM_ERROR, + _("Certificate %s purpose is TLS client, but wanted a %s certificate"), + certFile, isCA ? "CA" : "TLS server"); + goto cleanup; + } + } else if (STRNEQ(buffer, GNUTLS_KP_ANY)) { + virNetError(VIR_ERR_SYSTEM_ERROR, + _("Certificate %s purpose is wrong, wanted a %s certificate"), + certFile, isCA ? "CA" : (isServer ? "TLS server" : "TLS client"));
two more. ACK with translation string nits fixed. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org