1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*************************************************************************** 2e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * _ _ ____ _ 3e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Project ___| | | | _ \| | 4e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * / __| | | | |_) | | 5e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * | (__| |_| | _ <| |___ 6e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * \___|\___/|_| \_\_____| 7e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. 9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which 11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms 12e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * are also available at http://curl.haxx.se/docs/copyright.html. 13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is 16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file. 17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied. 20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/ 22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Note that this example currently requires cURL to be linked against 24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET GnuTLS (and this program must also be linked against -lgnutls). */ 25e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 26e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include <stdio.h> 27e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 28e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include <curl/curl.h> 29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include <gnutls/gnutls.h> 30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic CURL *curl; 32e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream) 34e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 35e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const struct curl_tlssessioninfo *info; 36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int cert_list_size; 37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const gnutls_datum_t *chainp; 38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CURLcode res; 39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void)stream; 41e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void)ptr; 42e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, &info); 44e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 45e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!res) { 46e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET switch(info->backend) { 47e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case CURLSSLBACKEND_GNUTLS: 48e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* info->internals is now the gnutls_session_t */ 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET chainp = gnutls_certificate_get_peers(info->internals, &cert_list_size); 50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((chainp) && (cert_list_size)) { 51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int i; 52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; i < cert_list_size; i++) { 54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gnutls_x509_crt_t cert; 55e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gnutls_datum_t dn; 56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(GNUTLS_E_SUCCESS == gnutls_x509_crt_init(&cert)) { 58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(GNUTLS_E_SUCCESS == 59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gnutls_x509_crt_import(cert, &chainp[i], GNUTLS_X509_FMT_DER)) { 60e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(GNUTLS_E_SUCCESS == 61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &dn)) { 62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(stderr, "Certificate #%d: %.*s", i, dn.size, dn.data); 63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gnutls_free(dn.data); 65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 68e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gnutls_x509_crt_deinit(cert); 69e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 70e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 71e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 72e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET case CURLSSLBACKEND_NONE: 74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET default: 75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return size * nmemb; 80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint main(void) 83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_global_init(CURL_GLOBAL_DEFAULT); 85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl = curl_easy_init(); 87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(curl) { 88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/"); 89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 90e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu); 91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 93e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 95e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); 96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (void) curl_easy_perform(curl); 98e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_easy_cleanup(curl); 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET curl_global_cleanup(); 103e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 0; 105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 106