9a2fd4347c
If the administrator incorrectly sets up their x509 certificates, the errors seen at runtime during connection attempts are very obscure and difficult to diagnose. This has been a particular problem for people using openssl to generate their certificates instead of the gnutls certtool, because the openssl tools don't turn on the various x509 extensions that gnutls expects to be present by default. This change thus adds support in the TLS credentials object to sanity check the certificates when QEMU first loads them. This gives the administrator immediate feedback for the majority of common configuration mistakes, reducing the pain involved in setting up TLS. The code is derived from equivalent code that has been part of libvirt's TLS support and has been seen to be valuable in assisting admins. It is possible to disable the sanity checking, however, via the new 'sanity-check' property on the tls-creds object type, with a value of 'no'. Unit tests are included in this change to verify the correctness of the sanity checking code in all the key scenarios it is intended to cope with. As part of the test suite, the pkix_asn1_tab.c from gnutls is imported. This file is intentionally copied from the (long since obsolete) gnutls 1.6.3 source tree, since that version was still under GPLv2+, rather than the GPLv3+ of gnutls >= 2.0. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
114 lines
3.2 KiB
C
114 lines
3.2 KiB
C
/*
|
|
* QEMU crypto TLS x509 credential support
|
|
*
|
|
* Copyright (c) 2015 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifndef QCRYPTO_TLSCRED_X509_H__
|
|
#define QCRYPTO_TLSCRED_X509_H__
|
|
|
|
#include "crypto/tlscreds.h"
|
|
|
|
#define TYPE_QCRYPTO_TLS_CREDS_X509 "tls-creds-x509"
|
|
#define QCRYPTO_TLS_CREDS_X509(obj) \
|
|
OBJECT_CHECK(QCryptoTLSCredsX509, (obj), TYPE_QCRYPTO_TLS_CREDS_X509)
|
|
|
|
typedef struct QCryptoTLSCredsX509 QCryptoTLSCredsX509;
|
|
typedef struct QCryptoTLSCredsX509Class QCryptoTLSCredsX509Class;
|
|
|
|
#define QCRYPTO_TLS_CREDS_X509_CA_CERT "ca-cert.pem"
|
|
#define QCRYPTO_TLS_CREDS_X509_CA_CRL "ca-crl.pem"
|
|
#define QCRYPTO_TLS_CREDS_X509_SERVER_KEY "server-key.pem"
|
|
#define QCRYPTO_TLS_CREDS_X509_SERVER_CERT "server-cert.pem"
|
|
#define QCRYPTO_TLS_CREDS_X509_CLIENT_KEY "client-key.pem"
|
|
#define QCRYPTO_TLS_CREDS_X509_CLIENT_CERT "client-cert.pem"
|
|
|
|
|
|
/**
|
|
* QCryptoTLSCredsX509:
|
|
*
|
|
* The QCryptoTLSCredsX509 object provides a representation
|
|
* of x509 credentials used to perform a TLS handshake.
|
|
*
|
|
* This is a user creatable object, which can be instantiated
|
|
* via object_new_propv():
|
|
*
|
|
* <example>
|
|
* <title>Creating x509 TLS credential objects in code</title>
|
|
* <programlisting>
|
|
* Object *obj;
|
|
* Error *err = NULL;
|
|
* obj = object_new_propv(TYPE_QCRYPTO_TLS_CREDS_X509,
|
|
* "tlscreds0",
|
|
* &err,
|
|
* "endpoint", "server",
|
|
* "dir", "/path/x509/cert/dir",
|
|
* "verify-peer", "yes",
|
|
* NULL);
|
|
* </programlisting>
|
|
* </example>
|
|
*
|
|
* Or via QMP:
|
|
*
|
|
* <example>
|
|
* <title>Creating x509 TLS credential objects via QMP</title>
|
|
* <programlisting>
|
|
* {
|
|
* "execute": "object-add", "arguments": {
|
|
* "id": "tlscreds0",
|
|
* "qom-type": "tls-creds-x509",
|
|
* "props": {
|
|
* "endpoint": "server",
|
|
* "dir": "/path/to/x509/cert/dir",
|
|
* "verify-peer": false
|
|
* }
|
|
* }
|
|
* }
|
|
* </programlisting>
|
|
* </example>
|
|
*
|
|
*
|
|
* Or via the CLI:
|
|
*
|
|
* <example>
|
|
* <title>Creating x509 TLS credential objects via CLI</title>
|
|
* <programlisting>
|
|
* qemu-system-x86_64 -object tls-creds-x509,id=tlscreds0,\
|
|
* endpoint=server,verify-peer=off,\
|
|
* dir=/path/to/x509/certdir/
|
|
* </programlisting>
|
|
* </example>
|
|
*
|
|
*/
|
|
|
|
struct QCryptoTLSCredsX509 {
|
|
QCryptoTLSCreds parent_obj;
|
|
#ifdef CONFIG_GNUTLS
|
|
gnutls_certificate_credentials_t data;
|
|
#endif
|
|
bool sanityCheck;
|
|
};
|
|
|
|
|
|
struct QCryptoTLSCredsX509Class {
|
|
QCryptoTLSCredsClass parent_class;
|
|
};
|
|
|
|
|
|
#endif /* QCRYPTO_TLSCRED_X509_H__ */
|
|
|