cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: How to get server SSL certificate

From: Bharat Bhushan <bharat_at_cs.arizona.edu>
Date: Wed, 22 Jun 2005 14:26:35 -0700 (MST)

Thank you very much. It worked great. So the url that we fetch in this
example comes without using ssl (since client didnt have the certificate
in the beginning) or it uses ssl to get even the very first page that we
are getting ?
Thanks again.

Regards,
Bharat

--------------------------------------------------------------------------------

On Wed, 22 Jun 2005, James Bursa wrote:

> In message <Pine.GSO.4.58.0506220839510.6391_at_lectura.CS.Arizona.EDU>
> Bharat Bhushan <bharat_at_cs.arizona.edu> wrote:
>
> > I want to use curl to talk to a HTTPS server. How can I get the
> > server's SSL certificate programatically ? If it's not possible in curl
> > then can someone please let me know how can I do it using openSSL (then I
> > can use this certificate with curl).
>
> Here's an example that fetches a page and displays all the
> certificates. I wrote this when I was working out how it works myself.
>
> I couldn't find any OpenSSL documentation about certificates, so I'm
> not sure that this is all correct (for example, incrementing the
> reference count to save it for after the transfer is complete).
>
> The page is fetched even if verifying the certificates fails, but
> certificate_error[] is filled in with error codes for each
> certificate.
>
> James
>
>
> /**
> * Fetch an HTTPS page and display the certificate chain.
> */
>
> #include <assert.h>
> #include <stdio.h>
> #include <curl/curl.h>
> #include <openssl/ssl.h>
>
>
> char error_buffer[CURL_ERROR_SIZE] = "";
>
>
> CURLcode go(CURL *curl, char *url);
> CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm);
> int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx);
> void print_certificate(X509 *cert);
>
>
> /* arrays for certificate chain and errors */
> #define MAX_CERTS 20
> X509 *certificate[MAX_CERTS];
> long certificate_error[MAX_CERTS];
>
>
> int main(int argc, char *argv[])
> {
> unsigned int i;
> CURL *curl;
> CURLcode code;
>
> assert(argc == 2);
>
> for (i = 0; i != MAX_CERTS; i++) {
> certificate[i] = 0;
> certificate_error[i] = X509_V_OK;
> }
>
> curl = curl_easy_init();
> assert(curl);
>
> code = go(curl, argv[1]);
> if (code != CURLE_OK)
> fprintf(stderr, "Error %u: %s\n%s\n",
> code,
> curl_easy_strerror(code),
> error_buffer);
>
> curl_easy_cleanup(curl);
>
> printf("\n\n========================================\n");
> for (i = 0; i != MAX_CERTS && certificate[i]; i++) {
> print_certificate(certificate[i]);
> printf("*** %s\n",
> X509_verify_cert_error_string(
> certificate_error[i]));
> certificate[i]->references--;
> if (certificate[i]->references == 0)
> X509_free(certificate[i]);
> printf("========================================\n");
> }
>
> return 0;
> }
>
>
> CURLcode go(CURL *curl, char *url)
> {
> CURLcode code;
>
> code = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer);
> if (code != CURLE_OK)
> return code;
> code = curl_easy_setopt(curl, CURLOPT_URL, url);
> if (code != CURLE_OK)
> return code;
> code = curl_easy_setopt(curl, CURLOPT_WRITEHEADER, stdout);
> if (code != CURLE_OK)
> return code;
>
> /* fetch the page even if verifying the certificates fails */
> code = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
> if (code != CURLE_OK)
> return code;
> code = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
> if (code != CURLE_OK)
> return code;
>
> code = curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun);
> if (code != CURLE_OK)
> return code;
>
> code = curl_easy_perform(curl);
>
> return code;
> }
>
>
> CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm)
> {
> SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback);
>
> return CURLE_OK;
> }
>
>
> int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
> {
> X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx);
> int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
> int err = X509_STORE_CTX_get_error(x509_ctx);
>
> /* save the certificate by incrementing the reference count and
> * keeping a pointer */
> if (depth < MAX_CERTS && !certificate[depth]) {
> certificate[depth] = cert;
> certificate_error[depth] = err;
> cert->references++;
> }
>
> return 1;
> }
>
>
> void print_certificate(X509 *cert)
> {
> char s[256];
>
> printf(" version %li\n", X509_get_version(cert));
> printf(" not before %s\n", X509_get_notBefore(cert)->data);
> printf(" not after %s\n", X509_get_notAfter(cert)->data);
> printf(" signature type %i\n", X509_get_signature_type(cert));
> printf(" serial no %li\n",
> ASN1_INTEGER_get(X509_get_serialNumber(cert)));
> X509_NAME_oneline(X509_get_issuer_name(cert), s, 256);
> printf(" issuer %s\n", s);
> X509_NAME_oneline(X509_get_subject_name(cert), s, 256);
> printf(" subject %s\n", s);
> printf(" cert type %i\n",
> X509_certificate_type(cert, X509_get_pubkey(cert)));
> }
>
Received on 2005-06-22