uschar * tls_cert_ocsp_uri(void * cert, uschar * mod) { #if GNUTLS_VERSION_NUMBER >= 0x030000 gnutls_datum_t uri; int ret; uschar sep = '\n'; int index; uschar * list = NULL; if (mod) if (*mod == '>' && *++mod) sep = *mod++; for(index = 0;; index++) { ret = gnutls_x509_crt_get_authority_info_access((gnutls_x509_crt_t)cert, index, GNUTLS_IA_OCSP_URI, &uri, NULL); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) return list; if (ret < 0) return g_err("gai", __FUNCTION__, ret); list = string_append_listele(list, sep, string_copyn(uri.data, uri.size)); } /*NOTREACHED*/ #else expand_string_message = string_sprintf("%s: OCSP support with GnuTLS requires version 3.0.0\n", __FUNCTION__); return NULL; #endif }
int main (int argc, char *argv[]) { gnutls_datum_t ud, tmp; int ret; gnutls_datum_t req; gnutls_x509_crt_t cert, issuer, signer; #ifndef NO_LIBCURL CURL *handle; struct curl_slist *headers = NULL; #endif int v, seq; const char *cert_file = argv[1]; const char *issuer_file = argv[2]; const char *signer_file = argv[3]; char *hostname = NULL; gnutls_global_init (); if (argc > 4) hostname = argv[4]; cert = load_cert (cert_file); issuer = load_cert (issuer_file); signer = load_cert (signer_file); if (hostname == NULL) { for (seq = 0;; seq++) { ret = gnutls_x509_crt_get_authority_info_access (cert, seq, GNUTLS_IA_OCSP_URI, &tmp, NULL); if (ret == GNUTLS_E_UNKNOWN_ALGORITHM) continue; if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { fprintf (stderr, "No URI was found in the certificate.\n"); exit (1); } if (ret < 0) { fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); exit (1); } printf ("CA issuers URI: %.*s\n", tmp.size, tmp.data); hostname = malloc (tmp.size + 1); memcpy (hostname, tmp.data, tmp.size); hostname[tmp.size] = 0; gnutls_free (tmp.data); break; } } /* Note that the OCSP servers hostname might be available * using gnutls_x509_crt_get_authority_info_access() in the issuer's * certificate */ memset (&ud, 0, sizeof (ud)); fprintf (stderr, "Connecting to %s\n", hostname); _generate_request (&req, cert, issuer); #ifndef NO_LIBCURL curl_global_init (CURL_GLOBAL_ALL); handle = curl_easy_init (); if (handle == NULL) exit (1); headers = curl_slist_append (headers, "Content-Type: application/ocsp-request"); curl_easy_setopt (handle, CURLOPT_HTTPHEADER, headers); curl_easy_setopt (handle, CURLOPT_POSTFIELDS, (void *) req.data); curl_easy_setopt (handle, CURLOPT_POSTFIELDSIZE, req.size); curl_easy_setopt (handle, CURLOPT_URL, hostname); curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, get_data); curl_easy_setopt (handle, CURLOPT_WRITEDATA, &ud); ret = curl_easy_perform (handle); if (ret != 0) { fprintf (stderr, "curl[%d] error %d\n", __LINE__, ret); exit (1); } curl_easy_cleanup (handle); #endif _response_info (&ud); v = _verify_response (&ud, cert, signer); gnutls_x509_crt_deinit (cert); gnutls_x509_crt_deinit (issuer); gnutls_x509_crt_deinit (signer); gnutls_global_deinit (); return v; }
void doit (void) { gnutls_x509_crt_t crt; int ret; gnutls_datum_t data; unsigned int critical; ret = gnutls_global_init (); if (ret < 0) { fail ("gnutls_global_init\n"); exit (1); } ret = gnutls_x509_crt_init (&crt); if (ret != 0) { fail ("gnutls_x509_crt_init\n"); exit (1); } ret = gnutls_x509_crt_import (crt, &cert_with_aia, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail ("gnutls_x509_crt_import\n"); exit (1); } /* test null input */ ret = gnutls_x509_crt_get_authority_info_access (NULL, 0, 0, NULL, NULL); if (ret != GNUTLS_E_INVALID_REQUEST) { fail ("gnutls_x509_crt_get_authority_info_access null input\n"); exit (1); } /* test unused enum */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, 44, NULL, NULL); if (ret != GNUTLS_E_INVALID_REQUEST) { fail ("gnutls_x509_crt_get_authority_info_access insane input\n"); exit (1); } /* test basic query with null output */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_ACCESSMETHOD_OID, NULL, NULL); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access " "GNUTLS_IA_ACCESSMETHOD_OID null output critical\n"); exit (1); } /* test same as previous but also check that critical flag is correct */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_ACCESSMETHOD_OID, NULL, &critical); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access " "GNUTLS_IA_ACCESSMETHOD_OID null output\n"); exit (1); } if (critical != 0) { fail ("gnutls_x509_crt_get_authority_info_access " "critical failed: %d\n", critical); exit (1); } /* basic query of another type */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, NULL, NULL); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access " "GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE null output\n"); exit (1); } /* basic query of another type, with out-of-bound sequence */ ret = gnutls_x509_crt_get_authority_info_access (crt, 1, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, NULL, NULL); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { fail ("gnutls_x509_crt_get_authority_info_access " "GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE out-of-bounds\n"); exit (1); } /* basic query and check output value */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_ACCESSMETHOD_OID, &data, NULL); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access " "GNUTLS_IA_ACCESSMETHOD_OID\n"); exit (1); } if (memcmp ("1.3.6.1.5.5.7.48.1", data.data, data.size) != 0) { fail ("memcmp OCSP OID failed\n"); exit (1); } gnutls_free (data.data); /* basic query of another type and check output value */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, &data, NULL); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access " "GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE\n"); exit (1); } if (memcmp ("uniformResourceIdentifier", data.data, data.size) != 0) { fail ("memcmp URI failed\n"); exit (1); } gnutls_free (data.data); /* specific query */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_URI, &data, NULL); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access GNUTLS_IA_URI\n"); exit (1); } if (memcmp ("https://ocsp.quovadisoffshore.com", data.data, data.size) != 0) { fail ("memcmp URI value failed\n"); exit (1); } gnutls_free (data.data); /* even more specific query */ ret = gnutls_x509_crt_get_authority_info_access (crt, 0, GNUTLS_IA_OCSP_URI, &data, NULL); if (ret < 0) { fail ("gnutls_x509_crt_get_authority_info_access GNUTLS_IA_OCSP_URI\n"); exit (1); } if (memcmp ("https://ocsp.quovadisoffshore.com", data.data, data.size) != 0) { fail ("memcmp URI value failed\n"); exit (1); } gnutls_free (data.data); gnutls_x509_crt_deinit (crt); gnutls_global_deinit (); }