|
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 |
}
|