[libvirt] [PATCH 4/4] Fix validation of CA certificate chains

Michal Privoznik mprivozn at redhat.com
Wed Aug 7 10:44:49 UTC 2013


On 06.08.2013 13:35, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> The code added to validate CA certificates did not take into
> account the possibility that the cacert.pem file can contain
> multiple (concatenated) cert data blocks. Extend the code for
> loading CA certs to use the gnutls APIs for loading cert lists.
> Add test cases to check that multi-level trees of certs will
> validate correctly.
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  src/rpc/virnettlscontext.c   | 73 ++++++++++++++++++++++++++++++++++----------
>  tests/virnettlscontexttest.c | 59 +++++++++++++++++++++++++++++++++++
>  tests/virnettlshelpers.c     | 34 +++++++++++++++++++++
>  tests/virnettlshelpers.h     |  3 ++
>  tests/virnettlssessiontest.c | 63 ++++++++++++++++++++++++++++++++++++--
>  5 files changed, 214 insertions(+), 18 deletions(-)
> 
> diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
> index af0ec21..55fb7d0 100644
> --- a/src/rpc/virnettlscontext.c
> +++ b/src/rpc/virnettlscontext.c

> +#define MAX_CERTS 16
>  static int virNetTLSContextSanityCheckCredentials(bool isServer,
>                                                    const char *cacertFile,
>                                                    const char *certFile)
>  {
>      gnutls_x509_crt_t cert = NULL;
> -    gnutls_x509_crt_t cacert = NULL;
> +    gnutls_x509_crt_t cacerts[MAX_CERTS];
> +    size_t ncacerts = MAX_CERTS;
> +    size_t i;
>      int ret = -1;
>  
>      if ((access(certFile, R_OK) == 0) &&
> -        !(cert = virNetTLSContextLoadCertFromFile(certFile, isServer, false)))
> +        !(cert = virNetTLSContextLoadCertFromFile(certFile, isServer)))
>          goto cleanup;
>      if ((access(cacertFile, R_OK) == 0) &&
> -        !(cacert = virNetTLSContextLoadCertFromFile(cacertFile, isServer, false)))
> +        virNetTLSContextLoadCACertListFromFile(cacertFile, cacerts, &ncacerts) < 0)
>          goto cleanup;
>  
>      if (cert &&
>          virNetTLSContextCheckCert(cert, certFile, isServer, false) < 0)
>          goto cleanup;
>  
> -    if (cacert &&
> -        virNetTLSContextCheckCert(cacert, cacertFile, isServer, true) < 0)
> -        goto cleanup;
> +    for (i = 0 ; i < ncacerts ; i++) {

Spacing

> +        if (virNetTLSContextCheckCert(cacerts[i], cacertFile, isServer, true) < 0)
> +            goto cleanup;
> +    }
>  
> -    if (cert && cacert &&
> -        virNetTLSContextCheckCertPair(cert, certFile, cacert, cacertFile, isServer) < 0)
> +    VIR_DEBUG("Here");
> +    if (cert && ncacerts &&
> +        virNetTLSContextCheckCertPair(cert, certFile, cacerts, ncacerts, cacertFile, isServer) < 0) {
> +        VIR_DEBUG("there");
>          goto cleanup;
> +    }
>  
>      ret = 0;
>  
>  cleanup:
>      if (cert)
>          gnutls_x509_crt_deinit(cert);
> -    if (cacert)
> -        gnutls_x509_crt_deinit(cacert);
> +    for (i = 0 ; i < ncacerts ; i++)

Spacing

> +        gnutls_x509_crt_deinit(cacerts[i]);
>      return ret;
>  }
>  

> diff --git a/tests/virnettlshelpers.c b/tests/virnettlshelpers.c
> index 8236e82..baf043a 100644
> --- a/tests/virnettlshelpers.c
> +++ b/tests/virnettlshelpers.c
> @@ -406,6 +406,40 @@ testTLSGenerateCert(struct testTLSCertReq *req,
>  }
>  
>  
> +void testTLSWriteCertChain(const char *filename,
> +                           gnutls_x509_crt_t *certs,
> +                           size_t ncerts)
> +{
> +    size_t i;
> +    int fd;
> +    int err;
> +    static char buffer[1024*1024];
> +    size_t size;
> +
> +    if ((fd = open(filename, O_WRONLY|O_CREAT, 0600)) < 0) {
> +        VIR_WARN("Failed to open %s", filename);
> +        abort();
> +    }
> +
> +    for (i = 0 ; i < ncerts ; i++) {

Spacing

> +        size = sizeof(buffer);
> +        if ((err = gnutls_x509_crt_export(certs[i], GNUTLS_X509_FMT_PEM, buffer, &size) < 0)) {
> +            VIR_WARN("Failed to export certificate %s", gnutls_strerror(err));
> +            unlink(filename);
> +            abort();
> +        }
> +

Michal




More information about the libvir-list mailing list