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(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org