Blame doc/examples/ex-verify.c

Packit Service 4684c1
/* This example code is placed in the public domain. */
Packit Service 4684c1
Packit Service 4684c1
#ifdef HAVE_CONFIG_H
Packit Service 4684c1
#include <config.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#include <stdio.h>
Packit Service 4684c1
#include <stdlib.h>
Packit Service 4684c1
#include <string.h>
Packit Service 4684c1
#include <assert.h>
Packit Service 4684c1
#include <gnutls/gnutls.h>
Packit Service 4684c1
#include <gnutls/x509.h>
Packit Service 4684c1
Packit Service 4684c1
#include "examples.h"
Packit Service 4684c1
Packit Service 4684c1
#define CHECK(x) assert((x)>=0)
Packit Service 4684c1
Packit Service 4684c1
/* All the available CRLs
Packit Service 4684c1
 */
Packit Service 4684c1
gnutls_x509_crl_t *crl_list;
Packit Service 4684c1
int crl_list_size;
Packit Service 4684c1
Packit Service 4684c1
/* All the available trusted CAs
Packit Service 4684c1
 */
Packit Service 4684c1
gnutls_x509_crt_t *ca_list;
Packit Service 4684c1
int ca_list_size;
Packit Service 4684c1
Packit Service 4684c1
static int print_details_func(gnutls_x509_crt_t cert,
Packit Service 4684c1
                              gnutls_x509_crt_t issuer,
Packit Service 4684c1
                              gnutls_x509_crl_t crl,
Packit Service 4684c1
                              unsigned int verification_output);
Packit Service 4684c1
Packit Service 4684c1
/* This function will try to verify the peer's certificate chain, and
Packit Service 4684c1
 * also check if the hostname matches.
Packit Service 4684c1
 */
Packit Service 4684c1
void
Packit Service 4684c1
verify_certificate_chain(const char *hostname,
Packit Service 4684c1
                         const gnutls_datum_t * cert_chain,
Packit Service 4684c1
                         int cert_chain_length)
Packit Service 4684c1
{
Packit Service 4684c1
        int i;
Packit Service 4684c1
        gnutls_x509_trust_list_t tlist;
Packit Service 4684c1
        gnutls_x509_crt_t *cert;
Packit Service 4684c1
        gnutls_datum_t txt;
Packit Service 4684c1
        unsigned int output;
Packit Service 4684c1
Packit Service 4684c1
        /* Initialize the trusted certificate list. This should be done
Packit Service 4684c1
         * once on initialization. gnutls_x509_crt_list_import2() and
Packit Service 4684c1
         * gnutls_x509_crl_list_import2() can be used to load them.
Packit Service 4684c1
         */
Packit Service 4684c1
        CHECK(gnutls_x509_trust_list_init(&tlist, 0));
Packit Service 4684c1
Packit Service 4684c1
        CHECK(gnutls_x509_trust_list_add_cas(tlist, ca_list, ca_list_size, 0));
Packit Service 4684c1
        CHECK(gnutls_x509_trust_list_add_crls(tlist, crl_list, crl_list_size,
Packit Service 4684c1
                                              GNUTLS_TL_VERIFY_CRL, 0));
Packit Service 4684c1
Packit Service 4684c1
        cert = malloc(sizeof(*cert) * cert_chain_length);
Packit Service 4684c1
        assert(cert != NULL);
Packit Service 4684c1
Packit Service 4684c1
        /* Import all the certificates in the chain to
Packit Service 4684c1
         * native certificate format.
Packit Service 4684c1
         */
Packit Service 4684c1
        for (i = 0; i < cert_chain_length; i++) {
Packit Service 4684c1
                CHECK(gnutls_x509_crt_init(&cert[i]));
Packit Service 4684c1
                CHECK(gnutls_x509_crt_import(cert[i], &cert_chain[i],
Packit Service 4684c1
                                             GNUTLS_X509_FMT_DER));
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
        CHECK(gnutls_x509_trust_list_verify_named_crt(tlist, cert[0],
Packit Service 4684c1
                                                hostname,
Packit Service 4684c1
                                                strlen(hostname),
Packit Service 4684c1
                                                GNUTLS_VERIFY_DISABLE_CRL_CHECKS,
Packit Service 4684c1
                                                &output,
Packit Service 4684c1
                                                print_details_func));
Packit Service 4684c1
Packit Service 4684c1
        /* if this certificate is not explicitly trusted verify against CAs 
Packit Service 4684c1
         */
Packit Service 4684c1
        if (output != 0) {
Packit Service 4684c1
                CHECK(gnutls_x509_trust_list_verify_crt(tlist, cert,
Packit Service 4684c1
                                                  cert_chain_length, 0,
Packit Service 4684c1
                                                  &output,
Packit Service 4684c1
                                                  print_details_func));
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
        if (output & GNUTLS_CERT_INVALID) {
Packit Service 4684c1
                fprintf(stderr, "Not trusted\n");
Packit Service 4684c1
                CHECK(gnutls_certificate_verification_status_print(
Packit Service 4684c1
                                                     output,
Packit Service 4684c1
                                                     GNUTLS_CRT_X509,
Packit Service 4684c1
                                                     &txt, 0));
Packit Service 4684c1
Packit Service 4684c1
                fprintf(stderr, "Error: %s\n", txt.data);
Packit Service 4684c1
                gnutls_free(txt.data);
Packit Service 4684c1
        } else
Packit Service 4684c1
                fprintf(stderr, "Trusted\n");
Packit Service 4684c1
Packit Service 4684c1
        /* Check if the name in the first certificate matches our destination!
Packit Service 4684c1
         */
Packit Service 4684c1
        if (!gnutls_x509_crt_check_hostname(cert[0], hostname)) {
Packit Service 4684c1
                printf
Packit Service 4684c1
                    ("The certificate's owner does not match hostname '%s'\n",
Packit Service 4684c1
                     hostname);
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
        gnutls_x509_trust_list_deinit(tlist, 1);
Packit Service 4684c1
Packit Service 4684c1
        return;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static int
Packit Service 4684c1
print_details_func(gnutls_x509_crt_t cert,
Packit Service 4684c1
                   gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
Packit Service 4684c1
                   unsigned int verification_output)
Packit Service 4684c1
{
Packit Service 4684c1
        char name[512];
Packit Service 4684c1
        char issuer_name[512];
Packit Service 4684c1
        size_t name_size;
Packit Service 4684c1
        size_t issuer_name_size;
Packit Service 4684c1
Packit Service 4684c1
        issuer_name_size = sizeof(issuer_name);
Packit Service 4684c1
        gnutls_x509_crt_get_issuer_dn(cert, issuer_name,
Packit Service 4684c1
                                      &issuer_name_size);
Packit Service 4684c1
Packit Service 4684c1
        name_size = sizeof(name);
Packit Service 4684c1
        gnutls_x509_crt_get_dn(cert, name, &name_size);
Packit Service 4684c1
Packit Service 4684c1
        fprintf(stdout, "\tSubject: %s\n", name);
Packit Service 4684c1
        fprintf(stdout, "\tIssuer: %s\n", issuer_name);
Packit Service 4684c1
Packit Service 4684c1
        if (issuer != NULL) {
Packit Service 4684c1
                issuer_name_size = sizeof(issuer_name);
Packit Service 4684c1
                gnutls_x509_crt_get_dn(issuer, issuer_name,
Packit Service 4684c1
                                       &issuer_name_size);
Packit Service 4684c1
Packit Service 4684c1
                fprintf(stdout, "\tVerified against: %s\n", issuer_name);
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
        if (crl != NULL) {
Packit Service 4684c1
                issuer_name_size = sizeof(issuer_name);
Packit Service 4684c1
                gnutls_x509_crl_get_issuer_dn(crl, issuer_name,
Packit Service 4684c1
                                              &issuer_name_size);
Packit Service 4684c1
Packit Service 4684c1
                fprintf(stdout, "\tVerified against CRL of: %s\n",
Packit Service 4684c1
                        issuer_name);
Packit Service 4684c1
        }
Packit Service 4684c1
Packit Service 4684c1
        fprintf(stdout, "\tVerification output: %x\n\n",
Packit Service 4684c1
                verification_output);
Packit Service 4684c1
Packit Service 4684c1
        return 0;
Packit Service 4684c1
}